diff --git a/build/sdk.atree b/build/sdk.atree
index e3468dd..2cf0eba 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -18,10 +18,10 @@
 # These are the files that comprise that SDK
 #
 
-# version files for the SDK updater
-development/tools/scripts/doc_source.properties docs/source.properties
-development/tools/scripts/tools_source.properties tools/source.properties
-development/tools/scripts/platform_source.properties platforms/${PLATFORM_NAME}/source.properties
+# version files for the SDK updater, from sdk.git
+sdk/scripts/doc_source.properties docs/source.properties
+sdk/scripts/tools_source.properties tools/source.properties
+sdk/scripts/platform_source.properties platforms/${PLATFORM_NAME}/source.properties
 
 # host tools from out/host/$(HOST_OS)-$(HOST_ARCH)/
 bin/aapt platforms/${PLATFORM_NAME}/tools/aapt
@@ -42,29 +42,32 @@
 framework/org.eclipse.jface_3.4.2.M20090107-0800.jar tools/lib/org.eclipse.jface_3.4.2.M20090107-0800.jar
 framework/osgi.jar tools/lib/osgi.jar
 
+# copy build prop from out/.../sdk/
 sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop
-development/tools/scripts/plugin.prop tools/lib/plugin.prop
+
+# copy plugin.prop from sdk.git
+sdk/scripts/plugin.prop tools/lib/plugin.prop
 
 # the aidl precompiled include
 obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl
 
-# sdk scripts
-development/tools/scripts/AndroidManifest.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.template
-development/tools/scripts/AndroidManifest.tests.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.tests.template
-development/tools/scripts/java_file.template platforms/${PLATFORM_NAME}/templates/java_file.template
-development/tools/scripts/java_tests_file.template platforms/${PLATFORM_NAME}/templates/java_tests_file.template
-development/tools/scripts/layout.template platforms/${PLATFORM_NAME}/templates/layout.template
-development/tools/scripts/strings.template platforms/${PLATFORM_NAME}/templates/strings.template
-development/tools/scripts/android_rules.xml platforms/${PLATFORM_NAME}/templates/android_rules.xml
-development/tools/scripts/android_test_rules.xml platforms/${PLATFORM_NAME}/templates/android_test_rules.xml
-development/tools/scripts/icon_ldpi.png platforms/${PLATFORM_NAME}/templates/icon_ldpi.png
-development/tools/scripts/icon_mdpi.png platforms/${PLATFORM_NAME}/templates/icon_mdpi.png
-development/tools/scripts/icon_hdpi.png platforms/${PLATFORM_NAME}/templates/icon_hdpi.png
-development/tools/scripts/build.template tools/lib/build.template
-development/tools/scripts/devices.xml tools/lib/devices.xml
+# sdk.git scripts
+sdk/scripts/AndroidManifest.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.template
+sdk/scripts/AndroidManifest.tests.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.tests.template
+sdk/scripts/java_file.template platforms/${PLATFORM_NAME}/templates/java_file.template
+sdk/scripts/java_tests_file.template platforms/${PLATFORM_NAME}/templates/java_tests_file.template
+sdk/scripts/layout.template platforms/${PLATFORM_NAME}/templates/layout.template
+sdk/scripts/strings.template platforms/${PLATFORM_NAME}/templates/strings.template
+sdk/scripts/android_rules.xml platforms/${PLATFORM_NAME}/templates/android_rules.xml
+sdk/scripts/android_test_rules.xml platforms/${PLATFORM_NAME}/templates/android_test_rules.xml
+sdk/scripts/icon_ldpi.png platforms/${PLATFORM_NAME}/templates/icon_ldpi.png
+sdk/scripts/icon_mdpi.png platforms/${PLATFORM_NAME}/templates/icon_mdpi.png
+sdk/scripts/icon_hdpi.png platforms/${PLATFORM_NAME}/templates/icon_hdpi.png
+sdk/scripts/build.template tools/lib/build.template
+sdk/scripts/devices.xml tools/lib/devices.xml
 
-# emacs support
-development/tools/scripts/android.el tools/lib/android.el
+# emacs support from sdk.git
+sdk/scripts/android.el tools/lib/android.el
 
 # samples
 development/apps/GestureBuilder platforms/${PLATFORM_NAME}/samples/GestureBuilder
@@ -156,20 +159,20 @@
 prebuilt/android-arm/kernel/kernel-qemu platforms/${PLATFORM_NAME}/images/kernel-qemu
 external/qemu/android/avd/hardware-properties.ini tools/lib/hardware-properties.ini
 
-# emulator skins
-development/emulator/skins/QVGA      platforms/${PLATFORM_NAME}/skins/QVGA
-development/emulator/skins/WQVGA432  platforms/${PLATFORM_NAME}/skins/WQVGA432
-development/emulator/skins/WQVGA400  platforms/${PLATFORM_NAME}/skins/WQVGA400
-development/emulator/skins/HVGA      platforms/${PLATFORM_NAME}/skins/HVGA
-development/emulator/skins/WVGA800   platforms/${PLATFORM_NAME}/skins/WVGA800
-development/emulator/skins/WVGA854   platforms/${PLATFORM_NAME}/skins/WVGA854
+# emulator skins from sdk.git
+sdk/emulator/skins/QVGA      platforms/${PLATFORM_NAME}/skins/QVGA
+sdk/emulator/skins/WQVGA432  platforms/${PLATFORM_NAME}/skins/WQVGA432
+sdk/emulator/skins/WQVGA400  platforms/${PLATFORM_NAME}/skins/WQVGA400
+sdk/emulator/skins/HVGA      platforms/${PLATFORM_NAME}/skins/HVGA
+sdk/emulator/skins/WVGA800   platforms/${PLATFORM_NAME}/skins/WVGA800
+sdk/emulator/skins/WVGA854   platforms/${PLATFORM_NAME}/skins/WVGA854
 
-# NOTICE files are copied by build/core/Makefile
-development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/templates/NOTICE.txt
-development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/samples/NOTICE.txt
-development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/data/NOTICE.txt
-development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/skins/NOTICE.txt
-development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/tools/NOTICE.txt
+# NOTICE files are copied by build/core/Makefile from sdk.git
+sdk/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/templates/NOTICE.txt
+sdk/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/samples/NOTICE.txt
+sdk/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/data/NOTICE.txt
+sdk/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/skins/NOTICE.txt
+sdk/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/tools/NOTICE.txt
 
 # the readme
 development/docs/SDK_RELEASE_NOTES RELEASE_NOTES.html
@@ -197,5 +200,5 @@
 frameworks/base/data/fonts/DroidSerif-Italic.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Italic.ttf
 frameworks/base/data/fonts/DroidSerif-Regular.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Regular.ttf
 
-# empty add-on folder with just a readme
-development/tools/scripts/README_add-ons.txt add-ons/README.txt
+# empty add-on folder with just a readme copied from sdk.git
+sdk/scripts/README_add-ons.txt add-ons/README.txt
diff --git a/build/tools/make_windows_sdk.sh b/build/tools/make_windows_sdk.sh
index 97c7bc7..c443430 100755
--- a/build/tools/make_windows_sdk.sh
+++ b/build/tools/make_windows_sdk.sh
@@ -163,13 +163,13 @@
     cp -v /cygdrive/c/cygwin/bin/mgwz.dll "$TOOLS"/
 
     # Update a bunch of bat files
-    cp -v development/tools/apkbuilder/etc/apkbuilder.bat           "$TOOLS"/
-    cp -v development/tools/ddms/app/etc/ddms.bat                   "$TOOLS"/
-    cp -v development/tools/traceview/etc/traceview.bat             "$TOOLS"/
-    cp -v development/tools/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"/
-    cp -v development/tools/layoutopt/app/etc/layoutopt.bat         "$TOOLS"/
-    cp -v development/tools/draw9patch/etc/draw9patch.bat           "$TOOLS"/
-    cp -v development/tools/sdkmanager/app/etc/android.bat          "$TOOLS"/
+    cp -v sdk/apkbuilder/etc/apkbuilder.bat           "$TOOLS"/
+    cp -v sdk/ddms/app/etc/ddms.bat                   "$TOOLS"/
+    cp -v sdk/traceview/etc/traceview.bat             "$TOOLS"/
+    cp -v sdk/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"/
+    cp -v sdk/layoutopt/app/etc/layoutopt.bat         "$TOOLS"/
+    cp -v sdk/draw9patch/etc/draw9patch.bat           "$TOOLS"/
+    cp -v sdk/sdkmanager/app/etc/android.bat          "$TOOLS"/
 
     # Put the JetCreator tools, content and docs (not available in the linux SDK)
     JET="$TOOLS/Jet"
diff --git a/tools/scripts/sdk_clean.sh b/build/tools/sdk_clean.sh
similarity index 100%
rename from tools/scripts/sdk_clean.sh
rename to build/tools/sdk_clean.sh
diff --git a/emulator/keymaps/AVRCP.kl b/emulator/keymaps/AVRCP.kl
deleted file mode 100644
index aeb3c8a..0000000
--- a/emulator/keymaps/AVRCP.kl
+++ /dev/null
@@ -1,7 +0,0 @@
-key 200   MEDIA_PLAY_PAUSE    WAKE
-key 201   MEDIA_PLAY_PAUSE    WAKE
-key 166   MEDIA_STOP          WAKE
-key 163   MEDIA_NEXT          WAKE
-key 165   MEDIA_PREVIOUS      WAKE
-key 168   MEDIA_REWIND        WAKE
-key 208   MEDIA_FAST_FORWARD  WAKE
diff --git a/emulator/keymaps/Android.mk b/emulator/keymaps/Android.mk
deleted file mode 100644
index 81ac530..0000000
--- a/emulator/keymaps/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := qwerty.kcm
-include $(BUILD_KEY_CHAR_MAP)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := qwerty2.kcm
-include $(BUILD_KEY_CHAR_MAP)
-
-file := $(TARGET_OUT_KEYLAYOUT)/qwerty.kl
-ALL_PREBUILT += $(file)
-$(file): $(LOCAL_PATH)/qwerty.kl | $(ACP)
-	$(transform-prebuilt-to-target)
-
-file := $(TARGET_OUT_KEYLAYOUT)/AVRCP.kl
-ALL_PREBUILT += $(file)
-$(file) : $(LOCAL_PATH)/AVRCP.kl | $(ACP)
-	$(transform-prebuilt-to-target)
diff --git a/emulator/keymaps/qwerty.kcm b/emulator/keymaps/qwerty.kcm
deleted file mode 100644
index 8056364..0000000
--- a/emulator/keymaps/qwerty.kcm
+++ /dev/null
@@ -1,64 +0,0 @@
-[type=QWERTY]                                           
-                                                        
-# keycode       display number  base    caps    fn      caps_fn
-                                                        
-A               'A'     '2'     'a'     'A'     '#'     0x00
-B               'B'     '2'     'b'     'B'     '<'     0x00
-C               'C'     '2'     'c'     'C'     '9'     0x00E7
-D               'D'     '3'     'd'     'D'     '5'     0x00
-E               'E'     '3'     'e'     'E'     '2'     0x0301
-F               'F'     '3'     'f'     'F'     '6'     0x00A5
-G               'G'     '4'     'g'     'G'     '-'     '_'
-H               'H'     '4'     'h'     'H'     '['     '{'
-I               'I'     '4'     'i'     'I'     '$'     0x0302
-J               'J'     '5'     'j'     'J'     ']'     '}'
-K               'K'     '5'     'k'     'K'     '"'     '~'
-L               'L'     '5'     'l'     'L'     '''     '`'
-M               'M'     '6'     'm'     'M'     '!'     0x00
-N               'N'     '6'     'n'     'N'     '>'     0x0303
-O               'O'     '6'     'o'     'O'     '('     0x00
-P               'P'     '7'     'p'     'P'     ')'     0x00
-Q               'Q'     '7'     'q'     'Q'     '*'     0x0300
-R               'R'     '7'     'r'     'R'     '3'     0x20AC
-S               'S'     '7'     's'     'S'     '4'     0x00DF
-T               'T'     '8'     't'     'T'     '+'     0x00A3
-U               'U'     '8'     'u'     'U'     '&'     0x0308
-V               'V'     '8'     'v'     'V'     '='     '^'
-W               'W'     '9'     'w'     'W'     '1'     0x00
-X               'X'     '9'     'x'     'X'     '8'     0xEF00
-Y               'Y'     '9'     'y'     'Y'     '%'     0x00A1
-Z               'Z'     '9'     'z'     'Z'     '7'     0x00
-                                                        
-# on pc keyboards
-COMMA           ','     ','     ','     ';'     ';'     '|'
-PERIOD          '.'     '.'     '.'     ':'     ':'     0x2026
-AT              '@'     '0'     '@'     '0'     '0'     0x2022
-SLASH           '/'     '/'     '/'     '?'     '?'     '\'
-                                                        
-SPACE           0x20    0x20    0x20    0x20    0xEF01  0xEF01
-ENTER         0xa     0xa     0xa     0xa     0xa     0xa
-                                                        
-TAB             0x9     0x9     0x9     0x9     0x9     0x9
-0               '0'     '0'     '0'     ')'     ')'     ')'
-1               '1'     '1'     '1'     '!'     '!'     '!'
-2               '2'     '2'     '2'     '@'     '@'     '@'
-3               '3'     '3'     '3'     '#'     '#'     '#'
-4               '4'     '4'     '4'     '$'     '$'     '$'
-5               '5'     '5'     '5'     '%'     '%'     '%'
-6               '6'     '6'     '6'     '^'     '^'     '^'
-7               '7'     '7'     '7'     '&'     '&'     '&'
-8               '8'     '8'     '8'     '*'     '*'     '*'
-9               '9'     '9'     '9'     '('     '('     '('
-                                                        
-GRAVE           '`'     '`'     '`'     '~'     '`'     '~'
-MINUS           '-'     '-'     '-'     '_'     '-'     '_'
-EQUALS          '='     '='     '='     '+'     '='     '+'
-LEFT_BRACKET    '['     '['     '['     '{'     '['     '{'
-RIGHT_BRACKET   ']'     ']'     ']'     '}'     ']'     '}'
-BACKSLASH       '\'     '\'     '\'     '|'     '\'     '|'
-SEMICOLON       ';'     ';'     ';'     ':'     ';'     ':'
-APOSTROPHE      '''     '''     '''     '"'     '''     '"'
-STAR            '*'     '*'     '*'     '*'     '*'     '*'
-POUND           '#'     '#'     '#'     '#'     '#'     '#'
-PLUS            '+'     '+'     '+'     '+'     '+'     '+'
-                                                        
diff --git a/emulator/keymaps/qwerty.kl b/emulator/keymaps/qwerty.kl
deleted file mode 100644
index c525fdd..0000000
--- a/emulator/keymaps/qwerty.kl
+++ /dev/null
@@ -1,89 +0,0 @@
-key 399   GRAVE
-key 2     1
-key 3     2
-key 4     3
-key 5     4
-key 6     5
-key 7     6
-key 8     7
-key 9     8
-key 10    9
-key 11    0
-key 158   BACK              WAKE_DROPPED
-key 230   SOFT_RIGHT        WAKE
-key 60    SOFT_RIGHT        WAKE
-key 107   ENDCALL           WAKE_DROPPED
-key 62    ENDCALL           WAKE_DROPPED
-key 229   MENU              WAKE_DROPPED
-key 139   MENU              WAKE_DROPPED
-key 59    MENU              WAKE_DROPPED
-key 127   SEARCH            WAKE_DROPPED
-key 217   SEARCH            WAKE_DROPPED
-key 228   POUND
-key 227   STAR
-key 231   CALL              WAKE_DROPPED
-key 61    CALL              WAKE_DROPPED
-key 232   DPAD_CENTER       WAKE_DROPPED
-key 108   DPAD_DOWN         WAKE_DROPPED
-key 103   DPAD_UP           WAKE_DROPPED
-key 102   HOME              WAKE
-key 105   DPAD_LEFT         WAKE_DROPPED
-key 106   DPAD_RIGHT        WAKE_DROPPED
-key 115   VOLUME_UP
-key 114   VOLUME_DOWN
-key 116   POWER             WAKE
-key 212   CAMERA
-
-key 16    Q
-key 17    W
-key 18    E
-key 19    R
-key 20    T
-key 21    Y
-key 22    U
-key 23    I
-key 24    O
-key 25    P
-key 26    LEFT_BRACKET
-key 27    RIGHT_BRACKET
-key 43    BACKSLASH
-
-key 30    A
-key 31    S
-key 32    D
-key 33    F
-key 34    G
-key 35    H
-key 36    J
-key 37    K
-key 38    L
-key 39    SEMICOLON
-key 40    APOSTROPHE
-key 14    DEL
-        
-key 44    Z
-key 45    X
-key 46    C
-key 47    V
-key 48    B
-key 49    N
-key 50    M
-key 51    COMMA
-key 52    PERIOD
-key 53    SLASH
-key 28    ENTER
-        
-key 56    ALT_LEFT
-key 100   ALT_RIGHT
-key 42    SHIFT_LEFT
-key 54    SHIFT_RIGHT
-key 15    TAB
-key 57    SPACE
-key 150   EXPLORER
-key 155   ENVELOPE        
-
-key 12    MINUS
-key 13    EQUALS
-key 215   AT
-
-
diff --git a/emulator/keymaps/qwerty2.kcm b/emulator/keymaps/qwerty2.kcm
deleted file mode 100644
index 1487fb7..0000000
--- a/emulator/keymaps/qwerty2.kcm
+++ /dev/null
@@ -1,81 +0,0 @@
-[type=QWERTY]                                           
-                                                        
-# this keymap is to be used in the emulator only. note
-# that I have liberally modified certain key strokes to
-# make it more usable in this context. the main differences
-# with the reference keyboard image are:
-#
-#  - cap-2 produces '@', and not '"', without that, typing
-#    email addresses becomes a major pain with a qwerty
-#    keyboard. note that you can type '"' with fn-E anyway.
-#
-#  - cap-COMMA and cap-PERIOD return '<' and '>', instead
-#    of nothing.
-#
-#
-                                                        
-# keycode       display  number base    caps    fn      caps_fn
-                                                        
-A               'A'     '2'     'a'     'A'     'a'     'A'
-B               'B'     '2'     'b'     'B'     'b'     'B'
-C               'C'     '2'     'c'     'C'     0x00e7  0x00E7
-D               'D'     '3'     'd'     'D'     '''     '''
-E               'E'     '3'     'e'     'E'     '"'     0x0301
-F               'F'     '3'     'f'     'F'     '['     '['
-G               'G'     '4'     'g'     'G'     ']'     ']'
-H               'H'     '4'     'h'     'H'     '<'     '<'
-I               'I'     '4'     'i'     'I'     '-'     0x0302
-J               'J'     '5'     'j'     'J'     '>'     '>'
-K               'K'     '5'     'k'     'K'     ';'     '~'
-L               'L'     '5'     'l'     'L'     ':'     '`'
-M               'M'     '6'     'm'     'M'     '%'     0x00
-N               'N'     '6'     'n'     'N'     0x00    0x0303
-O               'O'     '6'     'o'     'O'     '+'     '+'
-P               'P'     '7'     'p'     'P'     '='     0x00A5
-Q               'Q'     '7'     'q'     'Q'     '|'     0x0300
-R               'R'     '7'     'r'     'R'     '`'     0x20AC
-S               'S'     '7'     's'     'S'     '\'     0x00DF
-T               'T'     '8'     't'     'T'     '{'     0x00A3
-U               'U'     '8'     'u'     'U'     '_'     0x0308
-V               'V'     '8'     'v'     'V'     'v'     'V'
-W               'W'     '9'     'w'     'W'     '~'     '~'
-X               'X'     '9'     'x'     'X'     'x'     0xEF00
-Y               'Y'     '9'     'y'     'Y'     '}'     0x00A1
-Z               'Z'     '9'     'z'     'Z'     'z'     'Z'
-                                                        
-COMMA           ','     ','     ','     '<'     ','     ','
-PERIOD          '.'     '.'     '.'     '>'     '.'     0x2026
-AT              '@'     '@'     '@'     '@'     '@'     0x2022
-SLASH           '/'     '/'     '/'     '?'     '?'     '?'
-                                                        
-SPACE           0x20    0x20    0x20    0x20    0xEF01  0xEF01
-ENTER         0xa     0xa     0xa     0xa     0xa     0xa
-                                                        
-0               '0'     '0'     '0'     ')'     ')'     ')'
-1               '1'     '1'     '1'     '!'     '!'     '!'
-2               '2'     '2'     '2'     '@'     '@'     '@'
-3               '3'     '3'     '3'     '#'     '#'     '#'
-4               '4'     '4'     '4'     '$'     '$'     '$'
-5               '5'     '5'     '5'     '%'     '%'     '%'
-6               '6'     '6'     '6'     '^'     '^'     '^'
-7               '7'     '7'     '7'     '&'     '&'     '&'
-8               '8'     '8'     '8'     '*'     '*'     '*'
-9               '9'     '9'     '9'     '('     '('     '('
-                                                        
-# the rest is for a qwerty keyboard
-#
-TAB             0x9     0x9     0x9     0x9     0x9     0x9
-GRAVE           '`'     '`'     '`'     '~'     '`'     '~'
-MINUS           '-'     '-'     '-'     '_'     '-'     '_'
-EQUALS          '='     '='     '='     '+'     '='     '+'
-LEFT_BRACKET    '['     '['     '['     '{'     '['     '{'
-RIGHT_BRACKET   ']'     ']'     ']'     '}'     ']'     '}'
-BACKSLASH       '\'     '\'     '\'     '|'     '\'     '|'
-SEMICOLON       ';'     ';'     ';'     ':'     ';'     ':'
-APOSTROPHE      '''     '''     '''     '"'     '''     '"'
-STAR            '*'     '*'     '*'     '*'     '*'     '*'
-POUND           '#'     '#'     '#'     '#'     '#'     '#'
-PLUS            '+'     '+'     '+'     '+'     '+'     '+'
-                                                        
-                                                        
-                                                        
diff --git a/emulator/mksdcard/Android.mk b/emulator/mksdcard/Android.mk
deleted file mode 100644
index a5641b4..0000000
--- a/emulator/mksdcard/Android.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2006 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-
-# host executable
-#
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= mksdcard.c
-LOCAL_MODULE = mksdcard
-include $(BUILD_HOST_EXECUTABLE)
-
diff --git a/emulator/mksdcard/mksdcard.c b/emulator/mksdcard/mksdcard.c
deleted file mode 100644
index c85d0f8..0000000
--- a/emulator/mksdcard/mksdcard.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/* mksdcard.c
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**     * Redistributions of source code must retain the above copyright
-**       notice, this list of conditions and the following disclaimer.
-**     * Redistributions in binary form must reproduce the above copyright
-**       notice, this list of conditions and the following disclaimer in the
-**       documentation and/or other materials provided with the distribution.
-**     * Neither the name of Google Inc. nor the names of its contributors may
-**       be used to endorse or promote products derived from this software
-**       without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* a simple and portable program used to generate a blank FAT32 image file
- *
- * usage:  mksdcard  [-l label] <size> <filename>
- */
-
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-/* believe me, you *don't* want to change these constants !! */
-#define  BYTES_PER_SECTOR    512
-#define  RESERVED_SECTORS    32
-#define  BACKUP_BOOT_SECTOR  6
-#define  NUM_FATS            2
-
-typedef long long      Wide;   /* might be something else if you don't use GCC */
-typedef unsigned char  Byte;
-typedef Byte*          Bytes;
-
-#define  BYTE_(p,i)      (((Bytes)(p))[(i)])
-
-#define  POKEB(p,v)     BYTE_(p,0) = (Byte)(v)
-#define  POKES(p,v)   ( BYTE_(p,0) = (Byte)(v), BYTE_(p,1) = (Byte)((v) >> 8) )
-#define  POKEW(p,v)   ( BYTE_(p,0) = (Byte)(v), BYTE_(p,1) = (Byte)((v) >> 8), BYTE_(p,2) = (Byte)((v) >> 16), BYTE_(p,3) = (Byte)((v) >> 24) )
-
-static Byte  s_boot_sector   [ BYTES_PER_SECTOR ];       /* boot sector */
-static Byte  s_fsinfo_sector [ BYTES_PER_SECTOR ];   /* FS Info sector */
-static Byte  s_fat_head      [ BYTES_PER_SECTOR ];        /* first FAT sector */
-static Byte  s_zero_sector   [ BYTES_PER_SECTOR ];     /* empty sector */
-
-/* this is the date and time when creating the disk */
-static int
-get_serial_id( void )
-{
-    unsigned short  lo, hi, mid;
-    time_t          now = time(NULL);
-    struct tm       tm  = gmtime( &now )[0];
-
-    lo  = (unsigned short)(tm.tm_mday + ((tm.tm_mon+1) << 8) + (tm.tm_sec << 8));
-    hi  = (unsigned short)(tm.tm_min + (tm.tm_hour << 8) + (tm.tm_year + 1900));
-
-    return lo + (hi << 16);
-}
-
-static int
-get_sectors_per_cluster( Wide  disk_size )
-{
-    Wide  disk_MB = disk_size/(1024*1024);
-
-    if (disk_MB < 260)
-        return 1;
-
-    if (disk_MB < 8192)
-        return 4;
-
-    if (disk_MB < 16384)
-        return 8;
-
-    if (disk_MB < 32768)
-        return 16;
-
-    return 32;
-}
-
-static int
-get_sectors_per_fat( Wide  disk_size, int  sectors_per_cluster )
-{
-    Wide   divider;
-
-    /* weird computation from MS - see fatgen103.doc for details */
-    disk_size -= RESERVED_SECTORS * BYTES_PER_SECTOR;  /* don't count 32 reserved sectors */
-    disk_size /= BYTES_PER_SECTOR;       /* disk size in sectors */
-    divider = ((256 * sectors_per_cluster) + NUM_FATS) / 2;
-
-    return (int)( (disk_size + (divider-1)) / divider );
-}
-
-static void
-boot_sector_init( Bytes  boot, Bytes  info, Wide   disk_size, const char*  label )
-{
-    int   sectors_per_cluster = get_sectors_per_cluster(disk_size);
-    int   sectors_per_fat    = get_sectors_per_fat(disk_size, sectors_per_cluster);
-    int   sectors_per_disk   = (int)(disk_size / BYTES_PER_SECTOR);
-    int   serial_id          = get_serial_id();
-    int   free_count;
-
-    if (label == NULL)
-        label = "SDCARD";
-
-    POKEB(boot, 0xeb);
-    POKEB(boot+1, 0x5a);
-    POKEB(boot+2, 0x90);
-    strcpy( (char*)boot + 3, "MSWIN4.1" );
-    POKES( boot + 0x0b, BYTES_PER_SECTOR );    /* sector size */
-    POKEB( boot + 0xd, sectors_per_cluster );  /* sectors per cluster */
-    POKES( boot + 0xe, RESERVED_SECTORS );     /* reserved sectors before first FAT */
-    POKEB( boot + 0x10, NUM_FATS );            /* number of FATs */
-    POKES( boot + 0x11, 0 );                   /* max root directory entries for FAT12/FAT16, 0 for FAT32 */
-    POKES( boot + 0x13, 0 );                   /* total sectors, 0 to use 32-bit value at offset 0x20 */
-    POKEB( boot + 0x15, 0xF8 );                /* media descriptor, 0xF8 == hard disk */
-    POKES( boot + 0x16, 0 );                   /* Sectors per FAT for FAT12/16, 0 for FAT32 */
-    POKES( boot + 0x18, 9 );                   /* Sectors per track (whatever) */
-    POKES( boot + 0x1a, 2 );                   /* Number of heads (whatever) */
-    POKEW( boot + 0x1c, 0 );                   /* Hidden sectors */
-    POKEW( boot + 0x20, sectors_per_disk );    /* Total sectors */
-
-    /* extension */
-    POKEW( boot + 0x24, sectors_per_fat );       /* Sectors per FAT */
-    POKES( boot + 0x28, 0 );         /* FAT flags */
-    POKES( boot + 0x2a, 0 );         /* version */
-    POKEW( boot + 0x2c, 2 );         /* cluster number of root directory start */
-    POKES( boot + 0x30, 1 );         /* sector number of FS information sector */
-    POKES( boot + 0x32, BACKUP_BOOT_SECTOR );         /* sector number of a copy of this boot sector */
-    POKEB( boot + 0x40, 0x80 );      /* physical drive number */
-    POKEB( boot + 0x42, 0x29 );      /* extended boot signature ?? */
-    POKEW( boot + 0x43, serial_id ); /* serial ID */
-    strncpy( (char*)boot + 0x47, label, 11 );  /* Volume Label */
-    memcpy( boot + 0x52, "FAT32   ", 8 );  /* FAT system type, padded with 0x20 */
-
-    POKEB( boot + BYTES_PER_SECTOR-2, 0x55 );    /* boot sector signature */
-    POKEB( boot + BYTES_PER_SECTOR-1, 0xAA );
-
-    /* FSInfo sector */
-    free_count = sectors_per_disk - 32 - 2*sectors_per_fat;
-
-    POKEW( info + 0,   0x41615252 );
-    POKEW( info + 484, 0x61417272 );
-    POKEW( info + 488, free_count );   /* number of free clusters */
-    POKEW( info + 492, 3 );            /* next free clusters, 0-1 reserved, 2 is used for the root dir */
-    POKEW( info + 508, 0xAA550000 );
-}
-
-static void
-fat_init( Bytes  fat )
-{
-    POKEW( fat,     0x0ffffff8 );  /* reserve cluster 1, media id in low byte */
-    POKEW( fat + 4, 0x0fffffff );  /* reserve cluster 2 */
-    POKEW( fat + 8, 0x0fffffff );  /* end of clust chain for root dir */
-}
-
-
-static int
-write_sector( FILE*  file, Bytes  sector )
-{
-    return fwrite( sector, 1, 512, file ) != 512;
-}
-
-static int
-write_empty( FILE*   file, Wide  count )
-{
-    static  Byte  empty[64*1024];
-
-    count *= 512;
-    while (count > 0) {
-        int  len = sizeof(empty);
-        if (len > count)
-            len = count;
-
-        if ( fwrite( empty, 1, len, file ) != (size_t)len )
-            return 1;
-
-        count -= len;
-    }
-    return 0;
-}
-
-static void usage (void)
-{
-    fprintf(stderr, "mksdcard: create a blank FAT32 image to be used with the Android emulator\n" );
-    fprintf(stderr, "usage: mksdcard [-l label] <size> <file>\n\n");
-    fprintf(stderr, "  if <size> is a simple integer, it specifies a size in bytes\n" );
-    fprintf(stderr, "  if <size> is an integer followed by 'K', it specifies a size in KiB\n" );
-    fprintf(stderr, "  if <size> is an integer followed by 'M', it specifies a size in MiB\n" );
-    exit(1);
-}
-
-int  main( int argc, char**  argv )
-{
-    Wide   disk_size;
-    int    sectors_per_fat;
-    int    sectors_per_disk;
-    char*  end;
-    const char*  label = NULL;
-    FILE*  f;
-
-    for ( ; argc > 1 && argv[1][0] == '-'; argc--, argv++ )
-    {
-        char*  arg = argv[1] + 1;
-        switch (arg[0]) {
-            case 'l':
-                if (arg[1] != 0)
-                    arg += 2;
-                else {
-                    argc--;
-                    argv++;
-                    if (argc <= 1)
-                        usage();
-                    arg = argv[1];
-                }
-                label = arg;
-                break;
-
-            default:
-                usage();
-        }
-    }
-
-    if (argc != 3)
-        usage();
-
-    disk_size = strtol( argv[1], &end, 10 );
-    if (disk_size == 0 && errno == EINVAL)
-        usage();
-
-    if (*end == 'K')
-        disk_size *= 1024;
-    else if (*end == 'M')
-        disk_size *= 1024*1024;
-
-    if (disk_size < 8*1024*1024)
-        fprintf(stderr, "### WARNING : SD Card images < 8 MB cannot be used with the Android emulator\n");
-
-    sectors_per_disk = disk_size / 512;
-    sectors_per_fat  = get_sectors_per_fat( disk_size, get_sectors_per_cluster( disk_size ) );
-
-    boot_sector_init( s_boot_sector, s_fsinfo_sector, disk_size, NULL );
-    fat_init( s_fat_head );
-
-    f = fopen( argv[2], "wb" );
-    if ( !f ) {
-        fprintf(stderr, "could not create file '%s', aborting...\n", argv[2] );
-    }
-
-   /* here's the layout:
-    *
-    *  boot_sector
-    *  fsinfo_sector
-    *  empty
-    *  backup boot sector
-    *  backup fsinfo sector
-    *  RESERVED_SECTORS - 4 empty sectors (if backup sectors), or RESERVED_SECTORS - 2 (if no backup)
-    *  first fat
-    *  second fat
-    *  zero sectors
-   */
-
-    if ( write_sector( f, s_boot_sector ) )  goto FailWrite;
-    if ( write_sector( f, s_fsinfo_sector ) ) goto FailWrite;
-    if ( BACKUP_BOOT_SECTOR > 0 ) {
-        if ( write_empty( f, BACKUP_BOOT_SECTOR - 2 ) ) goto FailWrite;
-        if ( write_sector( f, s_boot_sector ) ) goto FailWrite;
-        if ( write_sector( f, s_fsinfo_sector ) ) goto FailWrite;
-        if ( write_empty( f, RESERVED_SECTORS - 2 - BACKUP_BOOT_SECTOR ) ) goto FailWrite;
-    }
-    else
-        if ( write_empty( f, RESERVED_SECTORS - 2 ) ) goto FailWrite;
-
-    if ( write_sector( f, s_fat_head ) ) goto FailWrite;
-    if ( write_empty( f, sectors_per_fat-1 ) ) goto FailWrite;
-
-    if ( write_sector( f, s_fat_head ) ) goto FailWrite;
-    if ( write_empty( f, sectors_per_fat-1 ) ) goto FailWrite;
-
-    if ( write_empty( f, sectors_per_disk - RESERVED_SECTORS - 2*sectors_per_fat ) ) goto FailWrite;
-
-    fclose(f);
-    return 0;
-
-FailWrite:
-    fprintf(stderr, "could not write to '%s', aborting...\n", argv[2] );
-    unlink( argv[2] );
-    fclose(f);
-    return 1;
-}
diff --git a/emulator/mksdcard/vfat-empty-32MB.img.gz b/emulator/mksdcard/vfat-empty-32MB.img.gz
deleted file mode 100644
index b205da3..0000000
--- a/emulator/mksdcard/vfat-empty-32MB.img.gz
+++ /dev/null
Binary files differ
diff --git a/emulator/qemud/Android.mk b/emulator/qemud/Android.mk
deleted file mode 100644
index a186c73..0000000
--- a/emulator/qemud/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	qemud.c
-
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-
-LOCAL_MODULE:= qemud
-LOCAL_MODULE_TAGS := debug
-
-include $(BUILD_EXECUTABLE)
diff --git a/emulator/qemud/qemud.c b/emulator/qemud/qemud.c
deleted file mode 100644
index 92b2a2b..0000000
--- a/emulator/qemud/qemud.c
+++ /dev/null
@@ -1,1715 +0,0 @@
-#include <stdint.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <termios.h>
-#include <cutils/sockets.h>
-
-/*
- *  the qemud daemon program is only used within Android as a bridge
- *  between the emulator program and the emulated system. it really works as
- *  a simple stream multiplexer that works as follows:
- *
- *    - qemud is started by init following instructions in
- *      /system/etc/init.goldfish.rc (i.e. it is never started on real devices)
- *
- *    - qemud communicates with the emulator program through a single serial
- *      port, whose name is passed through a kernel boot parameter
- *      (e.g. android.qemud=ttyS1)
- *
- *    - qemud binds one unix local stream socket (/dev/socket/qemud, created
- *      by init through /system/etc/init.goldfish.rc).
- *
- *
- *      emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
- *                                                            |
- *                                                            +--> client2
- *
- *   - the special channel index 0 is used by the emulator and qemud only.
- *     other channel numbers correspond to clients. More specifically,
- *     connection are created like this:
- *
- *     * the client connects to /dev/socket/qemud
- *
- *     * the client sends the service name through the socket, as
- *            <service-name>
- *
- *     * qemud creates a "Client" object internally, assigns it an
- *       internal unique channel number > 0, then sends a connection
- *       initiation request to the emulator (i.e. through channel 0):
- *
- *           connect:<id>:<name>
- *
- *       where <name> is the service name, and <id> is a 2-hexchar
- *       number corresponding to the channel number.
- *
- *     * in case of success, the emulator responds through channel 0
- *       with:
- *
- *           ok:connect:<id>
- *
- *       after this, all messages between the client and the emulator
- *       are passed in pass-through mode.
- *
- *     * if the emulator refuses the service connection, it will
- *       send the following through channel 0:
- *
- *           ko:connect:<id>:reason-for-failure
- *
- *     * If the client closes the connection, qemud sends the following
- *       to the emulator:
- *
- *           disconnect:<id>
- *
- *       The same message is the opposite direction if the emulator
- *       chooses to close the connection.
- *
- *     * any command sent through channel 0 to the emulator that is
- *       not properly recognized will be answered by:
- *
- *           ko:unknown command
- *
- *
- *  Internally, the daemon maintains a "Client" object for each client
- *  connection (i.e. accepting socket connection).
- */
-
-/* name of the single control socket used by the daemon */
-#define CONTROL_SOCKET_NAME  "qemud"
-
-#define  DEBUG     1
-#define  T_ACTIVE  0  /* set to 1 to dump traffic */
-
-#if DEBUG
-#  define LOG_TAG  "qemud"
-#  include <cutils/log.h>
-#  define  D(...)   LOGD(__VA_ARGS__)
-#else
-#  define  D(...)  ((void)0)
-#  define  T(...)  ((void)0)
-#endif
-
-#if T_ACTIVE
-#  define  T(...)   D(__VA_ARGS__)
-#else
-#  define  T(...)   ((void)0)
-#endif
-
-/** UTILITIES
- **/
-
-static void
-fatal( const char*  fmt, ... )
-{
-    va_list  args;
-    va_start(args, fmt);
-    fprintf(stderr, "PANIC: ");
-    vfprintf(stderr, fmt, args);
-    fprintf(stderr, "\n" );
-    va_end(args);
-    exit(1);
-}
-
-static void*
-xalloc( size_t   sz )
-{
-    void*  p;
-
-    if (sz == 0)
-        return NULL;
-
-    p = malloc(sz);
-    if (p == NULL)
-        fatal( "not enough memory" );
-
-    return p;
-}
-
-#define  xnew(p)   (p) = xalloc(sizeof(*(p)))
-
-static void*
-xalloc0( size_t  sz )
-{
-    void*  p = xalloc(sz);
-    memset( p, 0, sz );
-    return p;
-}
-
-#define  xnew0(p)   (p) = xalloc0(sizeof(*(p)))
-
-#define  xfree(p)    (free((p)), (p) = NULL)
-
-static void*
-xrealloc( void*  block, size_t  size )
-{
-    void*  p = realloc( block, size );
-
-    if (p == NULL && size > 0)
-        fatal( "not enough memory" );
-
-    return p;
-}
-
-#define  xrenew(p,count)  (p) = xrealloc((p),sizeof(*(p))*(count))
-
-static int
-hex2int( const uint8_t*  data, int  len )
-{
-    int  result = 0;
-    while (len > 0) {
-        int       c = *data++;
-        unsigned  d;
-
-        result <<= 4;
-        do {
-            d = (unsigned)(c - '0');
-            if (d < 10)
-                break;
-
-            d = (unsigned)(c - 'a');
-            if (d < 6) {
-                d += 10;
-                break;
-            }
-
-            d = (unsigned)(c - 'A');
-            if (d < 6) {
-                d += 10;
-                break;
-            }
-
-            return -1;
-        }
-        while (0);
-
-        result |= d;
-        len    -= 1;
-    }
-    return  result;
-}
-
-
-static void
-int2hex( int  value, uint8_t*  to, int  width )
-{
-    int  nn = 0;
-    static const char hexchars[16] = "0123456789abcdef";
-
-    for ( --width; width >= 0; width--, nn++ ) {
-        to[nn] = hexchars[(value >> (width*4)) & 15];
-    }
-}
-
-static int
-fd_read(int  fd, void*  to, int  len)
-{
-    int  ret;
-
-    do {
-        ret = read(fd, to, len);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-static int
-fd_write(int  fd, const void*  from, int  len)
-{
-    int  ret;
-
-    do {
-        ret = write(fd, from, len);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-static void
-fd_setnonblock(int  fd)
-{
-    int  ret, flags;
-
-    do {
-        flags = fcntl(fd, F_GETFD);
-    } while (flags < 0 && errno == EINTR);
-
-    if (flags < 0) {
-        fatal( "%s: could not get flags for fd %d: %s",
-               __FUNCTION__, fd, strerror(errno) );
-    }
-
-    do {
-        ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0) {
-        fatal( "%s: could not set fd %d to non-blocking: %s",
-               __FUNCTION__, fd, strerror(errno) );
-    }
-}
-
-
-static int
-fd_accept(int  fd)
-{
-    struct sockaddr  from;
-    socklen_t        fromlen = sizeof(from);
-    int              ret;
-
-    do {
-        ret = accept(fd, &from, &fromlen);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-/** FD EVENT LOOP
- **/
-
-/* A Looper object is used to monitor activity on one or more
- * file descriptors (e.g sockets).
- *
- * - call looper_add() to register a function that will be
- *   called when events happen on the file descriptor.
- *
- * - call looper_enable() or looper_disable() to enable/disable
- *   the set of monitored events for a given file descriptor.
- *
- * - call looper_del() to unregister a file descriptor.
- *   this does *not* close the file descriptor.
- *
- * Note that you can only provide a single function to handle
- * all events related to a given file descriptor.
-
- * You can call looper_enable/_disable/_del within a function
- * callback.
- */
-
-/* the current implementation uses Linux's epoll facility
- * the event mask we use are simply combinations of EPOLLIN
- * EPOLLOUT, EPOLLHUP and EPOLLERR
- */
-#include <sys/epoll.h>
-
-#define  MAX_CHANNELS  16
-#define  MAX_EVENTS    (MAX_CHANNELS+1)  /* each channel + the serial fd */
-
-/* the event handler function type, 'user' is a user-specific
- * opaque pointer passed to looper_add().
- */
-typedef void (*EventFunc)( void*  user, int  events );
-
-/* bit flags for the LoopHook structure.
- *
- * HOOK_PENDING means that an event happened on the
- * corresponding file descriptor.
- *
- * HOOK_CLOSING is used to delay-close monitored
- * file descriptors.
- */
-enum {
-    HOOK_PENDING = (1 << 0),
-    HOOK_CLOSING = (1 << 1),
-};
-
-/* A LoopHook structure is used to monitor a given
- * file descriptor and record its event handler.
- */
-typedef struct {
-    int        fd;
-    int        wanted;  /* events we are monitoring */
-    int        events;  /* events that occured */
-    int        state;   /* see HOOK_XXX constants */
-    void*      ev_user; /* user-provided handler parameter */
-    EventFunc  ev_func; /* event handler callback */
-} LoopHook;
-
-/* Looper is the main object modeling a looper object
- */
-typedef struct {
-    int                  epoll_fd;
-    int                  num_fds;
-    int                  max_fds;
-    struct epoll_event*  events;
-    LoopHook*            hooks;
-} Looper;
-
-/* initialize a looper object */
-static void
-looper_init( Looper*  l )
-{
-    l->epoll_fd = epoll_create(4);
-    l->num_fds  = 0;
-    l->max_fds  = 0;
-    l->events   = NULL;
-    l->hooks    = NULL;
-}
-
-/* finalize a looper object */
-static void
-looper_done( Looper*  l )
-{
-    xfree(l->events);
-    xfree(l->hooks);
-    l->max_fds = 0;
-    l->num_fds = 0;
-
-    close(l->epoll_fd);
-    l->epoll_fd  = -1;
-}
-
-/* return the LoopHook corresponding to a given
- * monitored file descriptor, or NULL if not found
- */
-static LoopHook*
-looper_find( Looper*  l, int  fd )
-{
-    LoopHook*  hook = l->hooks;
-    LoopHook*  end  = hook + l->num_fds;
-
-    for ( ; hook < end; hook++ ) {
-        if (hook->fd == fd)
-            return hook;
-    }
-    return NULL;
-}
-
-/* grow the arrays in the looper object */
-static void
-looper_grow( Looper*  l )
-{
-    int  old_max = l->max_fds;
-    int  new_max = old_max + (old_max >> 1) + 4;
-    int  n;
-
-    xrenew( l->events, new_max );
-    xrenew( l->hooks,  new_max );
-    l->max_fds = new_max;
-
-    /* now change the handles to all events */
-    for (n = 0; n < l->num_fds; n++) {
-        struct epoll_event ev;
-        LoopHook*          hook = l->hooks + n;
-
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
-    }
-}
-
-/* register a file descriptor and its event handler.
- * no event mask will be enabled
- */
-static void
-looper_add( Looper*  l, int  fd, EventFunc  func, void*  user )
-{
-    struct epoll_event  ev;
-    LoopHook*           hook;
-
-    if (l->num_fds >= l->max_fds)
-        looper_grow(l);
-
-    hook = l->hooks + l->num_fds;
-
-    hook->fd      = fd;
-    hook->ev_user = user;
-    hook->ev_func = func;
-    hook->state   = 0;
-    hook->wanted  = 0;
-    hook->events  = 0;
-
-    fd_setnonblock(fd);
-
-    ev.events   = 0;
-    ev.data.ptr = hook;
-    epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );
-
-    l->num_fds += 1;
-}
-
-/* unregister a file descriptor and its event handler
- */
-static void
-looper_del( Looper*  l, int  fd )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D( "%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-    /* don't remove the hook yet */
-    hook->state |= HOOK_CLOSING;
-
-    epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
-}
-
-/* enable monitoring of certain events for a file
- * descriptor. This adds 'events' to the current
- * event mask
- */
-static void
-looper_enable( Looper*  l, int  fd, int  events )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D("%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-
-    if (events & ~hook->wanted) {
-        struct epoll_event  ev;
-
-        hook->wanted |= events;
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
-    }
-}
-
-/* disable monitoring of certain events for a file
- * descriptor. This ignores events that are not
- * currently enabled.
- */
-static void
-looper_disable( Looper*  l, int  fd, int  events )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D("%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-
-    if (events & hook->wanted) {
-        struct epoll_event  ev;
-
-        hook->wanted &= ~events;
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
-    }
-}
-
-/* wait until an event occurs on one of the registered file
- * descriptors. Only returns in case of error !!
- */
-static void
-looper_loop( Looper*  l )
-{
-    for (;;) {
-        int  n, count;
-
-        do {
-            count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
-        } while (count < 0 && errno == EINTR);
-
-        if (count < 0) {
-            D("%s: error: %s", __FUNCTION__, strerror(errno) );
-            return;
-        }
-
-        if (count == 0) {
-            D("%s: huh ? epoll returned count=0", __FUNCTION__);
-            continue;
-        }
-
-        /* mark all pending hooks */
-        for (n = 0; n < count; n++) {
-            LoopHook*  hook = l->events[n].data.ptr;
-            hook->state  = HOOK_PENDING;
-            hook->events = l->events[n].events;
-        }
-
-        /* execute hook callbacks. this may change the 'hooks'
-         * and 'events' array, as well as l->num_fds, so be careful */
-        for (n = 0; n < l->num_fds; n++) {
-            LoopHook*  hook = l->hooks + n;
-            if (hook->state & HOOK_PENDING) {
-                hook->state &= ~HOOK_PENDING;
-                hook->ev_func( hook->ev_user, hook->events );
-            }
-        }
-
-        /* now remove all the hooks that were closed by
-         * the callbacks */
-        for (n = 0; n < l->num_fds;) {
-            LoopHook*  hook = l->hooks + n;
-
-            if (!(hook->state & HOOK_CLOSING)) {
-                n++;
-                continue;
-            }
-
-            hook[0]     = l->hooks[l->num_fds-1];
-            l->num_fds -= 1;
-        }
-    }
-}
-
-#if T_ACTIVE
-char*
-quote( const void*  data, int  len )
-{
-    const char*  p   = data;
-    const char*  end = p + len;
-    int          count = 0;
-    int          phase = 0;
-    static char*  buff = NULL;
-
-    for (phase = 0; phase < 2; phase++) {
-        if (phase != 0) {
-            xfree(buff);
-            buff = xalloc(count+1);
-        }
-        count = 0;
-        for (p = data; p < end; p++) {
-            int  c = *p;
-
-            if (c == '\\') {
-                if (phase != 0) {
-                    buff[count] = buff[count+1] = '\\';
-                }
-                count += 2;
-                continue;
-            }
-
-            if (c >= 32 && c < 127) {
-                if (phase != 0)
-                    buff[count] = c;
-                count += 1;
-                continue;
-            }
-
-
-            if (c == '\t') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<TAB>", 5);
-                }
-                count += 5;
-                continue;
-            }
-            if (c == '\n') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<LN>", 4);
-                }
-                count += 4;
-                continue;
-            }
-            if (c == '\r') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<CR>", 4);
-                }
-                count += 4;
-                continue;
-            }
-
-            if (phase != 0) {
-                buff[count+0] = '\\';
-                buff[count+1] = 'x';
-                buff[count+2] = "0123456789abcdef"[(c >> 4) & 15];
-                buff[count+3] = "0123456789abcdef"[     (c) & 15];
-            }
-            count += 4;
-        }
-    }
-    buff[count] = 0;
-    return buff;
-}
-#endif /* T_ACTIVE */
-
-/** PACKETS
- **
- ** We need a way to buffer data before it can be sent to the
- ** corresponding file descriptor. We use linked list of Packet
- ** objects to do this.
- **/
-
-typedef struct Packet   Packet;
-
-#define  MAX_PAYLOAD  4000
-
-struct Packet {
-    Packet*   next;
-    int       len;
-    int       channel;
-    uint8_t   data[ MAX_PAYLOAD ];
-};
-
-/* we expect to alloc/free a lot of packets during
- * operations so use a single linked list of free packets
- * to keep things speedy and simple.
- */
-static Packet*   _free_packets;
-
-/* Allocate a packet */
-static Packet*
-packet_alloc(void)
-{
-    Packet*  p = _free_packets;
-    if (p != NULL) {
-        _free_packets = p->next;
-    } else {
-        xnew(p);
-    }
-    p->next    = NULL;
-    p->len     = 0;
-    p->channel = -1;
-    return p;
-}
-
-/* Release a packet. This takes the address of a packet
- * pointer that will be set to NULL on exit (avoids
- * referencing dangling pointers in case of bugs)
- */
-static void
-packet_free( Packet*  *ppacket )
-{
-    Packet*  p = *ppacket;
-    if (p) {
-        p->next       = _free_packets;
-        _free_packets = p;
-        *ppacket = NULL;
-    }
-}
-
-/** PACKET RECEIVER
- **
- ** Simple abstraction for something that can receive a packet
- ** from a FDHandler (see below) or something else.
- **
- ** Send a packet to it with 'receiver_post'
- **
- ** Call 'receiver_close' to indicate that the corresponding
- ** packet source was closed.
- **/
-
-typedef void (*PostFunc) ( void*  user, Packet*  p );
-typedef void (*CloseFunc)( void*  user );
-
-typedef struct {
-    PostFunc   post;
-    CloseFunc  close;
-    void*      user;
-} Receiver;
-
-/* post a packet to a receiver. Note that this transfers
- * ownership of the packet to the receiver.
- */
-static __inline__ void
-receiver_post( Receiver*  r, Packet*  p )
-{
-    if (r->post)
-        r->post( r->user, p );
-    else
-        packet_free(&p);
-}
-
-/* tell a receiver the packet source was closed.
- * this will also prevent further posting to the
- * receiver.
- */
-static __inline__ void
-receiver_close( Receiver*  r )
-{
-    if (r->close) {
-        r->close( r->user );
-        r->close = NULL;
-    }
-    r->post  = NULL;
-}
-
-
-/** FD HANDLERS
- **
- ** these are smart listeners that send incoming packets to a receiver
- ** and can queue one or more outgoing packets and send them when
- ** possible to the FD.
- **
- ** note that we support clean shutdown of file descriptors,
- ** i.e. we try to send all outgoing packets before destroying
- ** the FDHandler.
- **/
-
-typedef struct FDHandler      FDHandler;
-typedef struct FDHandlerList  FDHandlerList;
-
-struct FDHandler {
-    int             fd;
-    FDHandlerList*  list;
-    char            closing;
-    Receiver        receiver[1];
-
-    /* queue of outgoing packets */
-    int             out_pos;
-    Packet*         out_first;
-    Packet**        out_ptail;
-
-    FDHandler*      next;
-    FDHandler**     pref;
-
-};
-
-struct FDHandlerList {
-    /* the looper that manages the fds */
-    Looper*      looper;
-
-    /* list of active FDHandler objects */
-    FDHandler*   active;
-
-    /* list of closing FDHandler objects.
-     * these are waiting to push their
-     * queued packets to the fd before
-     * freeing themselves.
-     */
-    FDHandler*   closing;
-
-};
-
-/* remove a FDHandler from its current list */
-static void
-fdhandler_remove( FDHandler*  f )
-{
-    f->pref[0] = f->next;
-    if (f->next)
-        f->next->pref = f->pref;
-}
-
-/* add a FDHandler to a given list */
-static void
-fdhandler_prepend( FDHandler*  f, FDHandler**  list )
-{
-    f->next = list[0];
-    f->pref = list;
-    list[0] = f;
-    if (f->next)
-        f->next->pref = &f->next;
-}
-
-/* initialize a FDHandler list */
-static void
-fdhandler_list_init( FDHandlerList*  list, Looper*  looper )
-{
-    list->looper  = looper;
-    list->active  = NULL;
-    list->closing = NULL;
-}
-
-
-/* close a FDHandler (and free it). Note that this will not
- * perform a graceful shutdown, i.e. all packets in the
- * outgoing queue will be immediately free.
- *
- * this *will* notify the receiver that the file descriptor
- * was closed.
- *
- * you should call fdhandler_shutdown() if you want to
- * notify the FDHandler that its packet source is closed.
- */
-static void
-fdhandler_close( FDHandler*  f )
-{
-    /* notify receiver */
-    receiver_close(f->receiver);
-
-    /* remove the handler from its list */
-    fdhandler_remove(f);
-
-    /* get rid of outgoing packet queue */
-    if (f->out_first != NULL) {
-        Packet*  p;
-        while ((p = f->out_first) != NULL) {
-            f->out_first = p->next;
-            packet_free(&p);
-        }
-    }
-
-    /* get rid of file descriptor */
-    if (f->fd >= 0) {
-        looper_del( f->list->looper, f->fd );
-        close(f->fd);
-        f->fd = -1;
-    }
-
-    f->list = NULL;
-    xfree(f);
-}
-
-/* Ask the FDHandler to cleanly shutdown the connection,
- * i.e. send any pending outgoing packets then auto-free
- * itself.
- */
-static void
-fdhandler_shutdown( FDHandler*  f )
-{
-    /* prevent later fdhandler_close() to
-     * call the receiver's close.
-     */
-    f->receiver->close = NULL;
-
-    if (f->out_first != NULL && !f->closing)
-    {
-        /* move the handler to the 'closing' list */
-        f->closing = 1;
-        fdhandler_remove(f);
-        fdhandler_prepend(f, &f->list->closing);
-        return;
-    }
-
-    fdhandler_close(f);
-}
-
-/* Enqueue a new packet that the FDHandler will
- * send through its file descriptor.
- */
-static void
-fdhandler_enqueue( FDHandler*  f, Packet*  p )
-{
-    Packet*  first = f->out_first;
-
-    p->next         = NULL;
-    f->out_ptail[0] = p;
-    f->out_ptail    = &p->next;
-
-    if (first == NULL) {
-        f->out_pos = 0;
-        looper_enable( f->list->looper, f->fd, EPOLLOUT );
-    }
-}
-
-
-/* FDHandler file descriptor event callback for read/write ops */
-static void
-fdhandler_event( FDHandler*  f, int  events )
-{
-   int  len;
-
-    /* in certain cases, it's possible to have both EPOLLIN and
-     * EPOLLHUP at the same time. This indicates that there is incoming
-     * data to read, but that the connection was nonetheless closed
-     * by the sender. Be sure to read the data before closing
-     * the receiver to avoid packet loss.
-     */
-
-    if (events & EPOLLIN) {
-        Packet*  p = packet_alloc();
-        int      len;
-
-        if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
-            D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
-            packet_free(&p);
-        } else if (len > 0) {
-            p->len     = len;
-            p->channel = -101;  /* special debug value, not used */
-            receiver_post( f->receiver, p );
-        }
-    }
-
-    if (events & (EPOLLHUP|EPOLLERR)) {
-        /* disconnection */
-        D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
-        fdhandler_close(f);
-        return;
-    }
-
-    if (events & EPOLLOUT && f->out_first) {
-        Packet*  p = f->out_first;
-        int      avail, len;
-
-        avail = p->len - f->out_pos;
-        if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
-            D("%s: can't send: %s", __FUNCTION__, strerror(errno));
-        } else {
-            f->out_pos += len;
-            if (f->out_pos >= p->len) {
-                f->out_pos   = 0;
-                f->out_first = p->next;
-                packet_free(&p);
-                if (f->out_first == NULL) {
-                    f->out_ptail = &f->out_first;
-                    looper_disable( f->list->looper, f->fd, EPOLLOUT );
-                }
-            }
-        }
-    }
-}
-
-
-/* Create a new FDHandler that monitors read/writes */
-static FDHandler*
-fdhandler_new( int             fd,
-               FDHandlerList*  list,
-               Receiver*       receiver )
-{
-    FDHandler*  f = xalloc0(sizeof(*f));
-
-    f->fd          = fd;
-    f->list        = list;
-    f->receiver[0] = receiver[0];
-    f->out_first   = NULL;
-    f->out_ptail   = &f->out_first;
-    f->out_pos     = 0;
-
-    fdhandler_prepend(f, &list->active);
-
-    looper_add( list->looper, fd, (EventFunc) fdhandler_event, f );
-    looper_enable( list->looper, fd, EPOLLIN );
-
-    return f;
-}
-
-
-/* event callback function to monitor accepts() on server sockets.
- * the convention used here is that the receiver will receive a
- * dummy packet with the new client socket in p->channel
- */
-static void
-fdhandler_accept_event( FDHandler*  f, int  events )
-{
-    if (events & EPOLLIN) {
-        /* this is an accept - send a dummy packet to the receiver */
-        Packet*  p = packet_alloc();
-
-        D("%s: accepting on fd %d", __FUNCTION__, f->fd);
-        p->data[0] = 1;
-        p->len     = 1;
-        p->channel = fd_accept(f->fd);
-        if (p->channel < 0) {
-            D("%s: accept failed ?: %s", __FUNCTION__, strerror(errno));
-            packet_free(&p);
-            return;
-        }
-        receiver_post( f->receiver, p );
-    }
-
-    if (events & (EPOLLHUP|EPOLLERR)) {
-        /* disconnecting !! */
-        D("%s: closing accept fd %d", __FUNCTION__, f->fd);
-        fdhandler_close(f);
-        return;
-    }
-}
-
-
-/* Create a new FDHandler used to monitor new connections on a
- * server socket. The receiver must expect the new connection
- * fd in the 'channel' field of a dummy packet.
- */
-static FDHandler*
-fdhandler_new_accept( int             fd,
-                      FDHandlerList*  list,
-                      Receiver*       receiver )
-{
-    FDHandler*  f = xalloc0(sizeof(*f));
-
-    f->fd          = fd;
-    f->list        = list;
-    f->receiver[0] = receiver[0];
-
-    fdhandler_prepend(f, &list->active);
-
-    looper_add( list->looper, fd, (EventFunc) fdhandler_accept_event, f );
-    looper_enable( list->looper, fd, EPOLLIN );
-    listen( fd, 5 );
-
-    return f;
-}
-
-/** SERIAL CONNECTION STATE
- **
- ** The following is used to handle the framing protocol
- ** used on the serial port connection.
- **/
-
-/* each packet is made of a 6 byte header followed by a payload
- * the header looks like:
- *
- *   offset   size    description
- *       0       2    a 2-byte hex string for the channel number
- *       4       4    a 4-char hex string for the size of the payload
- *       6       n    the payload itself
- */
-#define  HEADER_SIZE    6
-#define  CHANNEL_OFFSET 0
-#define  LENGTH_OFFSET  2
-#define  CHANNEL_SIZE   2
-#define  LENGTH_SIZE    4
-
-#define  CHANNEL_CONTROL  0
-
-/* The Serial object receives data from the serial port,
- * extracts the payload size and channel index, then sends
- * the resulting messages as a packet to a generic receiver.
- *
- * You can also use serial_send to send a packet through
- * the serial port.
- */
-typedef struct Serial {
-    FDHandler*  fdhandler;   /* used to monitor serial port fd */
-    Receiver    receiver[1]; /* send payload there */
-    int         in_len;      /* current bytes in input packet */
-    int         in_datalen;  /* payload size, or 0 when reading header */
-    int         in_channel;  /* extracted channel number */
-    Packet*     in_packet;   /* used to read incoming packets */
-} Serial;
-
-
-/* a callback called when the serial port's fd is closed */
-static void
-serial_fd_close( Serial*  s )
-{
-    fatal("unexpected serial port close !!");
-}
-
-static void
-serial_dump( Packet*  p, const char*  funcname )
-{
-    T("%s: %03d bytes: '%s'",
-      funcname, p->len, quote(p->data, p->len));
-}
-
-/* a callback called when a packet arrives from the serial port's FDHandler.
- *
- * This will essentially parse the header, extract the channel number and
- * the payload size and store them in 'in_datalen' and 'in_channel'.
- *
- * After that, the payload is sent to the receiver once completed.
- */
-static void
-serial_fd_receive( Serial*  s, Packet*  p )
-{
-    int      rpos  = 0, rcount = p->len;
-    Packet*  inp   = s->in_packet;
-    int      inpos = s->in_len;
-
-    serial_dump( p, __FUNCTION__ );
-
-    while (rpos < rcount)
-    {
-        int  avail = rcount - rpos;
-
-        /* first, try to read the header */
-        if (s->in_datalen == 0) {
-            int  wanted = HEADER_SIZE - inpos;
-            if (avail > wanted)
-                avail = wanted;
-
-            memcpy( inp->data + inpos, p->data + rpos, avail );
-            inpos += avail;
-            rpos  += avail;
-
-            if (inpos == HEADER_SIZE) {
-                s->in_datalen = hex2int( inp->data + LENGTH_OFFSET,  LENGTH_SIZE );
-                s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );
-
-                if (s->in_datalen <= 0) {
-                    D("ignoring %s packet from serial port",
-                      s->in_datalen ? "empty" : "malformed");
-                    s->in_datalen = 0;
-                }
-
-                //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
-                inpos = 0;
-            }
-        }
-        else /* then, populate the packet itself */
-        {
-            int   wanted = s->in_datalen - inpos;
-
-            if (avail > wanted)
-                avail = wanted;
-
-            memcpy( inp->data + inpos, p->data + rpos, avail );
-            inpos += avail;
-            rpos  += avail;
-
-            if (inpos == s->in_datalen) {
-                if (s->in_channel < 0) {
-                    D("ignoring %d bytes addressed to channel %d",
-                       inpos, s->in_channel);
-                } else {
-                    inp->len     = inpos;
-                    inp->channel = s->in_channel;
-                    receiver_post( s->receiver, inp );
-                    s->in_packet  = inp = packet_alloc();
-                }
-                s->in_datalen = 0;
-                inpos         = 0;
-            }
-        }
-    }
-    s->in_len = inpos;
-    packet_free(&p);
-}
-
-
-/* send a packet to the serial port.
- * this assumes that p->len and p->channel contain the payload's
- * size and channel and will add the appropriate header.
- */
-static void
-serial_send( Serial*  s, Packet*  p )
-{
-    Packet*  h = packet_alloc();
-
-    //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);
-
-    /* insert a small header before this packet */
-    h->len = HEADER_SIZE;
-    int2hex( p->len,     h->data + LENGTH_OFFSET,  LENGTH_SIZE );
-    int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );
-
-    serial_dump( h, __FUNCTION__ );
-    serial_dump( p, __FUNCTION__ );
-
-    fdhandler_enqueue( s->fdhandler, h );
-    fdhandler_enqueue( s->fdhandler, p );
-}
-
-
-/* initialize serial reader */
-static void
-serial_init( Serial*         s,
-             int             fd,
-             FDHandlerList*  list,
-             Receiver*       receiver )
-{
-    Receiver  recv;
-
-    recv.user  = s;
-    recv.post  = (PostFunc)  serial_fd_receive;
-    recv.close = (CloseFunc) serial_fd_close;
-
-    s->receiver[0] = receiver[0];
-
-    s->fdhandler = fdhandler_new( fd, list, &recv );
-    s->in_len     = 0;
-    s->in_datalen = 0;
-    s->in_channel = 0;
-    s->in_packet  = packet_alloc();
-}
-
-
-/** CLIENTS
- **/
-
-typedef struct Client       Client;
-typedef struct Multiplexer  Multiplexer;
-
-/* A Client object models a single qemud client socket
- * connection in the emulated system.
- *
- * the client first sends the name of the system service
- * it wants to contact (no framing), then waits for a 2
- * byte answer from qemud.
- *
- * the answer is either "OK" or "KO" to indicate
- * success or failure.
- *
- * In case of success, the client can send messages
- * to the service.
- *
- * In case of failure, it can disconnect or try sending
- * the name of another service.
- */
-struct Client {
-    Client*       next;
-    Client**      pref;
-    int           channel;
-    char          registered;
-    FDHandler*    fdhandler;
-    Multiplexer*  multiplexer;
-};
-
-struct Multiplexer {
-    Client*        clients;
-    int            last_channel;
-    Serial         serial[1];
-    Looper         looper[1];
-    FDHandlerList  fdhandlers[1];
-};
-
-
-static int   multiplexer_open_channel( Multiplexer*  mult, Packet*  p );
-static void  multiplexer_close_channel( Multiplexer*  mult, int  channel );
-static void  multiplexer_serial_send( Multiplexer* mult, int  channel, Packet*  p );
-
-static void
-client_dump( Client*  c, Packet*  p, const char*  funcname )
-{
-    T("%s: client %p (%d): %3d bytes: '%s'",
-      funcname, c, c->fdhandler->fd,
-      p->len, quote(p->data, p->len));
-}
-
-/* destroy a client */
-static void
-client_free( Client*  c )
-{
-    /* remove from list */
-    c->pref[0] = c->next;
-    if (c->next)
-        c->next->pref = c->pref;
-
-    c->channel    = -1;
-    c->registered = 0;
-
-    /* gently ask the FDHandler to shutdown to
-     * avoid losing queued outgoing packets */
-    if (c->fdhandler != NULL) {
-        fdhandler_shutdown(c->fdhandler);
-        c->fdhandler = NULL;
-    }
-
-    xfree(c);
-}
-
-
-/* a function called when a client socket receives data */
-static void
-client_fd_receive( Client*  c, Packet*  p )
-{
-    client_dump(c, p, __FUNCTION__);
-
-    if (c->registered) {
-        /* the client is registered, just send the
-         * data through the serial port
-         */
-        multiplexer_serial_send(c->multiplexer, c->channel, p);
-        return;
-    }
-
-    if (c->channel > 0) {
-        /* the client is waiting registration results.
-         * this should not happen because the client
-         * should wait for our 'ok' or 'ko'.
-         * close the connection.
-         */
-         D("%s: bad client sending data before end of registration",
-           __FUNCTION__);
-     BAD_CLIENT:
-         packet_free(&p);
-         client_free(c);
-         return;
-    }
-
-    /* the client hasn't registered a service yet,
-     * so this must be the name of a service, call
-     * the multiplexer to start registration for
-     * it.
-     */
-    D("%s: attempting registration for service '%.*s'",
-      __FUNCTION__, p->len, p->data);
-    c->channel = multiplexer_open_channel(c->multiplexer, p);
-    if (c->channel < 0) {
-        D("%s: service name too long", __FUNCTION__);
-        goto BAD_CLIENT;
-    }
-    D("%s:    -> received channel id %d", __FUNCTION__, c->channel);
-    packet_free(&p);
-}
-
-
-/* a function called when the client socket is closed. */
-static void
-client_fd_close( Client*  c )
-{
-    T("%s: client %p (%d)", __FUNCTION__, c, c->fdhandler->fd);
-
-    /* no need to shutdown the FDHandler */
-    c->fdhandler = NULL;
-
-    /* tell the emulator we're out */
-    if (c->channel > 0)
-        multiplexer_close_channel(c->multiplexer, c->channel);
-
-    /* free the client */
-    client_free(c);
-}
-
-/* a function called when the multiplexer received a registration
- * response from the emulator for a given client.
- */
-static void
-client_registration( Client*  c, int  registered )
-{
-    Packet*  p = packet_alloc();
-
-    /* sends registration status to client */
-    if (!registered) {
-        D("%s: registration failed for client %d", __FUNCTION__, c->channel);
-        memcpy( p->data, "KO", 2 );
-        p->len = 2;
-    } else {
-        D("%s: registration succeeded for client %d", __FUNCTION__, c->channel);
-        memcpy( p->data, "OK", 2 );
-        p->len = 2;
-    }
-    client_dump(c, p, __FUNCTION__);
-    fdhandler_enqueue(c->fdhandler, p);
-
-    /* now save registration state
-     */
-    c->registered = registered;
-    if (!registered) {
-        /* allow the client to try registering another service */
-        c->channel = -1;
-    }
-}
-
-/* send data to a client */
-static void
-client_send( Client*  c, Packet*  p )
-{
-    client_dump(c, p, __FUNCTION__);
-    fdhandler_enqueue(c->fdhandler, p);
-}
-
-
-/* Create new client socket handler */
-static Client*
-client_new( Multiplexer*    mult,
-            int             fd,
-            FDHandlerList*  pfdhandlers,
-            Client**        pclients )
-{
-    Client*   c;
-    Receiver  recv;
-
-    xnew(c);
-
-    c->multiplexer = mult;
-    c->next        = NULL;
-    c->pref        = &c->next;
-    c->channel     = -1;
-    c->registered  = 0;
-
-    recv.user  = c;
-    recv.post  = (PostFunc)  client_fd_receive;
-    recv.close = (CloseFunc) client_fd_close;
-
-    c->fdhandler = fdhandler_new( fd, pfdhandlers, &recv );
-
-    /* add to client list */
-    c->next   = *pclients;
-    c->pref   = pclients;
-    *pclients = c;
-    if (c->next)
-        c->next->pref = &c->next;
-
-    return c;
-}
-
-/**  GLOBAL MULTIPLEXER
- **/
-
-/* find a client by its channel */
-static Client*
-multiplexer_find_client( Multiplexer*  mult, int  channel )
-{
-    Client* c = mult->clients;
-
-    for ( ; c != NULL; c = c->next ) {
-        if (c->channel == channel)
-            return c;
-    }
-    return NULL;
-}
-
-/* handle control messages coming from the serial port
- * on CONTROL_CHANNEL.
- */
-static void
-multiplexer_handle_control( Multiplexer*  mult, Packet*  p )
-{
-    /* connection registration success */
-    if (p->len == 13 && !memcmp(p->data, "ok:connect:", 11)) {
-        int      channel = hex2int(p->data+11, 2);
-        Client*  client  = multiplexer_find_client(mult, channel);
-
-        /* note that 'client' can be NULL if the corresponding
-         * socket was closed before the emulator response arrived.
-         */
-        if (client != NULL) {
-            client_registration(client, 1);
-        } else {
-            D("%s: NULL client: '%.*s'", __FUNCTION__, p->len, p->data+11);
-        }
-        goto EXIT;
-    }
-
-    /* connection registration failure */
-    if (p->len == 13 && !memcmp(p->data, "ko:connect:",11)) {
-        int     channel = hex2int(p->data+11, 2);
-        Client* client  = multiplexer_find_client(mult, channel);
-
-        if (client != NULL)
-            client_registration(client, 0);
-
-        goto EXIT;
-    }
-
-    /* emulator-induced client disconnection */
-    if (p->len == 13 && !memcmp(p->data, "disconnect:",11)) {
-        int      channel = hex2int(p->data+11, 2);
-        Client*  client  = multiplexer_find_client(mult, channel);
-
-        if (client != NULL)
-            client_free(client);
-
-        goto EXIT;
-    }
-
-    /* A message that begins with "X00" is a probe sent by
-     * the emulator used to detect which version of qemud it runs
-     * against (in order to detect 1.0/1.1 system images. Just
-     * silently ignore it there instead of printing an error
-     * message.
-     */
-    if (p->len >= 3 && !memcmp(p->data,"X00",3)) {
-        goto EXIT;
-    }
-
-    D("%s: unknown control message (%d bytes): '%.*s'",
-      __FUNCTION__, p->len, p->len, p->data);
-
-EXIT:
-    packet_free(&p);
-}
-
-/* a function called when an incoming packet comes from the serial port */
-static void
-multiplexer_serial_receive( Multiplexer*  mult, Packet*  p )
-{
-    Client*  client;
-
-    T("%s: channel=%d '%.*s'", __FUNCTION__, p->channel, p->len, p->data);
-
-    if (p->channel == CHANNEL_CONTROL) {
-        multiplexer_handle_control(mult, p);
-        return;
-    }
-
-    client = multiplexer_find_client(mult, p->channel);
-    if (client != NULL) {
-        client_send(client, p);
-        return;
-    }
-
-    D("%s: discarding packet for unknown channel %d", __FUNCTION__, p->channel);
-    packet_free(&p);
-}
-
-/* a function called when the serial reader closes */
-static void
-multiplexer_serial_close( Multiplexer*  mult )
-{
-    fatal("unexpected close of serial reader");
-}
-
-/* a function called to send a packet to the serial port */
-static void
-multiplexer_serial_send( Multiplexer*  mult, int  channel, Packet*  p )
-{
-    p->channel = channel;
-    serial_send( mult->serial, p );
-}
-
-
-
-/* a function used by a client to allocate a new channel id and
- * ask the emulator to open it. 'service' must be a packet containing
- * the name of the service in its payload.
- *
- * returns -1 if the service name is too long.
- *
- * notice that client_registration() will be called later when
- * the answer arrives.
- */
-static int
-multiplexer_open_channel( Multiplexer*  mult, Packet*  service )
-{
-    Packet*   p = packet_alloc();
-    int       len, channel;
-
-    /* find a free channel number, assume we don't have many
-     * clients here. */
-    {
-        Client*  c;
-    TRY_AGAIN:
-        channel = (++mult->last_channel) & 0xff;
-
-        for (c = mult->clients; c != NULL; c = c->next)
-            if (c->channel == channel)
-                goto TRY_AGAIN;
-    }
-
-    len = snprintf((char*)p->data, sizeof p->data, "connect:%.*s:%02x", service->len, service->data, channel);
-    if (len >= (int)sizeof(p->data)) {
-        D("%s: weird, service name too long (%d > %d)", __FUNCTION__, len, sizeof(p->data));
-        packet_free(&p);
-        return -1;
-    }
-    p->channel = CHANNEL_CONTROL;
-    p->len     = len;
-
-    serial_send(mult->serial, p);
-    return channel;
-}
-
-/* used to tell the emulator a channel was closed by a client */
-static void
-multiplexer_close_channel( Multiplexer*  mult, int  channel )
-{
-    Packet*  p   = packet_alloc();
-    int      len = snprintf((char*)p->data, sizeof(p->data), "disconnect:%02x", channel);
-
-    if (len > (int)sizeof(p->data)) {
-        /* should not happen */
-        return;
-    }
-
-    p->channel = CHANNEL_CONTROL;
-    p->len     = len;
-
-    serial_send(mult->serial, p);
-}
-
-/* this function is used when a new connection happens on the control
- * socket.
- */
-static void
-multiplexer_control_accept( Multiplexer*  m, Packet*  p )
-{
-    /* the file descriptor for the new socket connection is
-     * in p->channel. See fdhandler_accept_event() */
-    int      fd     = p->channel;
-    Client*  client = client_new( m, fd, m->fdhandlers, &m->clients );
-
-    D("created client %p listening on fd %d", client, fd);
-
-    /* free dummy packet */
-    packet_free(&p);
-}
-
-static void
-multiplexer_control_close( Multiplexer*  m )
-{
-    fatal("unexpected multiplexer control close");
-}
-
-static void
-multiplexer_init( Multiplexer*  m, const char*  serial_dev )
-{
-    int       fd, control_fd;
-    Receiver  recv;
-
-    /* initialize looper and fdhandlers list */
-    looper_init( m->looper );
-    fdhandler_list_init( m->fdhandlers, m->looper );
-
-    /* open the serial port */
-    do {
-        fd = open(serial_dev, O_RDWR);
-    } while (fd < 0 && errno == EINTR);
-
-    if (fd < 0) {
-        fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
-               strerror(errno) );
-    }
-    // disable echo on serial lines
-    if ( !memcmp( serial_dev, "/dev/ttyS", 9 ) ) {
-        struct termios  ios;
-        tcgetattr( fd, &ios );
-        ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
-        tcsetattr( fd, TCSANOW, &ios );
-    }
-
-    /* initialize the serial reader/writer */
-    recv.user  = m;
-    recv.post  = (PostFunc)  multiplexer_serial_receive;
-    recv.close = (CloseFunc) multiplexer_serial_close;
-
-    serial_init( m->serial, fd, m->fdhandlers, &recv );
-
-    /* open the qemud control socket */
-    recv.user  = m;
-    recv.post  = (PostFunc)  multiplexer_control_accept;
-    recv.close = (CloseFunc) multiplexer_control_close;
-
-    fd = android_get_control_socket(CONTROL_SOCKET_NAME);
-    if (fd < 0) {
-        fatal("couldn't get fd for control socket '%s'", CONTROL_SOCKET_NAME);
-    }
-
-    fdhandler_new_accept( fd, m->fdhandlers, &recv );
-
-    /* initialize clients list */
-    m->clients = NULL;
-}
-
-/** MAIN LOOP
- **/
-
-static Multiplexer  _multiplexer[1];
-
-int  main( void )
-{
-    Multiplexer*  m = _multiplexer;
-
-   /* extract the name of our serial device from the kernel
-    * boot options that are stored in /proc/cmdline
-    */
-#define  KERNEL_OPTION  "android.qemud="
-
-    {
-        char          buff[1024];
-        int           fd, len;
-        char*         p;
-        char*         q;
-
-        fd = open( "/proc/cmdline", O_RDONLY );
-        if (fd < 0) {
-            D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
-            strerror(errno));
-            exit(1);
-        }
-
-        len = fd_read( fd, buff, sizeof(buff)-1 );
-        close(fd);
-        if (len < 0) {
-            D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
-            strerror(errno));
-            exit(1);
-        }
-        buff[len] = 0;
-
-        p = strstr( buff, KERNEL_OPTION );
-        if (p == NULL) {
-            D("%s: can't find '%s' in /proc/cmdline",
-            __FUNCTION__, KERNEL_OPTION );
-            exit(1);
-        }
-
-        p += sizeof(KERNEL_OPTION)-1;  /* skip option */
-        q  = p;
-        while ( *q && *q != ' ' && *q != '\t' )
-            q += 1;
-
-        snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );
-
-        multiplexer_init( m, buff );
-    }
-
-    D( "entering main loop");
-    looper_loop( m->looper );
-    D( "unexpected termination !!" );
-    return 0;
-}
diff --git a/emulator/qtools/Android.mk b/emulator/qtools/Android.mk
deleted file mode 100644
index 149390c..0000000
--- a/emulator/qtools/Android.mk
+++ /dev/null
@@ -1,157 +0,0 @@
-# 
-# Copyright 2006 The Android Open Source Project
-#
-# Java method trace dump tool
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-common_includes := external/qemu
-common_cflags := -O0 -g
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := post_trace.cpp trace_reader.cpp decoder.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := post_trace
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := read_trace.cpp trace_reader.cpp decoder.cpp armdis.cpp \
-	thumbdis.cpp opcode.cpp read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := read_trace
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := check_trace.cpp trace_reader.cpp decoder.cpp \
-	opcode.cpp read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := check_trace
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := bb_dump.cpp trace_reader.cpp decoder.cpp \
-	read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := bb_dump
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := bb2sym.cpp trace_reader.cpp decoder.cpp \
-	read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := bb2sym
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := profile_trace.cpp trace_reader.cpp decoder.cpp \
-	opcode.cpp read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := profile_trace
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := bbprof.cpp trace_reader.cpp decoder.cpp armdis.cpp \
-	thumbdis.cpp opcode.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := bbprof
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := q2g.cpp trace_reader.cpp decoder.cpp \
-	opcode.cpp read_elf.cpp parse_options.cpp gtrace.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := q2g
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := q2dm.cpp trace_reader.cpp decoder.cpp armdis.cpp \
-	thumbdis.cpp opcode.cpp read_elf.cpp parse_options.cpp dmtrace.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := q2dm
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := coverage.cpp trace_reader.cpp decoder.cpp armdis.cpp \
-	thumbdis.cpp opcode.cpp read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := coverage
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := stack_dump.cpp trace_reader.cpp decoder.cpp armdis.cpp \
-	thumbdis.cpp opcode.cpp read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := stack_dump
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := check_stack.cpp trace_reader.cpp decoder.cpp armdis.cpp \
-	thumbdis.cpp opcode.cpp read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := check_stack
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := hist_trace.cpp trace_reader.cpp decoder.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := hist_trace
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := read_addr.cpp trace_reader.cpp decoder.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := read_addr
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := read_pid.cpp trace_reader.cpp decoder.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := read_pid
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := exc_dump.cpp trace_reader.cpp decoder.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := exc_dump
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := read_method.cpp trace_reader.cpp decoder.cpp \
-	read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := read_method
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := profile_pid.cpp trace_reader.cpp decoder.cpp \
-	read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := profile_pid
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := dump_regions.cpp trace_reader.cpp decoder.cpp \
-	read_elf.cpp parse_options.cpp
-LOCAL_C_INCLUDES += $(common_includes)
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_MODULE := dump_regions
-include $(BUILD_HOST_EXECUTABLE)
diff --git a/emulator/qtools/armdis.cpp b/emulator/qtools/armdis.cpp
deleted file mode 100644
index 1f35867..0000000
--- a/emulator/qtools/armdis.cpp
+++ /dev/null
@@ -1,905 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <string.h>
-#include "armdis.h"
-#include "opcode.h"
-
-static const char *cond_names[] = {
-    "eq",
-    "ne",
-    "cs",
-    "cc",
-    "mi",
-    "pl",
-    "vs",
-    "vc",
-    "hi",
-    "ls",
-    "ge",
-    "lt",
-    "gt",
-    "le",
-    "",
-    "RESERVED"
-};
-
-// Indexed by the shift type (bits 6-5)
-static const char *shift_names[] = {
-    "LSL",
-    "LSR",
-    "ASR",
-    "ROR"
-};
-
-static const char* cond_to_str(int cond) {
-    return cond_names[cond];
-}
-
-char *Arm::disasm(uint32_t addr, uint32_t insn, char *result)
-{
-    static char   buf[80];
-    char          *ptr;
-
-    ptr = result ? result : buf;
-    Opcode opcode = decode(insn);
-    switch (opcode) {
-        case OP_INVALID:
-            sprintf(ptr, "Invalid");
-            return ptr;
-        case OP_UNDEFINED:
-            sprintf(ptr, "Undefined");
-            return ptr;
-        case OP_ADC:
-        case OP_ADD:
-        case OP_AND:
-        case OP_BIC:
-        case OP_CMN:
-        case OP_CMP:
-        case OP_EOR:
-        case OP_MOV:
-        case OP_MVN:
-        case OP_ORR:
-        case OP_RSB:
-        case OP_RSC:
-        case OP_SBC:
-        case OP_SUB:
-        case OP_TEQ:
-        case OP_TST:
-            return disasm_alu(opcode, insn, ptr);
-        case OP_B:
-        case OP_BL:
-            return disasm_branch(addr, opcode, insn, ptr);
-        case OP_BKPT:
-            return disasm_bkpt(insn, ptr);
-        case OP_BLX:
-            // not supported yet
-            break;
-        case OP_BX:
-            return disasm_bx(insn, ptr);
-        case OP_CDP:
-            sprintf(ptr, "cdp");
-            return ptr;
-        case OP_CLZ:
-            return disasm_clz(insn, ptr);
-        case OP_LDC:
-            sprintf(ptr, "ldc");
-            return ptr;
-        case OP_LDM:
-        case OP_STM:
-            return disasm_memblock(opcode, insn, ptr);
-        case OP_LDR:
-        case OP_LDRB:
-        case OP_LDRBT:
-        case OP_LDRT:
-        case OP_STR:
-        case OP_STRB:
-        case OP_STRBT:
-        case OP_STRT:
-            return disasm_mem(insn, ptr);
-        case OP_LDRH:
-        case OP_LDRSB:
-        case OP_LDRSH:
-        case OP_STRH:
-            return disasm_memhalf(insn, ptr);
-        case OP_MCR:
-        case OP_MRC:
-            return disasm_mcr(opcode, insn, ptr);
-        case OP_MLA:
-            return disasm_mla(opcode, insn, ptr);
-        case OP_MRS:
-            return disasm_mrs(insn, ptr);
-        case OP_MSR:
-            return disasm_msr(insn, ptr);
-        case OP_MUL:
-            return disasm_mul(opcode, insn, ptr);
-        case OP_PLD:
-            return disasm_pld(insn, ptr);
-        case OP_STC:
-            sprintf(ptr, "stc");
-            return ptr;
-        case OP_SWI:
-            return disasm_swi(insn, ptr);
-        case OP_SWP:
-        case OP_SWPB:
-            return disasm_swp(opcode, insn, ptr);
-        case OP_UMLAL:
-        case OP_UMULL:
-        case OP_SMLAL:
-        case OP_SMULL:
-            return disasm_umlal(opcode, insn, ptr);
-        default:
-            sprintf(ptr, "Error");
-            return ptr;
-    }
-    return NULL;
-}
-
-char *Arm::disasm_alu(Opcode opcode, uint32_t insn, char *ptr)
-{
-    static const uint8_t kNoOperand1 = 1;
-    static const uint8_t kNoDest = 2;
-    static const uint8_t kNoSbit = 4;
-
-    char rn_str[20];
-    char rd_str[20];
-    uint8_t flags = 0;
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t is_immed = (insn >> 25) & 0x1;
-    uint8_t bit_s = (insn >> 20) & 1;
-    uint8_t rn = (insn >> 16) & 0xf;
-    uint8_t rd = (insn >> 12) & 0xf;
-    uint8_t immed = insn & 0xff;
-
-    const char *opname = opcode_names[opcode];
-    switch (opcode) {
-        case OP_CMN:
-        case OP_CMP:
-        case OP_TEQ:
-        case OP_TST:
-            flags = kNoDest | kNoSbit;
-            break;
-        case OP_MOV:
-        case OP_MVN:
-            flags = kNoOperand1;
-            break;
-        default:
-            break;
-    }
-
-    // The "mov" instruction ignores the first operand (rn).
-    rn_str[0] = 0;
-    if ((flags & kNoOperand1) == 0) {
-        sprintf(rn_str, "r%d, ", rn);
-    }
-
-    // The following instructions do not write the result register (rd):
-    // tst, teq, cmp, cmn.
-    rd_str[0] = 0;
-    if ((flags & kNoDest) == 0) {
-        sprintf(rd_str, "r%d, ", rd);
-    }
-
-    const char *sbit_str = "";
-    if (bit_s && !(flags & kNoSbit))
-        sbit_str = "s";
-
-    if (is_immed) {
-        sprintf(ptr, "%s%s%s\t%s%s#%u  ; 0x%x",
-                opname, cond_to_str(cond), sbit_str, rd_str, rn_str, immed, immed);
-        return ptr;
-    }
-
-    uint8_t shift_is_reg = (insn >> 4) & 1;
-    uint8_t rotate = (insn >> 8) & 0xf;
-    uint8_t rm = insn & 0xf;
-    uint8_t shift_type = (insn >> 5) & 0x3;
-    uint8_t rs = (insn >> 8) & 0xf;
-    uint8_t shift_amount = (insn >> 7) & 0x1f;
-    uint32_t rotated_val = immed;
-    uint8_t rotate2 = rotate << 1;
-    rotated_val = (rotated_val >> rotate2) | (rotated_val << (32 - rotate2));
-
-    if (!shift_is_reg && shift_type == 0 && shift_amount == 0) {
-        sprintf(ptr, "%s%s%s\t%s%sr%d",
-                opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm);
-        return ptr;
-    }
-
-    const char *shift_name = shift_names[shift_type];
-    if (shift_is_reg) {
-        sprintf(ptr, "%s%s%s\t%s%sr%d, %s r%d",
-                opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm,
-                shift_name, rs);
-        return ptr;
-    }
-    if (shift_amount == 0) {
-        if (shift_type == 3) {
-            sprintf(ptr, "%s%s%s\t%s%sr%d, RRX",
-                    opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm);
-            return ptr;
-        }
-        shift_amount = 32;
-    }
-    sprintf(ptr, "%s%s%s\t%s%sr%d, %s #%u",
-            opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm,
-            shift_name, shift_amount);
-    return ptr;
-}
-
-char *Arm::disasm_branch(uint32_t addr, Opcode opcode, uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint32_t offset = insn & 0xffffff;
-    // Sign-extend the 24-bit offset
-    if ((offset >> 23) & 1)
-        offset |= 0xff000000;
-
-    // Pre-compute the left-shift and the prefetch offset
-    offset <<= 2;
-    offset += 8;
-    addr += offset;
-    const char *opname = opcode_names[opcode];
-    sprintf(ptr, "%s%s\t0x%x", opname, cond_to_str(cond), addr);
-    return ptr;
-}
-
-char *Arm::disasm_bx(uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t rn = insn & 0xf;
-    sprintf(ptr, "bx%s\tr%d", cond_to_str(cond), rn);
-    return ptr;
-}
-
-char *Arm::disasm_bkpt(uint32_t insn, char *ptr)
-{
-    uint32_t immed = (((insn >> 8) & 0xfff) << 4) | (insn & 0xf);
-    sprintf(ptr, "bkpt\t#%d", immed);
-    return ptr;
-}
-
-char *Arm::disasm_clz(uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t rd = (insn >> 12) & 0xf;
-    uint8_t rm = insn & 0xf;
-    sprintf(ptr, "clz%s\tr%d, r%d", cond_to_str(cond), rd, rm);
-    return ptr;
-}
-
-char *Arm::disasm_memblock(Opcode opcode, uint32_t insn, char *ptr)
-{
-    char tmp_reg[10], tmp_list[80];
-
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t write_back = (insn >> 21) & 0x1;
-    uint8_t bit_s = (insn >> 22) & 0x1;
-    uint8_t is_up = (insn >> 23) & 0x1;
-    uint8_t is_pre = (insn >> 24) & 0x1;
-    uint8_t rn = (insn >> 16) & 0xf;
-    uint16_t reg_list = insn & 0xffff;
-
-    const char *opname = opcode_names[opcode];
-
-    const char *bang = "";
-    if (write_back)
-        bang = "!";
-
-    const char *carret = "";
-    if (bit_s)
-        carret = "^";
-
-    const char *comma = "";
-    tmp_list[0] = 0;
-    for (int ii = 0; ii < 16; ++ii) {
-        if (reg_list & (1 << ii)) {
-            sprintf(tmp_reg, "%sr%d", comma, ii);
-            strcat(tmp_list, tmp_reg);
-            comma = ",";
-        }
-    }
-
-    const char *addr_mode = "";
-    if (is_pre) {
-        if (is_up) {
-            addr_mode = "ib";
-        } else {
-            addr_mode = "db";
-        }
-    } else {
-        if (is_up) {
-            addr_mode = "ia";
-        } else {
-            addr_mode = "da";
-        }
-    }
-
-    sprintf(ptr, "%s%s%s\tr%d%s, {%s}%s",
-            opname, cond_to_str(cond), addr_mode, rn, bang, tmp_list, carret);
-    return ptr;
-}
-
-char *Arm::disasm_mem(uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t is_reg = (insn >> 25) & 0x1;
-    uint8_t is_load = (insn >> 20) & 0x1;
-    uint8_t write_back = (insn >> 21) & 0x1;
-    uint8_t is_byte = (insn >> 22) & 0x1;
-    uint8_t is_up = (insn >> 23) & 0x1;
-    uint8_t is_pre = (insn >> 24) & 0x1;
-    uint8_t rn = (insn >> 16) & 0xf;
-    uint8_t rd = (insn >> 12) & 0xf;
-    uint16_t offset = insn & 0xfff;
-
-    const char *opname = "ldr";
-    if (!is_load)
-        opname = "str";
-
-    const char *bang = "";
-    if (write_back)
-        bang = "!";
-
-    const char *minus = "";
-    if (is_up == 0)
-        minus = "-";
-
-    const char *byte = "";
-    if (is_byte)
-        byte = "b";
-
-    if (is_reg == 0) {
-        if (is_pre) {
-            if (offset == 0) {
-                sprintf(ptr, "%s%s%s\tr%d, [r%d]",
-                        opname, cond_to_str(cond), byte, rd, rn);
-            } else {
-                sprintf(ptr, "%s%s%s\tr%d, [r%d, #%s%u]%s",
-                        opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang);
-            }
-        } else {
-            const char *transfer = "";
-            if (write_back)
-                transfer = "t";
-            sprintf(ptr, "%s%s%s%s\tr%d, [r%d], #%s%u",
-                    opname, cond_to_str(cond), byte, transfer, rd, rn, minus, offset);
-        }
-        return ptr;
-    }
-
-    uint8_t rm = insn & 0xf;
-    uint8_t shift_type = (insn >> 5) & 0x3;
-    uint8_t shift_amount = (insn >> 7) & 0x1f;
-
-    const char *shift_name = shift_names[shift_type];
-
-    if (is_pre) {
-        if (shift_amount == 0) {
-            if (shift_type == 0) {
-                sprintf(ptr, "%s%s%s\tr%d, [r%d, %sr%d]%s",
-                        opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang);
-                return ptr;
-            }
-            if (shift_type == 3) {
-                sprintf(ptr, "%s%s%s\tr%d, [r%d, %sr%d, RRX]%s",
-                        opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang);
-                return ptr;
-            }
-            shift_amount = 32;
-        }
-        sprintf(ptr, "%s%s%s\tr%d, [r%d, %sr%d, %s #%u]%s",
-                opname, cond_to_str(cond), byte, rd, rn, minus, rm,
-                shift_name, shift_amount, bang);
-        return ptr;
-    }
-
-    const char *transfer = "";
-    if (write_back)
-        transfer = "t";
-
-    if (shift_amount == 0) {
-        if (shift_type == 0) {
-            sprintf(ptr, "%s%s%s%s\tr%d, [r%d], %sr%d",
-                    opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm);
-            return ptr;
-        }
-        if (shift_type == 3) {
-            sprintf(ptr, "%s%s%s%s\tr%d, [r%d], %sr%d, RRX",
-                    opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm);
-            return ptr;
-        }
-        shift_amount = 32;
-    }
-
-    sprintf(ptr, "%s%s%s%s\tr%d, [r%d], %sr%d, %s #%u",
-            opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm,
-            shift_name, shift_amount);
-    return ptr;
-}
-
-char *Arm::disasm_memhalf(uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t is_load = (insn >> 20) & 0x1;
-    uint8_t write_back = (insn >> 21) & 0x1;
-    uint8_t is_immed = (insn >> 22) & 0x1;
-    uint8_t is_up = (insn >> 23) & 0x1;
-    uint8_t is_pre = (insn >> 24) & 0x1;
-    uint8_t rn = (insn >> 16) & 0xf;
-    uint8_t rd = (insn >> 12) & 0xf;
-    uint8_t bits_65 = (insn >> 5) & 0x3;
-    uint8_t rm = insn & 0xf;
-    uint8_t offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf);
-
-    const char *opname = "ldr";
-    if (is_load == 0)
-        opname = "str";
-
-    const char *width = "";
-    if (bits_65 == 1)
-        width = "h";
-    else if (bits_65 == 2)
-        width = "sb";
-    else
-        width = "sh";
-
-    const char *bang = "";
-    if (write_back)
-        bang = "!";
-    const char *minus = "";
-    if (is_up == 0)
-        minus = "-";
-
-    if (is_immed) {
-        if (is_pre) {
-            if (offset == 0) {
-                sprintf(ptr, "%s%sh\tr%d, [r%d]", opname, cond_to_str(cond), rd, rn);
-            } else {
-                sprintf(ptr, "%s%sh\tr%d, [r%d, #%s%u]%s",
-                        opname, cond_to_str(cond), rd, rn, minus, offset, bang);
-            }
-        } else {
-            sprintf(ptr, "%s%sh\tr%d, [r%d], #%s%u",
-                    opname, cond_to_str(cond), rd, rn, minus, offset);
-        }
-        return ptr;
-    }
-
-    if (is_pre) {
-        sprintf(ptr, "%s%sh\tr%d, [r%d, %sr%d]%s",
-                opname, cond_to_str(cond), rd, rn, minus, rm, bang);
-    } else {
-        sprintf(ptr, "%s%sh\tr%d, [r%d], %sr%d",
-                opname, cond_to_str(cond), rd, rn, minus, rm);
-    }
-    return ptr;
-}
-
-char *Arm::disasm_mcr(Opcode opcode, uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t crn = (insn >> 16) & 0xf;
-    uint8_t crd = (insn >> 12) & 0xf;
-    uint8_t cpnum = (insn >> 8) & 0xf;
-    uint8_t opcode2 = (insn >> 5) & 0x7;
-    uint8_t crm = insn & 0xf;
-
-    const char *opname = opcode_names[opcode];
-    sprintf(ptr, "%s%s\t%d, 0, r%d, cr%d, cr%d, {%d}",
-            opname, cond_to_str(cond), cpnum, crd, crn, crm, opcode2);
-    return ptr;
-}
-
-char *Arm::disasm_mla(Opcode opcode, uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t rd = (insn >> 16) & 0xf;
-    uint8_t rn = (insn >> 12) & 0xf;
-    uint8_t rs = (insn >> 8) & 0xf;
-    uint8_t rm = insn & 0xf;
-    uint8_t bit_s = (insn >> 20) & 1;
-
-    const char *opname = opcode_names[opcode];
-    sprintf(ptr, "%s%s%s\tr%d, r%d, r%d, r%d",
-            opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs, rn);
-    return ptr;
-}
-
-char *Arm::disasm_umlal(Opcode opcode, uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t rdhi = (insn >> 16) & 0xf;
-    uint8_t rdlo = (insn >> 12) & 0xf;
-    uint8_t rs = (insn >> 8) & 0xf;
-    uint8_t rm = insn & 0xf;
-    uint8_t bit_s = (insn >> 20) & 1;
-
-    const char *opname = opcode_names[opcode];
-    sprintf(ptr, "%s%s%s\tr%d, r%d, r%d, r%d",
-            opname, cond_to_str(cond), bit_s ? "s" : "", rdlo, rdhi, rm, rs);
-    return ptr;
-}
-
-char *Arm::disasm_mul(Opcode opcode, uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t rd = (insn >> 16) & 0xf;
-    uint8_t rs = (insn >> 8) & 0xf;
-    uint8_t rm = insn & 0xf;
-    uint8_t bit_s = (insn >> 20) & 1;
-
-    const char *opname = opcode_names[opcode];
-    sprintf(ptr, "%s%s%s\tr%d, r%d, r%d",
-            opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs);
-    return ptr;
-}
-
-char *Arm::disasm_mrs(uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t rd = (insn >> 12) & 0xf;
-    uint8_t ps = (insn >> 22) & 1;
-
-    sprintf(ptr, "mrs%s\tr%d, %s", cond_to_str(cond), rd, ps ? "spsr" : "cpsr");
-    return ptr;
-}
-
-char *Arm::disasm_msr(uint32_t insn, char *ptr)
-{
-    char flags[8];
-    int flag_index = 0;
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t is_immed = (insn >> 25) & 0x1;
-    uint8_t pd = (insn >> 22) & 1;
-    uint8_t mask = (insn >> 16) & 0xf;
-
-    if (mask & 1)
-        flags[flag_index++] = 'c';
-    if (mask & 2)
-        flags[flag_index++] = 'x';
-    if (mask & 4)
-        flags[flag_index++] = 's';
-    if (mask & 8)
-        flags[flag_index++] = 'f';
-    flags[flag_index] = 0;
-
-    if (is_immed) {
-        uint32_t immed = insn & 0xff;
-        uint8_t rotate = (insn >> 8) & 0xf;
-        uint8_t rotate2 = rotate << 1;
-        uint32_t rotated_val = (immed >> rotate2) | (immed << (32 - rotate2));
-        sprintf(ptr, "msr%s\t%s_%s, #0x%x",
-                cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rotated_val);
-        return ptr;
-    }
-
-    uint8_t rm = insn & 0xf;
-
-    sprintf(ptr, "msr%s\t%s_%s, r%d",
-            cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm);
-    return ptr;
-}
-
-char *Arm::disasm_pld(uint32_t insn, char *ptr)
-{
-    uint8_t is_reg = (insn >> 25) & 0x1;
-    uint8_t is_up = (insn >> 23) & 0x1;
-    uint8_t rn = (insn >> 16) & 0xf;
-
-    const char *minus = "";
-    if (is_up == 0)
-        minus = "-";
-
-    if (is_reg) {
-        uint8_t rm = insn & 0xf;
-        sprintf(ptr, "pld\t[r%d, %sr%d]", rn, minus, rm);
-        return ptr;
-    }
-
-    uint16_t offset = insn & 0xfff;
-    if (offset == 0) {
-        sprintf(ptr, "pld\t[r%d]", rn);
-    } else {
-        sprintf(ptr, "pld\t[r%d, #%s%u]", rn, minus, offset);
-    }
-    return ptr;
-}
-
-char *Arm::disasm_swi(uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint32_t sysnum = insn & 0x00ffffff;
-
-    sprintf(ptr, "swi%s 0x%x", cond_to_str(cond), sysnum);
-    return ptr;
-}
-
-char *Arm::disasm_swp(Opcode opcode, uint32_t insn, char *ptr)
-{
-    uint8_t cond = (insn >> 28) & 0xf;
-    uint8_t rn = (insn >> 16) & 0xf;
-    uint8_t rd = (insn >> 12) & 0xf;
-    uint8_t rm = insn & 0xf;
-
-    const char *opname = opcode_names[opcode];
-    sprintf(ptr, "%s%s\tr%d, r%d, [r%d]", opname, cond_to_str(cond), rd, rm, rn);
-    return ptr;
-}
-
-Opcode Arm::decode(uint32_t insn) {
-    uint32_t bits27_26 = (insn >> 26) & 0x3;
-    switch (bits27_26) {
-        case 0x0:
-            return decode00(insn);
-        case 0x1:
-            return decode01(insn);
-        case 0x2:
-            return decode10(insn);
-        case 0x3:
-            return decode11(insn);
-    }
-    return OP_INVALID;
-}
-
-Opcode Arm::decode00(uint32_t insn) {
-    uint8_t bit25 = (insn >> 25) & 0x1;
-    uint8_t bit4 = (insn >> 4) & 0x1;
-    if (bit25 == 0 && bit4 == 1) {
-        if ((insn & 0x0ffffff0) == 0x012fff10) {
-            // Bx instruction
-            return OP_BX;
-        }
-        if ((insn & 0x0ff000f0) == 0x01600010) {
-            // Clz instruction
-            return OP_CLZ;
-        }
-        if ((insn & 0xfff000f0) == 0xe1200070) {
-            // Bkpt instruction
-            return OP_BKPT;
-        }
-        uint32_t bits7_4 = (insn >> 4) & 0xf;
-        if (bits7_4 == 0x9) {
-            if ((insn & 0x0ff00ff0) == 0x01000090) {
-                // Swp instruction
-                uint8_t bit22 = (insn >> 22) & 0x1;
-                if (bit22)
-                    return OP_SWPB;
-                return OP_SWP;
-            }
-            // One of the multiply instructions
-            return decode_mul(insn);
-        }
-
-        uint8_t bit7 = (insn >> 7) & 0x1;
-        if (bit7 == 1) {
-            // One of the load/store halfword/byte instructions
-            return decode_ldrh(insn);
-        }
-    }
-
-    // One of the data processing instructions
-    return decode_alu(insn);
-}
-
-Opcode Arm::decode01(uint32_t insn) {
-    uint8_t is_reg = (insn >> 25) & 0x1;
-    uint8_t bit4 = (insn >> 4) & 0x1;
-    if (is_reg == 1 && bit4 == 1)
-        return OP_UNDEFINED;
-    uint8_t is_load = (insn >> 20) & 0x1;
-    uint8_t is_byte = (insn >> 22) & 0x1;
-    if ((insn & 0xfd70f000) == 0xf550f000) {
-        // Pre-load
-        return OP_PLD;
-    }
-    if (is_load) {
-        if (is_byte) {
-            // Load byte
-            return OP_LDRB;
-        }
-        // Load word
-        return OP_LDR;
-    }
-    if (is_byte) {
-        // Store byte
-        return OP_STRB;
-    }
-    // Store word
-    return OP_STR;
-}
-
-Opcode Arm::decode10(uint32_t insn) {
-    uint8_t bit25 = (insn >> 25) & 0x1;
-    if (bit25 == 0) {
-        // LDM/STM
-        uint8_t is_load = (insn >> 20) & 0x1;
-        if (is_load)
-            return OP_LDM;
-        return OP_STM;
-    }
-    // Branch or Branch with link
-    uint8_t is_link = (insn >> 24) & 1;
-    uint32_t offset = insn & 0xffffff;
-
-    // Sign-extend the 24-bit offset
-    if ((offset >> 23) & 1)
-        offset |= 0xff000000;
-
-    // Pre-compute the left-shift and the prefetch offset
-    offset <<= 2;
-    offset += 8;
-    if (is_link == 0)
-        return OP_B;
-    return OP_BL;
-}
-
-Opcode Arm::decode11(uint32_t insn) {
-    uint8_t bit25 = (insn >> 25) & 0x1;
-    if (bit25 == 0) {
-        // LDC, SDC
-        uint8_t is_load = (insn >> 20) & 0x1;
-        if (is_load) {
-            // LDC
-            return OP_LDC;
-        }
-        // STC
-        return OP_STC;
-    }
-
-    uint8_t bit24 = (insn >> 24) & 0x1;
-    if (bit24 == 0x1) {
-        // SWI
-        return OP_SWI;
-    }
-  
-    uint8_t bit4 = (insn >> 4) & 0x1;
-    uint8_t cpnum = (insn >> 8) & 0xf;
-
-    if (cpnum == 15) {
-        // Special case for coprocessor 15
-        uint8_t opcode = (insn >> 21) & 0x7;
-        if (bit4 == 0 || opcode != 0) {
-            // This is an unexpected bit pattern.  Create an undefined
-            // instruction in case this is ever executed.
-            return OP_UNDEFINED;
-        }
-
-        // MRC, MCR
-        uint8_t is_mrc = (insn >> 20) & 0x1;
-        if (is_mrc)
-            return OP_MRC;
-        return OP_MCR;
-    }
-
-    if (bit4 == 0) {
-        // CDP
-        return OP_CDP;
-    }
-    // MRC, MCR
-    uint8_t is_mrc = (insn >> 20) & 0x1;
-    if (is_mrc)
-        return OP_MRC;
-    return OP_MCR;
-}
-
-Opcode Arm::decode_mul(uint32_t insn) {
-    uint8_t bit24 = (insn >> 24) & 0x1;
-    if (bit24 != 0) {
-        // This is an unexpected bit pattern.  Create an undefined
-        // instruction in case this is ever executed.
-        return OP_UNDEFINED;
-    }
-    uint8_t bit23 = (insn >> 23) & 0x1;
-    uint8_t bit22_U = (insn >> 22) & 0x1;
-    uint8_t bit21_A = (insn >> 21) & 0x1;
-    if (bit23 == 0) {
-        // 32-bit multiply
-        if (bit22_U != 0) {
-            // This is an unexpected bit pattern.  Create an undefined
-            // instruction in case this is ever executed.
-            return OP_UNDEFINED;
-        }
-        if (bit21_A == 0)
-            return OP_MUL;
-        return OP_MLA;
-    }
-    // 64-bit multiply
-    if (bit22_U == 0) {
-        // Unsigned multiply long
-        if (bit21_A == 0)
-            return OP_UMULL;
-        return OP_UMLAL;
-    }
-    // Signed multiply long
-    if (bit21_A == 0)
-        return OP_SMULL;
-    return OP_SMLAL;
-}
-
-Opcode Arm::decode_ldrh(uint32_t insn) {
-    uint8_t is_load = (insn >> 20) & 0x1;
-    uint8_t bits_65 = (insn >> 5) & 0x3;
-    if (is_load) {
-        if (bits_65 == 0x1) {
-            // Load unsigned halfword
-            return OP_LDRH;
-        } else if (bits_65 == 0x2) {
-            // Load signed byte
-            return OP_LDRSB;
-        }
-        // Signed halfword
-        if (bits_65 != 0x3) {
-            // This is an unexpected bit pattern.  Create an undefined
-            // instruction in case this is ever executed.
-            return OP_UNDEFINED;
-        }
-        // Load signed halfword
-        return OP_LDRSH;
-    }
-    // Store halfword
-    if (bits_65 != 0x1) {
-        // This is an unexpected bit pattern.  Create an undefined
-        // instruction in case this is ever executed.
-        return OP_UNDEFINED;
-    }
-    // Store halfword
-    return OP_STRH;
-}
-
-Opcode Arm::decode_alu(uint32_t insn) {
-    uint8_t is_immed = (insn >> 25) & 0x1;
-    uint8_t opcode = (insn >> 21) & 0xf;
-    uint8_t bit_s = (insn >> 20) & 1;
-    uint8_t shift_is_reg = (insn >> 4) & 1;
-    uint8_t bit7 = (insn >> 7) & 1;
-    if (!is_immed && shift_is_reg && (bit7 != 0)) {
-        // This is an unexpected bit pattern.  Create an undefined
-        // instruction in case this is ever executed.
-        return OP_UNDEFINED;
-    }
-    switch (opcode) {
-        case 0x0:
-            return OP_AND;
-        case 0x1:
-            return OP_EOR;
-        case 0x2:
-            return OP_SUB;
-        case 0x3:
-            return OP_RSB;
-        case 0x4:
-            return OP_ADD;
-        case 0x5:
-            return OP_ADC;
-        case 0x6:
-            return OP_SBC;
-        case 0x7:
-            return OP_RSC;
-        case 0x8:
-            if (bit_s)
-                return OP_TST;
-            return OP_MRS;
-        case 0x9:
-            if (bit_s)
-                return OP_TEQ;
-            return OP_MSR;
-        case 0xa:
-            if (bit_s)
-                return OP_CMP;
-            return OP_MRS;
-        case 0xb:
-            if (bit_s)
-                return OP_CMN;
-            return OP_MSR;
-        case 0xc:
-            return OP_ORR;
-        case 0xd:
-            return OP_MOV;
-        case 0xe:
-            return OP_BIC;
-        case 0xf:
-            return OP_MVN;
-    }
-    // Unreachable
-    return OP_INVALID;
-}
diff --git a/emulator/qtools/armdis.h b/emulator/qtools/armdis.h
deleted file mode 100644
index 230f833..0000000
--- a/emulator/qtools/armdis.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef ARMDIS_H
-#define ARMDIS_H
-
-#include <inttypes.h>
-#include "opcode.h"
-
-class Arm {
- public:
-  static char *disasm(uint32_t addr, uint32_t insn, char *buffer);
-  static Opcode decode(uint32_t insn);
-
- private:
-  static Opcode decode00(uint32_t insn);
-  static Opcode decode01(uint32_t insn);
-  static Opcode decode10(uint32_t insn);
-  static Opcode decode11(uint32_t insn);
-  static Opcode decode_mul(uint32_t insn);
-  static Opcode decode_ldrh(uint32_t insn);
-  static Opcode decode_alu(uint32_t insn);
-
-  static char *disasm_alu(Opcode opcode, uint32_t insn, char *ptr);
-  static char *disasm_branch(uint32_t addr, Opcode opcode, uint32_t insn, char *ptr);
-  static char *disasm_bx(uint32_t insn, char *ptr);
-  static char *disasm_bkpt(uint32_t insn, char *ptr);
-  static char *disasm_clz(uint32_t insn, char *ptr);
-  static char *disasm_memblock(Opcode opcode, uint32_t insn, char *ptr);
-  static char *disasm_mem(uint32_t insn, char *ptr);
-  static char *disasm_memhalf(uint32_t insn, char *ptr);
-  static char *disasm_mcr(Opcode opcode, uint32_t insn, char *ptr);
-  static char *disasm_mla(Opcode opcode, uint32_t insn, char *ptr);
-  static char *disasm_umlal(Opcode opcode, uint32_t insn, char *ptr);
-  static char *disasm_mul(Opcode opcode, uint32_t insn, char *ptr);
-  static char *disasm_mrs(uint32_t insn, char *ptr);
-  static char *disasm_msr(uint32_t insn, char *ptr);
-  static char *disasm_pld(uint32_t insn, char *ptr);
-  static char *disasm_swi(uint32_t insn, char *ptr);
-  static char *disasm_swp(Opcode opcode, uint32_t insn, char *ptr);
-};
-
-extern char *disasm_insn_thumb(uint32_t pc, uint32_t insn1, uint32_t insn2, char *result);
-extern Opcode decode_insn_thumb(uint32_t given);
-
-#endif /* ARMDIS_H */
diff --git a/emulator/qtools/bb2sym.cpp b/emulator/qtools/bb2sym.cpp
deleted file mode 100644
index 8a18b67..0000000
--- a/emulator/qtools/bb2sym.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "parse_options.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-struct MyStaticRec {
-    StaticRec   bb;
-    symbol_type *sym;
-    MyStaticRec *inner;    // pointer to an inner basic block
-    int         is_thumb;
-};
-
-MyStaticRec **assign_inner_blocks(int num_blocks, MyStaticRec *blocks);
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_file elf_file\n", program);
-    OptionsUsage();
-}
-
-// This function is called from quicksort to compare addresses of basic
-// blocks.
-int cmp_inc_addr(const void *a, const void *b) {
-    MyStaticRec *bb1, *bb2;
-
-    bb1 = *(MyStaticRec**)a;
-    bb2 = *(MyStaticRec**)b;
-    if (bb1->bb.bb_addr < bb2->bb.bb_addr)
-        return -1;
-    if (bb1->bb.bb_addr > bb2->bb.bb_addr)
-        return 1;
-    return bb1->bb.bb_num - bb2->bb.bb_num;
-}
-
-int main(int argc, char **argv) {
-    uint32_t insns[kMaxInsnPerBB];
-
-    // Parse the options
-    ParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReader<> *trace = new TraceReader<>;
-    trace->Open(trace_filename);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    TraceHeader *header = trace->GetHeader();
-    uint32_t num_static_bb = header->num_static_bb;
-
-    // Allocate space for all of the static blocks
-    MyStaticRec *blocks = new MyStaticRec[num_static_bb];
-
-    // Read in all the static blocks
-    for (uint32_t ii = 0; ii < num_static_bb; ++ii) {
-        trace->ReadStatic(&blocks[ii].bb);
-        blocks[ii].is_thumb = blocks[ii].bb.bb_addr & 1;
-        blocks[ii].bb.bb_addr &= ~1;
-        blocks[ii].sym = NULL;
-        blocks[ii].inner = NULL;
-        trace->ReadStaticInsns(blocks[ii].bb.num_insns, insns);
-    }
-
-    MyStaticRec **sorted = assign_inner_blocks(num_static_bb, blocks);
-
-    while (1) {
-        symbol_type *sym;
-        BBEvent event;
-        BBEvent ignored;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &sym))
-            break;
-
-        uint64_t bb_num = event.bb_num;
-        blocks[bb_num].sym = sym;
-    }
-        
-    printf("#     bb num_insns     bb_addr file  symbol\n");
-    for (uint32_t ii = 0; ii < num_static_bb; ++ii) {
-        if (sorted[ii]->bb.bb_addr == 0 || sorted[ii]->bb.num_insns == 0
-            || sorted[ii]->sym == NULL)
-            continue;
-
-        printf("%8lld       %3d  0x%08x %s %s\n",
-               sorted[ii]->bb.bb_num, sorted[ii]->bb.num_insns,
-               sorted[ii]->bb.bb_addr, sorted[ii]->sym->region->path,
-               sorted[ii]->sym->name);
-    }
-    return 0;
-}
-
-// Find the basic blocks that are subsets of other basic blocks.
-MyStaticRec **assign_inner_blocks(int num_blocks, MyStaticRec *blocks)
-{
-    int ii;
-    uint32_t addr_end, addr_diff;
-
-    // Create a list of pointers to the basic blocks that we can sort.
-    MyStaticRec **sorted = new MyStaticRec*[num_blocks];
-    for (ii = 0; ii < num_blocks; ++ii) {
-        sorted[ii] = &blocks[ii];
-    }
-
-    // Sort the basic blocks into increasing address order
-    qsort(sorted, num_blocks, sizeof(MyStaticRec*), cmp_inc_addr);
-
-    // Create pointers to inner blocks and break up the enclosing block
-    // so that there is no overlap.
-    for (ii = 0; ii < num_blocks - 1; ++ii) {
-        int num_bytes;
-        if (sorted[ii]->is_thumb)
-            num_bytes = sorted[ii]->bb.num_insns << 1;
-        else
-            num_bytes = sorted[ii]->bb.num_insns << 2;
-        addr_end = sorted[ii]->bb.bb_addr + num_bytes;
-        if (addr_end > sorted[ii + 1]->bb.bb_addr) {
-            sorted[ii]->inner = sorted[ii + 1];
-            addr_diff = sorted[ii + 1]->bb.bb_addr - sorted[ii]->bb.bb_addr;
-            uint32_t num_insns;
-            if (sorted[ii]->is_thumb)
-                num_insns = addr_diff >> 1;
-            else
-                num_insns = addr_diff >> 2;
-            sorted[ii]->bb.num_insns = num_insns;
-        }
-    }
-
-    return sorted;
-}
diff --git a/emulator/qtools/bb_dump.cpp b/emulator/qtools/bb_dump.cpp
deleted file mode 100644
index de241fb..0000000
--- a/emulator/qtools/bb_dump.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "parse_options.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_file elf_file\n", program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv) {
-    // Parse the options
-    ParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReader<> *trace = new TraceReader<>;
-    trace->Open(trace_filename);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    printf("#  time   bb   pid num_insns  bb_addr\n");
-    while (1) {
-        symbol_type *sym;
-        BBEvent event;
-        BBEvent ignored;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &sym))
-            break;
-        printf("%7lld %4lld %5d       %3d  0x%08x %s\n",
-               event.time, event.bb_num, event.pid, event.num_insns,
-               event.bb_addr, sym->name);
-    }
-    return 0;
-}
diff --git a/emulator/qtools/bbprof.cpp b/emulator/qtools/bbprof.cpp
deleted file mode 100644
index 36d0941..0000000
--- a/emulator/qtools/bbprof.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-#include "armdis.h"
-
-struct MyStaticRec {
-    StaticRec   bb;
-    uint32_t    *insns;
-    uint32_t    *cycles;    // number of cycles for each insn
-    uint32_t    elapsed;    // number of cycles for basic block
-    int         freq;       // execution frequency
-    MyStaticRec *inner;     // pointer to an inner basic block
-    int         is_thumb;
-};
-
-MyStaticRec **assign_inner_blocks(int num_blocks, MyStaticRec *blocks);
-
-// This function is called from quicksort to compare addresses of basic
-// blocks.
-int cmp_inc_addr(const void *a, const void *b) {
-    MyStaticRec *bb1, *bb2;
-
-    bb1 = *(MyStaticRec**)a;
-    bb2 = *(MyStaticRec**)b;
-    if (bb1->bb.bb_addr < bb2->bb.bb_addr)
-        return -1;
-    if (bb1->bb.bb_addr > bb2->bb.bb_addr)
-        return 1;
-    return bb1->bb.bb_num - bb2->bb.bb_num;
-}
-
-// This function is called from quicksort to compare the elapsed time
-// of basic blocks.
-int cmp_dec_elapsed(const void *a, const void *b) {
-    MyStaticRec *bb1, *bb2;
-
-    bb1 = *(MyStaticRec**)a;
-    bb2 = *(MyStaticRec**)b;
-    if (bb1->elapsed < bb2->elapsed)
-        return 1;
-    if (bb1->elapsed > bb2->elapsed)
-        return -1;
-    return bb1->bb.bb_num - bb2->bb.bb_num;
-}
-
-// This function is called from quicksort to compare frequencies of
-// basic blocks.
-int cmp_dec_freq(const void *a, const void *b) {
-    MyStaticRec *bb1, *bb2;
-
-    bb1 = *(MyStaticRec**)a;
-    bb2 = *(MyStaticRec**)b;
-    if (bb1->freq < bb2->freq)
-        return 1;
-    if (bb1->freq > bb2->freq)
-        return -1;
-    return bb1->bb.bb_num - bb2->bb.bb_num;
-}
-
-int main(int argc, char **argv)
-{
-    if (argc != 2) {
-        fprintf(stderr, "Usage: %s trace_file\n", argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[1];
-    TraceReaderBase *trace = new TraceReaderBase;
-    trace->Open(trace_filename);
-    TraceHeader *header = trace->GetHeader();
-    uint32_t num_static_bb = header->num_static_bb;
-
-    // Allocate space for all of the static blocks
-    MyStaticRec *blocks = new MyStaticRec[num_static_bb];
-
-    // Read in all the static blocks
-    for (uint32_t ii = 0; ii < num_static_bb; ++ii) {
-        trace->ReadStatic(&blocks[ii].bb);
-        blocks[ii].is_thumb = blocks[ii].bb.bb_addr & 1;
-        blocks[ii].bb.bb_addr &= ~1;
-        uint32_t num_insns = blocks[ii].bb.num_insns;
-        blocks[ii].insns = new uint32_t[num_insns];
-        blocks[ii].cycles = new uint32_t[num_insns];
-        memset(blocks[ii].cycles, 0, num_insns * sizeof(uint32_t));
-        trace->ReadStaticInsns(num_insns, blocks[ii].insns);
-        blocks[ii].elapsed = 0;
-        blocks[ii].freq = 0;
-        blocks[ii].inner = NULL;
-    }
-
-    MyStaticRec **sorted = assign_inner_blocks(num_static_bb, blocks);
-
-    uint32_t prev_time = 0;
-    uint32_t elapsed = 0;
-    uint32_t dummy;
-    uint32_t *cycle_ptr = &dummy;
-    uint32_t *bb_elapsed_ptr = &dummy;
-    while (1) {
-        BBEvent event;
-
-        if (trace->ReadBB(&event))
-            break;
-        // Assign frequencies to each basic block
-        uint64_t bb_num = event.bb_num;
-        int num_insns = event.num_insns;
-        blocks[bb_num].freq += 1;
-        for (MyStaticRec *bptr = blocks[bb_num].inner; bptr; bptr = bptr->inner)
-            bptr->freq += 1;
-
-        // Assign simulation time to each instruction
-        for (MyStaticRec *bptr = &blocks[bb_num]; bptr; bptr = bptr->inner) {
-            uint32_t bb_num_insns = bptr->bb.num_insns;
-            for (uint32_t ii = 0; num_insns && ii < bb_num_insns; ++ii, --num_insns) {
-                uint32_t sim_time = trace->ReadInsnTime(event.time);
-                elapsed = sim_time - prev_time;
-                prev_time = sim_time;
-
-                // Attribute the elapsed time to the previous instruction and
-                // basic block.
-                *cycle_ptr += elapsed;
-                *bb_elapsed_ptr += elapsed;
-                cycle_ptr = &bptr->cycles[ii];
-                bb_elapsed_ptr = &bptr->elapsed;
-            }
-        }
-    }
-    *cycle_ptr += 1;
-    *bb_elapsed_ptr += 1;
-
-    // Sort the basic blocks into decreasing elapsed time
-    qsort(sorted, num_static_bb, sizeof(MyStaticRec*), cmp_dec_elapsed);
-
-    char spaces[80];
-    memset(spaces, ' ', 79);
-    spaces[79] = 0;
-    for (uint32_t ii = 0; ii < num_static_bb; ++ii) {
-        printf("bb %lld addr: 0x%x, insns: %d freq: %u elapsed: %u\n",
-               sorted[ii]->bb.bb_num, sorted[ii]->bb.bb_addr,
-               sorted[ii]->bb.num_insns, sorted[ii]->freq,
-               sorted[ii]->elapsed);
-        int num_insns = sorted[ii]->bb.num_insns;
-        uint32_t addr = sorted[ii]->bb.bb_addr;
-        for (int jj = 0; jj < num_insns; ++jj) {
-            uint32_t elapsed = sorted[ii]->cycles[jj];
-            uint32_t insn = sorted[ii]->insns[jj];
-            if (insn_is_thumb(insn)) {
-                insn = insn_unwrap_thumb(insn);
-
-                // thumb_pair is true if this is the first of a pair of
-                // thumb instructions (BL or BLX).
-                bool thumb_pair = ((insn & 0xf800) == 0xf000);
-
-                // Get the next thumb instruction (if any) because we may need
-                // it for the case where insn is BL or BLX.
-                uint32_t insn2 = 0;
-                if (thumb_pair && (jj + 1 < num_insns)) {
-                    insn2 = sorted[ii]->insns[jj + 1];
-                    insn2 = insn_unwrap_thumb(insn2);
-                    jj += 1;
-                }
-                char *disasm = disasm_insn_thumb(addr, insn, insn2, NULL);
-                if (thumb_pair) {
-                    printf("  %4u %08x %04x %04x %s\n", elapsed, addr, insn,
-                           insn2, disasm);
-                    addr += 2;
-                } else {
-                    printf("  %4u %08x     %04x %s\n", elapsed, addr, insn,
-                           disasm);
-                }
-                addr += 2;
-            } else {
-                char *disasm = Arm::disasm(addr, insn, NULL);
-                printf("  %4u %08x %08x %s\n", elapsed, addr, insn, disasm);
-                addr += 4;
-            }
-        }
-    }
-
-    delete[] sorted;
-    return 0;
-}
-
-// Find the basic blocks that are subsets of other basic blocks.
-MyStaticRec **assign_inner_blocks(int num_blocks, MyStaticRec *blocks)
-{
-    int ii;
-    uint32_t addr_end, addr_diff;
-
-    // Create a list of pointers to the basic blocks that we can sort.
-    MyStaticRec **sorted = new MyStaticRec*[num_blocks];
-    for (ii = 0; ii < num_blocks; ++ii) {
-        sorted[ii] = &blocks[ii];
-    }
-
-    // Sort the basic blocks into increasing address order
-    qsort(sorted, num_blocks, sizeof(MyStaticRec*), cmp_inc_addr);
-
-    // Create pointers to inner blocks and break up the enclosing block
-    // so that there is no overlap.
-    for (ii = 0; ii < num_blocks - 1; ++ii) {
-        int num_bytes;
-        if (sorted[ii]->is_thumb)
-            num_bytes = sorted[ii]->bb.num_insns << 1;
-        else
-            num_bytes = sorted[ii]->bb.num_insns << 2;
-        addr_end = sorted[ii]->bb.bb_addr + num_bytes;
-        if (addr_end > sorted[ii + 1]->bb.bb_addr) {
-            sorted[ii]->inner = sorted[ii + 1];
-            addr_diff = sorted[ii + 1]->bb.bb_addr - sorted[ii]->bb.bb_addr;
-            uint32_t num_insns;
-            if (sorted[ii]->is_thumb)
-                num_insns = addr_diff >> 1;
-            else
-                num_insns = addr_diff >> 2;
-            sorted[ii]->bb.num_insns = num_insns;
-        }
-    }
-
-    return sorted;
-}
diff --git a/emulator/qtools/bitvector.h b/emulator/qtools/bitvector.h
deleted file mode 100644
index d3f5cf1..0000000
--- a/emulator/qtools/bitvector.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef BITVECTOR_H
-#define BITVECTOR_H
-
-#include <inttypes.h>
-#include <assert.h>
-
-class Bitvector {
- public:
-  explicit Bitvector(int num_bits) {
-    num_bits_ = num_bits;
-
-    // Round up to a multiple of 32
-    num_bits = (num_bits + 31) & ~31;
-    vector_ = new uint32_t[num_bits >> 5];
-  }
-  ~Bitvector() {
-    delete[] vector_;
-  }
-
-  void        SetBit(int bitnum) {
-    assert(bitnum < num_bits_);
-    vector_[bitnum >> 5] |= 1 << (bitnum & 31);
-  }
-  void        ClearBit(int bitnum) {
-    assert(bitnum < num_bits_);
-    vector_[bitnum >> 5] &= ~(1 << (bitnum & 31));
-  }
-  bool        GetBit(int bitnum) {
-    assert(bitnum < num_bits_);
-    return (vector_[bitnum >> 5] >> (bitnum & 31)) & 1;
-  }
-
- private:
-  int         num_bits_;
-  uint32_t    *vector_;
-};
-
-#endif  // BITVECTOR_H
diff --git a/emulator/qtools/callstack.h b/emulator/qtools/callstack.h
deleted file mode 100644
index 8982330..0000000
--- a/emulator/qtools/callstack.h
+++ /dev/null
@@ -1,775 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef CALL_STACK_H
-#define CALL_STACK_H
-
-#include "opcode.h"
-#include "armdis.h"
-
-class CallStackBase {
-  public:
-    int    getId()          { return mId; }
-    void   setId(int id)    { mId = id; }
-
-  private:
-    int    mId;
-};
-
-// Define a template class for the stack frame.  The template parameter
-// SYM is the symbol_type from the TraceReader<> template class. To
-// use the CallStack class, the user derives a subclass of StackFrame
-// and defines push() and pop() methods.  This derived class is then
-// passed as a template parameter to CallStack.
-template <class SYM>
-class StackFrame {
-  public:
-
-    virtual ~StackFrame() {};
-
-    virtual void push(int stackLevel, uint64_t time, CallStackBase *base) {};
-    virtual void pop(int stackLevel, uint64_t time, CallStackBase *base) {};
-
-    typedef SYM symbol_type;
-    static const uint32_t kCausedException = 0x01;
-    static const uint32_t kInterpreted     = 0x02;
-    static const uint32_t kStartNative     = 0x04;
-    static const uint32_t kPopBarrier      = (kCausedException | kInterpreted
-        | kStartNative);
-
-    symbol_type *function;      // the symbol for the function we entered
-    uint32_t    addr;           // return address when this function returns
-    uint32_t    flags;
-    uint32_t    time;           // for debugging when a problem occurred
-    uint32_t    global_time;    // for debugging when a problem occurred
-};
-
-template <class FRAME, class BASE = CallStackBase>
-class CallStack : public BASE {
-public:
-    typedef FRAME frame_type;
-    typedef typename FRAME::symbol_type symbol_type;
-    typedef typename FRAME::symbol_type::region_type region_type;
-    typedef BASE base_type;
-
-    CallStack(int id, int numFrames, TraceReaderType *trace);
-    ~CallStack();
-
-    void    updateStack(BBEvent *event, symbol_type *function);
-    void    popAll(uint64_t time);
-    void    threadStart(uint64_t time);
-    void    threadStop(uint64_t time);
-
-    // Set to true if you don't want to see any Java methods ever
-    void    setNativeOnly(bool nativeOnly) {
-        mNativeOnly = nativeOnly;
-    }
-
-    int         getStackLevel() { return mTop; }
-
-    uint64_t    getGlobalTime(uint64_t time) { return time + mSkippedTime; }
-    void        showStack(FILE *stream);
-
-    int         mNumFrames;
-    FRAME       *mFrames;
-    int         mTop;           // index of the next stack frame to write
-
-private:
-    enum Action { NONE, PUSH, POP, NATIVE_PUSH };
-
-    Action      getAction(BBEvent *event, symbol_type *function);
-    void        doMethodAction(BBEvent *event, symbol_type *function);
-    void        doMethodPop(BBEvent *event, uint32_t addr, const uint32_t flags);
-    void        doSimplePush(symbol_type *function, uint32_t addr,
-                             uint64_t time, int flags);
-    void        doSimplePop(uint64_t time);
-    void        doPush(BBEvent *event, symbol_type *function);
-    void        doPop(BBEvent *event, symbol_type *function, Action methodAction);
-
-    TraceReaderType *mTrace;
-
-    // This is a global switch that disables Java methods from appearing
-    // on the stack.
-    bool        mNativeOnly;
-  
-    // This keeps track of whether native frames are currently allowed on the
-    // stack.
-    bool        mAllowNativeFrames;
-
-    symbol_type mDummyFunction;
-    region_type mDummyRegion;
-
-    symbol_type *mPrevFunction;
-    BBEvent     mPrevEvent;
-
-    symbol_type *mUserFunction;
-    BBEvent     mUserEvent;     // the previous user-mode event
-
-    uint64_t    mSkippedTime;
-    uint64_t    mLastRunTime;
-
-    static MethodRec    sCurrentMethod;
-    static MethodRec    sNextMethod;
-};
-
-template<class FRAME, class BASE>
-MethodRec CallStack<FRAME, BASE>::sCurrentMethod;
-template<class FRAME, class BASE>
-MethodRec CallStack<FRAME, BASE>::sNextMethod;
-
-template<class FRAME, class BASE>
-CallStack<FRAME, BASE>::CallStack(int id, int numFrames, TraceReaderType *trace)
-{
-    mNativeOnly = false;
-    mTrace = trace;
-    BASE::setId(id);
-    mNumFrames = numFrames;
-    mFrames = new FRAME[mNumFrames];
-    mTop = 0;
-    mAllowNativeFrames = true;
-
-    memset(&mDummyFunction, 0, sizeof(symbol_type));
-    memset(&mDummyRegion, 0, sizeof(region_type));
-    mDummyFunction.region = &mDummyRegion;
-    mPrevFunction = &mDummyFunction;
-    memset(&mPrevEvent, 0, sizeof(BBEvent));
-    mUserFunction = &mDummyFunction;
-    memset(&mUserEvent, 0, sizeof(BBEvent));
-    mSkippedTime = 0;
-    mLastRunTime = 0;
-
-    // Read the first two methods from the trace if we haven't already read
-    // from the method trace yet.
-    if (sCurrentMethod.time == 0) {
-        if (mTrace->ReadMethod(&sCurrentMethod)) {
-            sCurrentMethod.time = ~0ull;
-            sNextMethod.time = ~0ull;
-        }
-        if (sNextMethod.time != ~0ull && mTrace->ReadMethod(&sNextMethod)) {
-            sNextMethod.time = ~0ull;
-        }
-    }
-}
-
-template<class FRAME, class BASE>
-CallStack<FRAME, BASE>::~CallStack()
-{
-    delete mFrames;
-}
-
-template<class FRAME, class BASE>
-void
-CallStack<FRAME, BASE>::updateStack(BBEvent *event, symbol_type *function)
-{
-    if (mNativeOnly) {
-        // If this is an interpreted function, then use the native VM function
-        // instead.
-        if (function->vm_sym != NULL)
-            function = function->vm_sym;
-    } else {
-        doMethodAction(event, function);
-    }
-
-    Action action = getAction(event, function);
-
-    // Allow native frames if we are executing in the kernel.
-    if (!mAllowNativeFrames
-        && (function->region->flags & region_type::kIsKernelRegion) == 0) {
-        action = NONE;
-    }
-
-    if (function->vm_sym != NULL) {
-        function = function->vm_sym;
-        function->vm_sym = NULL;
-    }
-    if (action == PUSH) {
-        doPush(event, function);
-    } else if (action == POP) {
-        doPop(event, function, NONE);
-    }
-
-#if 0
-    // Pop off native functions before pushing or popping Java methods.
-    if (action == POP && mPrevFunction->vm_sym == NULL) {
-        // Pop off the previous function first.
-        doPop(event, function, NONE);
-        if (methodAction == POP) {
-            doPop(event, function, POP);
-        } else if (methodAction == PUSH) {
-            doPush(event, function);
-        }
-    } else {
-        if (methodAction != NONE) {
-            // If the method trace has a push or pop, then do it.
-            action = methodAction;
-        } else if (function->vm_sym != NULL) {
-            // This function is a Java method.  Don't push or pop the
-            // Java method without a corresponding method trace record.
-            action = NONE;
-        }
-        if (action == POP) {
-            doPop(event, function, methodAction);
-        } else if (action == PUSH) {
-            doPush(event, function);
-        }
-    }
-#endif
-
-    // If the stack is now empty, then push the current function.
-    if (mTop == 0) {
-        uint64_t time = event->time - mSkippedTime;
-        int flags = 0;
-        if (function->vm_sym != NULL) {
-            flags = FRAME::kInterpreted;
-        }
-        doSimplePush(function, 0, time, 0);
-    }
-
-    mPrevFunction = function;
-    mPrevEvent = *event;
-}
-
-template<class FRAME, class BASE>
-void
-CallStack<FRAME, BASE>::threadStart(uint64_t time)
-{
-    mSkippedTime += time - mLastRunTime;
-}
-
-template<class FRAME, class BASE>
-void
-CallStack<FRAME, BASE>::threadStop(uint64_t time)
-{
-    mLastRunTime = time;
-}
-
-template<class FRAME, class BASE>
-typename CallStack<FRAME, BASE>::Action
-CallStack<FRAME, BASE>::getAction(BBEvent *event, symbol_type *function)
-{
-    Action action;
-    uint32_t offset;
-
-    // Compute the offset from the start of the function to this basic
-    // block address.
-    offset = event->bb_addr - function->addr - function->region->base_addr;
-
-    // Get the previously executed instruction
-    Opcode op = OP_INVALID;
-    int numInsns = mPrevEvent.num_insns;
-    uint32_t insn = 0;
-    if (numInsns > 0) {
-        insn = mPrevEvent.insns[numInsns - 1];
-        if (mPrevEvent.is_thumb) {
-            insn = insn_unwrap_thumb(insn);
-            op = decode_insn_thumb(insn);
-        } else {
-            op = Arm::decode(insn);
-        }
-    }
-
-    // The number of bytes in the previous basic block depends on
-    // whether the basic block was ARM or THUMB instructions.
-    int numBytes;
-    if (mPrevEvent.is_thumb) {
-        numBytes = numInsns << 1;
-    } else {
-        numBytes = numInsns << 2;
-    }
-
-    // If this basic block follows the previous one, then return NONE.
-    // If we don't do this, then we may be fooled into thinking this
-    // is a POP if the previous block ended with a conditional
-    // (non-executed) ldmia instruction.  We do this check before
-    // checking if we are in a different function because we otherwise
-    // we might be fooled into thinking this is a PUSH to a new function
-    // when it is really just a fall-thru into a local kernel symbol
-    // that just looks like a new function.
-    uint32_t prev_end_addr = mPrevEvent.bb_addr + numBytes;
-    if (prev_end_addr == event->bb_addr) {
-        return NONE;
-    }
-
-    // If this basic block is in the same function as the last basic block,
-    // then just return NONE (but see the exceptions below).
-    // Exception 1: if the function calls itself (offset == 0) then we
-    // want to push this function.
-    // Exception 2: if the function returns to itself, then we want
-    // to pop this function.  We detect this case by checking if the last
-    // instruction in the previous basic block was a load-multiple (ldm)
-    // and included r15 as one of the loaded registers.
-    if (function == mPrevFunction) {
-        if (numInsns > 0) {
-            // If this is the beginning of the function and the previous
-            // instruction was not a branch, then it's a PUSH.
-            if (offset == 0 && op != OP_B && op != OP_THUMB_B)
-                return PUSH;
-
-            // If the previous instruction was an ldm that loaded r15,
-            // then it's a POP.
-            if (offset != 0 && ((op == OP_LDM && (insn & 0x8000))
-                                || (op == OP_THUMB_POP && (insn & 0x100)))) {
-                return POP;
-            }
-        }
-
-        return NONE;
-    }
-
-    // We have to figure out if this new function is a call or a
-    // return.  We don't necessarily have a complete call stack (since
-    // we could have started tracing at any point), so we have to use
-    // heuristics.  If the address we are jumping to is the beginning
-    // of a function, or if the instruction that took us there was
-    // either "bl" or "blx" then this is a PUSH.  Also, if the
-    // function offset is non-zero and the previous instruction is a
-    // branch instruction, we will call it a PUSH.  This happens in
-    // the kernel a lot when there is a branch to an offset from a
-    // label. A couple more special cases:
-    //
-    //   - entering a .plt section ("procedure linkage table") is a PUSH,
-    //   - an exception that jumps into the kernel vector entry point
-    //     is also a push.
-    // 
-    // If the function offset is non-zero and the previous instruction
-    // is a bx or some non-branch instruction, then it's a POP.
-    //
-    // There's another special case that comes up.  The user code
-    // might execute an instruction that returns but before the pc
-    // starts executing in the caller, a kernel interrupt occurs.
-    // But it may be hard to tell if this is a return until after
-    // the kernel interrupt code is done and returns to user space.
-    // So we save the last user basic block and look at it when
-    // we come back into user space.
-
-    const uint32_t kIsKernelRegion = region_type::kIsKernelRegion;
-
-    if (((mPrevFunction->region->flags & kIsKernelRegion) == 0)
-        && (function->region->flags & kIsKernelRegion)) {
-        // We just switched into the kernel.  Save the previous
-        // user-mode basic block and function.
-        mUserEvent = mPrevEvent;
-        mUserFunction = mPrevFunction;
-    } else if ((mPrevFunction->region->flags & kIsKernelRegion)
-               && ((function->region->flags & kIsKernelRegion) == 0)) {
-        // We just switched from kernel to user mode.
-        return POP;
-    }
-
-    action = PUSH;
-    if (offset != 0 && mPrevFunction != &mDummyFunction) {
-        // We are jumping into the middle of a function, so this is
-        // probably a return, not a function call.  But look at the
-        // previous instruction first to see if it was a branch-and-link.
-
-        // If the previous instruction was not a branch (and not a
-        // branch-and-link) then POP; or if it is a "bx" instruction
-        // then POP because that is used to return from functions.
-        if (!isBranch(op) || op == OP_BX || op == OP_THUMB_BX) {
-            action = POP;
-        } else if (isBranch(op) && !isBranchLink(op)) {
-            // If the previous instruction was a normal branch to a
-            // local symbol then don't count it as a push or a pop.
-            action = NONE;
-        }
-
-        if (function->flags & symbol_type::kIsVectorTable)
-            action = PUSH;
-    }
-    return action;
-}
-
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
-{
-    uint64_t time = event->time - mSkippedTime;
-
-    // Check for stack overflow
-    if (mTop >= mNumFrames) {
-        // Don't show the stack by default because this generates a lot
-        // of output and this is seen by users if there is an error when
-        // post-processing the trace. But this is useful for debugging.
-#if 0
-        showStack(stderr);
-#endif
-        fprintf(stderr, "Error: stack overflow (%d frames)\n", mTop);
-        exit(1);
-    }
-
-    // Compute the return address here because we may need to change
-    // it if we are popping off a frame for a vector table.
-    int numBytes;
-    if (mPrevEvent.is_thumb) {
-        numBytes = mPrevEvent.num_insns << 1;
-    } else {
-        numBytes = mPrevEvent.num_insns << 2;
-    }
-    uint32_t retAddr = mPrevEvent.bb_addr + numBytes;
-
-    // If this is a Java method then set the return address to zero.
-    // We won't be using it for popping the method and it may lead
-    // to false matches when searching the stack.
-    if (function->vm_sym != NULL) {
-        retAddr = 0;
-    }
-
-#if 0
-    // For debugging only.  Show the stack before entering the kernel
-    // exception-handling code.
-    if (function->flags & symbol_type::kIsVectorStart) {
-        printf("stack before entering exception\n");
-        showStack(stderr);
-    }
-#endif
-
-    // If the top of stack is a vector table, then pop it
-    // off before pushing on the new function.  Also, change the
-    // return address for the new function to the return address
-    // from the vector table.
-    if (mTop > 0
-        && (mFrames[mTop - 1].function->flags & symbol_type::kIsVectorTable)) {
-        retAddr = mFrames[mTop - 1].addr;
-        doSimplePop(time);
-    }
-
-    const uint32_t kIsKernelRegion = region_type::kIsKernelRegion;
-
-    // The following code handles the case where one function, F1,
-    // calls another function, F2, but the before F2 can start
-    // executing, it takes a page fault (on the first instruction
-    // in F2).  The kernel is entered, handles the page fault, and
-    // then returns to the called function.  The problem is that
-    // this looks like a new function call to F2 from the kernel.
-    // The following code cleans up the stack by popping the
-    // kernel frames back to F1 (but not including F1).  The
-    // return address for F2 also has to be fixed up to point to
-    // F1 instead of the kernel.
-    //
-    // We detect this case by checking if the previous basic block
-    // was in the kernel and the current basic block is not.
-    if ((mPrevFunction->region->flags & kIsKernelRegion)
-        && ((function->region->flags & kIsKernelRegion) == 0)
-        && mTop > 0) {
-        // We are switching from kernel mode to user mode.
-#if 0
-        // For debugging.
-        printf("  doPush(): popping to user mode, bb_addr: 0x%08x\n",
-               event->bb_addr);
-        showStack(stderr);
-#endif
-        do {
-            // Pop off the kernel frames until we reach the one that
-            // caused the exception.
-            doSimplePop(time);
-
-            // If the next stack frame is the one that caused an
-            // exception then stop popping frames.
-            if (mTop > 0
-                && (mFrames[mTop - 1].flags & FRAME::kCausedException)) {
-                mFrames[mTop - 1].flags &= ~FRAME::kCausedException;
-                retAddr = mFrames[mTop].addr;
-                break;
-            }
-        } while (mTop > 0);
-#if 0
-        // For debugging
-        printf("  doPush() popping to level %d, using retAddr 0x%08x\n",
-               mTop, retAddr);
-#endif
-    }
-
-    // If we are starting an exception handler, then mark the previous
-    // stack frame so that we know where to return when the exception
-    // handler finishes.
-    if ((function->flags & symbol_type::kIsVectorStart) && mTop > 0)
-        mFrames[mTop - 1].flags |= FRAME::kCausedException;
-
-    // If the function being pushed is a Java method, then mark it on
-    // the stack so that we don't pop it off until we get a matching
-    // trace record from the method trace file.
-    int flags = 0;
-    if (function->vm_sym != NULL) {
-        flags = FRAME::kInterpreted;
-    }
-    doSimplePush(function, retAddr, time, flags);
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::doSimplePush(symbol_type *function, uint32_t addr,
-                                          uint64_t time, int flags)
-{
-    // Check for stack overflow
-    if (mTop >= mNumFrames) {
-        showStack(stderr);
-        fprintf(stderr, "too many stack frames (%d)\n", mTop);
-        exit(1);
-    }
-
-    mFrames[mTop].addr = addr;
-    mFrames[mTop].function = function;
-    mFrames[mTop].flags = flags;
-    mFrames[mTop].time = time;
-    mFrames[mTop].global_time = time + mSkippedTime;
-
-    mFrames[mTop].push(mTop, time, this);
-    mTop += 1;
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::doSimplePop(uint64_t time)
-{
-    if (mTop <= 0) {
-        return;
-    }
-
-    mTop -= 1;
-    mFrames[mTop].pop(mTop, time, this);
-
-    if (mNativeOnly)
-        return;
-
-    // If the stack is empty, then allow more native frames.
-    // Otherwise, if we are transitioning from Java to native, then allow
-    // more native frames.
-    // Otherwise, if we are transitioning from native to Java, then disallow
-    // more native frames.
-    if (mTop == 0) {
-        mAllowNativeFrames = true;
-    } else {
-        bool newerIsJava = (mFrames[mTop].flags & FRAME::kInterpreted) != 0;
-        bool olderIsJava = (mFrames[mTop - 1].flags & FRAME::kInterpreted) != 0;
-        if (newerIsJava && !olderIsJava) {
-            // We are transitioning from Java to native
-            mAllowNativeFrames = true;
-        } else if (!newerIsJava && olderIsJava) {
-            // We are transitioning from native to Java
-            mAllowNativeFrames = false;
-        }
-    }
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::doPop(BBEvent *event, symbol_type *function,
-                                   Action methodAction)
-{
-    uint64_t time = event->time - mSkippedTime;
-
-    // Search backward on the stack for a matching return address.
-    // The most common case is that we pop one stack frame, but
-    // sometimes we pop more than one.
-    int stackLevel;
-    bool allowMethodPop = (methodAction == POP);
-    for (stackLevel = mTop - 1; stackLevel >= 0; --stackLevel) {
-        if (event->bb_addr == mFrames[stackLevel].addr) {
-            // We found a matching return address on the stack.
-            break;
-        }
-
-        // If this stack frame caused an exception, then do not pop
-        // this stack frame.
-        if (mFrames[stackLevel].flags & FRAME::kPopBarrier) {
-            // If this is a Java method, then allow a pop only if we
-            // have a matching trace record.
-            if (mFrames[stackLevel].flags & FRAME::kInterpreted) {
-                if (allowMethodPop) {
-                    // Allow at most one method pop
-                    allowMethodPop = false;
-                    continue;
-                }
-            }
-            stackLevel += 1;
-            break;
-        }
-    }
-
-    // If we didn't find a matching return address then search the stack
-    // again for a matching function.
-    if (stackLevel < 0 || event->bb_addr != mFrames[stackLevel].addr) {
-        bool allowMethodPop = (methodAction == POP);
-        for (stackLevel = mTop - 1; stackLevel >= 0; --stackLevel) {
-            // Compare the function with the one in the stack frame.
-            if (function == mFrames[stackLevel].function) {
-                // We found a matching function.  We want to pop up to but not
-                // including this frame.  But allow popping this frame if this
-                // method called itself and we have a method pop.
-                if (allowMethodPop && function == mPrevFunction) {
-                    // pop this frame
-                    break;
-                }
-                // do not pop this frame
-                stackLevel += 1;
-                break;
-            }
-
-            // If this stack frame caused an exception, then do not pop
-            // this stack frame.
-            if (mFrames[stackLevel].flags & FRAME::kPopBarrier) {
-                // If this is a Java method, then allow a pop only if we
-                // have a matching trace record.
-                if (mFrames[stackLevel].flags & FRAME::kInterpreted) {
-                    if (allowMethodPop) {
-                        // Allow at most one method pop
-                        allowMethodPop = false;
-                        continue;
-                    }
-                }
-                stackLevel += 1;
-                break;
-            }
-        }
-        if (stackLevel < 0)
-            stackLevel = 0;
-    }
-
-    // Note that if we didn't find a matching stack frame, we will pop
-    // the whole stack (unless there is a Java method or exception
-    // frame on the stack).  This is intentional because we may have
-    // started the trace in the middle of an executing program that is
-    // returning up the stack and we do not know the whole stack.  So
-    // the right thing to do is to empty the stack.
-
-    // If we are emptying the stack, then add the current function
-    // on top.  If the current function is the same as the top of
-    // stack, then avoid an extraneous pop and push.
-    if (stackLevel == 0 && mFrames[0].function == function)
-        stackLevel = 1;
-
-#if 0
-    // If we are popping off a large number of stack frames, then
-    // we might have a bug.
-    if (mTop - stackLevel > 7) {
-        printf("popping thru level %d\n", stackLevel);
-        showStack(stderr);
-    }
-#endif
-
-    // Pop the stack frames
-    for (int ii = mTop - 1; ii >= stackLevel; --ii)
-        doSimplePop(time);
-
-    // Clear the "caused exception" bit on the current stack frame
-    if (mTop > 0) {
-        mFrames[mTop - 1].flags &= ~FRAME::kCausedException;
-    }
-
-    // Also handle the case where F1 calls F2 and F2 returns to
-    // F1, but before we can execute any instructions in F1, we
-    // switch to the kernel.  Then when we return from the kernel
-    // we want to pop off F2 from the stack instead of pushing F1
-    // on top of F2.  To handle this case, we saved the last
-    // user-mode basic block when we entered the kernel (in
-    // the getAction() function) and now we can check to see if
-    // that was a return to F1 instead of a call.  We use the
-    // getAction() function to determine this.
-    const uint32_t kIsKernelRegion = region_type::kIsKernelRegion;
-    if ((mPrevFunction->region->flags & kIsKernelRegion)
-        && ((function->region->flags & kIsKernelRegion) == 0)) {
-        mPrevEvent = mUserEvent;
-        mPrevFunction = mUserFunction;
-        if (getAction(event, function) == POP) {
-            // We may need to pop more than one frame, so just
-            // call doPop() again.  This won't be an infinite loop
-            // here because we changed mPrevEvent to the last
-            // user-mode event.
-            doPop(event, function, methodAction);
-            return;
-        }
-    }
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::popAll(uint64_t time)
-{
-    time -= mSkippedTime;
-    while (mTop != 0) {
-        doSimplePop(time);
-    }
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::doMethodPop(BBEvent *event, uint32_t addr,
-                                         const uint32_t flags)
-{
-    uint64_t time = event->time - mSkippedTime;
-
-    // Search the stack from the top down for a frame that contains a
-    // matching method.
-    int stackLevel;
-    for (stackLevel = mTop - 1; stackLevel >= 0; --stackLevel) {
-        if (mFrames[stackLevel].flags & flags) {
-            // If we are searching for a native method, then don't bother trying
-            // to match the address.
-            if (flags == FRAME::kStartNative)
-                break;
-            symbol_type *func = mFrames[stackLevel].function;
-            uint32_t methodAddr = func->region->base_addr + func->addr;
-            if (methodAddr == addr) {
-                break;
-            }
-        }
-    }
-
-    // If we found a matching frame then pop the stack up to and including
-    // that frame.
-    if (stackLevel >= 0) {
-        // Pop the stack frames
-        for (int ii = mTop - 1; ii >= stackLevel; --ii)
-            doSimplePop(time);
-    }
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::doMethodAction(BBEvent *event, symbol_type *function)
-{
-    // If the events get ahead of the method trace, then read ahead until we
-    // sync up again.  This can happen if there is a pop of a method in the
-    // method trace for which we don't have a previous push.  Such an unmatched
-    // pop can happen because the user can start tracing at any time and so
-    // there might already be a stack when we start tracing.
-    while (event->time >= sNextMethod.time) {
-        sCurrentMethod = sNextMethod;
-        if (mTrace->ReadMethod(&sNextMethod)) {
-            sNextMethod.time = ~0ull;
-        }
-    }
-
-    if (event->time >= sCurrentMethod.time && event->pid == sCurrentMethod.pid) {
-        uint64_t time = event->time - mSkippedTime;
-        int flags = sCurrentMethod.flags;
-        if (flags == kMethodEnter) {
-            doSimplePush(function, 0, time, FRAME::kInterpreted);
-            mAllowNativeFrames = false;
-        } else if (flags == kNativeEnter) {
-            doSimplePush(function, 0, time, FRAME::kStartNative);
-            mAllowNativeFrames = true;
-        } else if (flags == kMethodExit || flags == kMethodException) {
-            doMethodPop(event, sCurrentMethod.addr, FRAME::kInterpreted);
-        } else if (flags == kNativeExit || flags == kNativeException) {
-            doMethodPop(event, sCurrentMethod.addr, FRAME::kStartNative);
-        }
-
-        // We found a match, so read the next record. When we get to the end
-        // of the trace, we set the time to the maximum value (~0).
-        sCurrentMethod = sNextMethod;
-        if (sNextMethod.time != ~0ull && mTrace->ReadMethod(&sNextMethod)) {
-            sNextMethod.time = ~0ull;
-        }
-    }
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::showStack(FILE *stream)
-{
-    fprintf(stream, "mTop: %d skippedTime: %llu\n", mTop, mSkippedTime);
-    for (int ii = 0; ii < mTop; ++ii) {
-        uint32_t addr = mFrames[ii].function->addr;
-        addr += mFrames[ii].function->region->vstart;
-        fprintf(stream, "  %d: t %d gt %d f %x 0x%08x 0x%08x %s\n",
-                ii, mFrames[ii].time, mFrames[ii].global_time,
-                mFrames[ii].flags,
-                mFrames[ii].addr, addr,
-                mFrames[ii].function->name);
-    }
-}
-
-#endif /* CALL_STACK_H */
diff --git a/emulator/qtools/check_stack.cpp b/emulator/qtools/check_stack.cpp
deleted file mode 100644
index b4d14d3..0000000
--- a/emulator/qtools/check_stack.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2009 The Android Open Source Project
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "bitvector.h"
-#include "parse_options.h"
-#include "armdis.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-#include "callstack.h"
-
-typedef CallStack<StackFrame<symbol_type> > CallStackType;
-
-void compareStacks(uint64_t time, int pid);
-void dumpStacks(int pid);
-
-static uint64_t debugTime;
-static const int kNumStackFrames = 500;
-static const int kMaxThreads = (32 * 1024);
-CallStackType *eStacks[kMaxThreads];
-
-int numErrors;
-static const int kMaxErrors = 3;
-
-struct frame {
-    uint64_t    time;
-    uint32_t    addr;
-    const char  *name;
-    bool        isNative;
-
-    frame(uint64_t time, uint32_t addr, const char *name, bool isNative) {
-        this->time = time;
-        this->addr = addr;
-        this->name = name;
-        this->isNative = isNative;
-    }
-};
-
-class Stack {
-public:
-    static const int kMaxFrames = 1000;
-    int top;
-    frame *frames[kMaxFrames];
-
-    Stack() {
-        top = 0;
-    }
-
-    void        push(frame *pframe);
-    frame*      pop();
-    void        dump();
-};
-
-void Stack::push(frame *pframe) {
-    if (top == kMaxFrames) {
-        fprintf(stderr, "Error: stack overflow\n");
-        exit(1);
-    }
-    frames[top] = pframe;
-    top += 1;
-}
-
-frame *Stack::pop() {
-    if (top <= 0)
-        return NULL;
-    top -= 1;
-    return frames[top];
-}
-
-Stack *mStacks[kMaxThreads];
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
-            program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv)
-{
-    ParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *qemu_trace_file = argv[optind++];
-    char *elf_file = argv[optind++];
-
-    TraceReaderType *etrace = new TraceReaderType;
-    etrace->Open(qemu_trace_file);
-    etrace->ReadKernelSymbols(elf_file);
-    etrace->SetRoot(root);
-
-    TraceReaderType *mtrace = new TraceReaderType;
-    mtrace->Open(qemu_trace_file);
-    mtrace->ReadKernelSymbols(elf_file);
-    mtrace->SetRoot(root);
-
-    BBEvent event;
-    while (1) {
-        BBEvent ignored;
-        symbol_type *function;
-        MethodRec method_record;
-        symbol_type *sym;
-        TraceReaderType::ProcessState *proc;
-        frame *pframe;
-
-        if (mtrace->ReadMethodSymbol(&method_record, &sym, &proc))
-            break;
-
-        if (!IsValidPid(proc->pid))
-            continue;
-
-        // Get the stack for the current thread
-        Stack *mStack = mStacks[proc->pid];
-
-        // If the stack does not exist, then allocate a new one.
-        if (mStack == NULL) {
-            mStack = new Stack();
-            mStacks[proc->pid] = mStack;
-        }
-
-        int flags = method_record.flags;
-        if (flags == kMethodEnter || flags == kNativeEnter) {
-            pframe = new frame(method_record.time, method_record.addr,
-                               sym == NULL ? NULL: sym->name,
-                               method_record.flags == kNativeEnter);
-            mStack->push(pframe);
-        } else {
-            pframe = mStack->pop();
-            delete pframe;
-        }
-
-        do {
-            if (GetNextValidEvent(etrace, &event, &ignored, &function))
-                break;
-            if (event.bb_num == 0)
-                break;
-
-            // Get the stack for the current thread
-            CallStackType *eStack = eStacks[event.pid];
-
-            // If the stack does not exist, then allocate a new one.
-            if (eStack == NULL) {
-                eStack = new CallStackType(event.pid, kNumStackFrames, etrace);
-                eStacks[event.pid] = eStack;
-            }
-            if (debugTime != 0 && event.time >= debugTime)
-                printf("time: %llu debug time: %lld\n", event.time, debugTime);
-
-            // Update the stack
-            eStack->updateStack(&event, function);
-        } while (event.time < method_record.time);
-
-        compareStacks(event.time, event.pid);
-    }
-
-    for (int ii = 0; ii < kMaxThreads; ++ii) {
-        if (eStacks[ii])
-            eStacks[ii]->popAll(event.time);
-    }
-
-    delete etrace;
-    delete mtrace;
-    return 0;
-}
-
-void compareStacks(uint64_t time, int pid) {
-    CallStackType *eStack = eStacks[pid];
-    Stack *mStack = mStacks[pid];
-    frame **mFrames = mStack->frames;
-    frame *mframe;
-
-    int mTop = mStack->top;
-    int eTop = eStack->mTop;
-    CallStackType::frame_type *eFrames = eStack->mFrames;
-
-    // Count the number of non-native methods (ie, Java methods) on the
-    // Java method stack
-    int numNonNativeMethods = 0;
-    for (int ii = 0; ii < mTop; ++ii) {
-        if (!mFrames[ii]->isNative) {
-            numNonNativeMethods += 1;
-        }
-    }
-
-    // Count the number of Java methods on the native stack
-    int numMethods = 0;
-    for (int ii = 0; ii < eTop; ++ii) {
-        if (eFrames[ii].flags & CallStackType::frame_type::kInterpreted) {
-            numMethods += 1;
-        }
-    }
-
-    // Verify that the number of Java methods on both stacks are the same.
-    // Allow the native stack to have one less Java method because the
-    // native stack might be pushing a native function first.
-    if (numNonNativeMethods != numMethods && numNonNativeMethods != numMethods + 1) {
-        printf("\nDiff at time %llu pid %d: non-native %d numMethods %d\n",
-               time, pid, numNonNativeMethods, numMethods);
-        dumpStacks(pid);
-        numErrors += 1;
-        if (numErrors >= kMaxErrors)
-            exit(1);
-    }
-
-    // Verify that the Java methods on the method stack are the same
-    // as the Java methods on the native stack.
-    int mIndex = 0;
-    for (int ii = 0; ii < eTop; ++ii) {
-        // Ignore native functions on the native stack.
-        if ((eFrames[ii].flags & CallStackType::frame_type::kInterpreted) == 0)
-            continue;
-        uint32_t addr = eFrames[ii].function->addr;
-        addr += eFrames[ii].function->region->vstart;
-        while (mIndex < mTop && mFrames[mIndex]->isNative) {
-            mIndex += 1;
-        }
-        if (mIndex >= mTop)
-            break;
-        if (addr != mFrames[mIndex]->addr) {
-            printf("\nDiff at time %llu pid %d: frame %d\n", time, pid, ii);
-            dumpStacks(pid);
-            exit(1);
-        }
-        mIndex += 1;
-    }
-}
-
-void dumpStacks(int pid) {
-    CallStackType *eStack = eStacks[pid];
-    Stack *mStack = mStacks[pid];
-    frame *mframe;
-
-    int mTop = mStack->top;
-    printf("\nJava method stack\n");
-    for (int ii = 0; ii < mTop; ii++) {
-        mframe = mStack->frames[ii];
-        const char *native = mframe->isNative ? "n" : " ";
-        printf("  %s %d: %llu 0x%x %s\n",
-               native, ii, mframe->time, mframe->addr,
-               mframe->name == NULL ? "" : mframe->name);
-    }
-
-    int eTop = eStack->mTop;
-    CallStackType::frame_type *eFrames = eStack->mFrames;
-    int mIndex = 0;
-    printf("\nNative stack\n");
-    for (int ii = 0; ii < eTop; ++ii) {
-        uint32_t addr = eFrames[ii].function->addr;
-        addr += eFrames[ii].function->region->vstart;
-        const char *marker = " ";
-        if (eFrames[ii].flags & CallStackType::frame_type::kInterpreted) {
-            if (mIndex >= mTop || addr != mStack->frames[mIndex]->addr) {
-                marker = "*";
-            }
-            mIndex += 1;
-        }
-        printf(" %s %d: %d f %d 0x%08x %s\n",
-               marker, ii, eFrames[ii].time, eFrames[ii].flags, addr,
-               eFrames[ii].function->name);
-    }
-}
diff --git a/emulator/qtools/check_trace.cpp b/emulator/qtools/check_trace.cpp
deleted file mode 100644
index d933a87..0000000
--- a/emulator/qtools/check_trace.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "armdis.h"
-#include "parse_options.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-static const uint32_t kOffsetThreshold = 0x100000;
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_file elf_file\n", program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv) {
-    // Parse the options
-    ParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReader<> *trace = new TraceReader<>;
-    trace->Open(trace_filename);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    while (1) {
-        symbol_type *sym;
-        BBEvent event;
-        BBEvent ignored;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &sym))
-            break;
-        if (event.bb_num == 0)
-            break;
-        //printf("t%llu bb %lld %d\n", event.time, event.bb_num, event.num_insns);
-        uint64_t insn_time = trace->ReadInsnTime(event.time);
-        if (insn_time != event.time) {
-            printf("time: %llu insn time: %llu bb: %llu addr: 0x%x num_insns: %d, pid: %d\n",
-                   event.time, insn_time, event.bb_num, event.bb_addr,
-                   event.num_insns, event.pid);
-            exit(1);
-        }
-        for (int ii = 1; ii < event.num_insns; ++ii) {
-            trace->ReadInsnTime(event.time);
-        }
-    }
-
-    delete trace;
-    return 0;
-}
diff --git a/emulator/qtools/coverage.cpp b/emulator/qtools/coverage.cpp
deleted file mode 100644
index 790f721..0000000
--- a/emulator/qtools/coverage.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-#include "parse_options.h"
-#include "opcode.h"
-
-const int kMillion = 1000000;
-const int kMHz = 200 * kMillion;
-
-struct symbol {
-    int    numCalls;    // number of times this function is called
-};
-
-typedef TraceReader<symbol> TraceReaderType;
-
-#include "parse_options-inl.h"
-#include "callstack.h"
-
-class MyFrame : public StackFrame<symbol_type> {
-  public:
-    void    push(int stackLevel, uint64_t time, CallStackBase *base) {
-        function->numCalls += 1;
-    }
-    void    pop(int stackLevel, uint64_t time, CallStackBase *base) {
-    }
-};
-
-typedef CallStack<MyFrame> CallStackType;
-
-static const int kNumStackFrames = 500;
-static const int kMaxThreads = (32 * 1024);
-CallStackType *stacks[kMaxThreads];
-
-// This comparison function is called from qsort() to sort symbols
-// into decreasing number of calls.
-int cmp_sym_calls(const void *a, const void *b) {
-    const symbol_type *syma, *symb;
-    uint64_t calls1, calls2;
-
-    syma = static_cast<symbol_type const *>(a);
-    symb = static_cast<symbol_type const *>(b);
-    calls1 = syma->numCalls;
-    calls2 = symb->numCalls;
-    if (calls1 < calls2)
-        return 1;
-    if (calls1 == calls2) {
-        int cmp = strcmp(syma->name, symb->name);
-        if (cmp == 0)
-            cmp = strcmp(syma->region->path, symb->region->path);
-        return cmp;
-    }
-    return -1;
-}
-
-// This comparison function is called from qsort() to sort symbols
-// into alphabetical order.
-int cmp_sym_names(const void *a, const void *b) {
-    const symbol_type *syma, *symb;
-
-    syma = static_cast<symbol_type const *>(a);
-    symb = static_cast<symbol_type const *>(b);
-    int cmp = strcmp(syma->region->path, symb->region->path);
-    if (cmp == 0)
-        cmp = strcmp(syma->name, symb->name);
-    return cmp;
-}
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_file elf_file\n", program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv)
-{
-    ParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReader<symbol> *trace = new TraceReader<symbol>;
-    trace->Open(trace_filename);
-    trace->SetDemangle(demangle);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    BBEvent event;
-    while (1) {
-        BBEvent ignored;
-        symbol_type *function;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &function))
-            break;
-        if (event.bb_num == 0)
-            break;
-
-        // Get the stack for the current thread
-        CallStackType *pStack = stacks[event.pid];
-
-        // If the stack does not exist, then allocate a new one.
-        if (pStack == NULL) {
-            pStack = new CallStackType(event.pid, kNumStackFrames, trace);
-            stacks[event.pid] = pStack;
-        }
-
-        // Update the stack
-        pStack->updateStack(&event, function);
-    }
-
-    for (int ii = 0; ii < kMaxThreads; ++ii) {
-        if (stacks[ii])
-            stacks[ii]->popAll(event.time);
-    }
-
-    int nsyms;
-    symbol_type *syms = trace->GetSymbols(&nsyms);
-
-    // Sort the symbols into decreasing number of calls
-    qsort(syms, nsyms, sizeof(symbol_type), cmp_sym_names);
-
-    symbol_type *psym = syms;
-    for (int ii = 0; ii < nsyms; ++ii, ++psym) {
-        // Ignore functions with non-zero calls
-        if (psym->numCalls)
-            continue;
-
-        // Ignore some symbols
-        if (strcmp(psym->name, "(end)") == 0)
-            continue;
-        if (strcmp(psym->name, "(unknown)") == 0)
-            continue;
-        if (strcmp(psym->name, ".plt") == 0)
-            continue;
-        const char *ksym = " ";
-        if (psym->region->flags & region_type::kIsKernelRegion)
-            ksym = "k";
-        printf("%s %s %s\n", ksym, psym->name, psym->region->path);
-#if 0
-        printf("#%d %5d %s %s %s\n", ii + 1, psym->numCalls, ksym, psym->name,
-               psym->region->path);
-#endif
-    }
-    delete[] syms;
-    delete trace;
-
-    return 0;
-}
diff --git a/emulator/qtools/decoder.cpp b/emulator/qtools/decoder.cpp
deleted file mode 100644
index ec53181..0000000
--- a/emulator/qtools/decoder.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include "decoder.h"
-#include "trace_common.h"
-
-// This array provides a fast conversion from the initial byte in
-// a varint-encoded object to the length (in bytes) of that object.
-int prefix_to_len[] = {
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-    5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 9, 9, 17, 17
-};
-
-// This array provides a fast conversion from the initial byte in
-// a varint-encoded object to the initial data bits for that object.
-int prefix_to_data[] = {
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
-    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-    112, 113, 114, 115, 116, 117, 118, 119,
-    120, 121, 122, 123, 124, 125, 126, 127,
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-    0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 0, 0, 0
-};
-
-signed char prefix_to_signed_data[] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
-    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
-    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
-    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
-    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
-    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
-    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
-    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
-    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
-    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
-    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
-    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-    0x00, 0x01, 0x02, 0x03, 0xfc, 0xfd, 0xfe, 0xff,
-    0x00, 0x01, 0xfe, 0xff, 0x00, 0xff, 0x00, 0xff,
-};
-
-Decoder::Decoder()
-{
-    filename_ = NULL;
-    fstream_ = NULL;
-    next_ = NULL;
-    end_ = NULL;
-}
-
-Decoder::~Decoder()
-{
-    Close();
-    delete[] filename_;
-}
-
-void Decoder::Close()
-{
-    if (fstream_) {
-        fclose(fstream_);
-        fstream_ = NULL;
-    }
-}
-
-void Decoder::Open(char *filename)
-{
-    if (filename_ != NULL) {
-        delete[] filename_;
-    }
-    filename_ = new char[strlen(filename) + 1];
-    strcpy(filename_, filename);
-    fstream_ = fopen(filename_, "r");
-    if (fstream_ == NULL) {
-        perror(filename_);
-        exit(1);
-    }
-
-    int rval = fread(buf_, 1, kBufSize, fstream_);
-    if (rval != kBufSize) {
-        if (ferror(fstream_)) {
-            perror(filename_);
-            exit(1);
-        }
-        if (!feof(fstream_)) {
-            fprintf(stderr, "Unexpected short fread() before eof\n");
-            exit(1);
-        }
-    }
-    next_ = buf_;
-    end_ = buf_ + rval;
-}
-
-void Decoder::FillBuffer()
-{
-    assert(next_ <= end_);
-  
-    if (end_ - next_ < kDecodingSpace && end_ == &buf_[kBufSize]) {
-        // Copy the unused bytes left at the end to the beginning of the
-        // buffer.
-        int len = end_ - next_;
-        if (len > 0)
-            memcpy(buf_, next_, len);
-
-        // Read enough bytes to fill up the buffer, if possible.
-        int nbytes = kBufSize - len;
-        int rval = fread(buf_ + len, 1, nbytes, fstream_);
-        if (rval < nbytes) {
-            if (ferror(fstream_)) {
-                perror(filename_);
-                exit(1);
-            }
-            if (!feof(fstream_)) {
-                fprintf(stderr, "Unexpected short fread() before eof\n");
-                exit(1);
-            }
-        }
-        end_ = &buf_[len + rval];
-        next_ = buf_;
-    }
-}
-
-void Decoder::Read(char *dest, int len)
-{
-    while (len > 0) {
-        int nbytes = end_ - next_;
-        if (nbytes == 0) {
-            FillBuffer();
-            nbytes = end_ - next_;
-            if (nbytes == 0)
-                break;
-        }
-        if (nbytes > len)
-            nbytes = len;
-        memcpy(dest, next_, nbytes);
-        dest += nbytes;
-        len -= nbytes;
-        next_ += nbytes;
-    }
-}
-
-// Decode a varint-encoded object starting at the current position in
-// the array "buf_" and return the decoded value as a 64-bit integer.
-// A varint-encoded object has an initial prefix that specifies how many
-// data bits follow.  If the first bit is zero, for example, then there
-// are 7 data bits that follow.  The table below shows the prefix values
-// and corresponding data bits.
-//
-// Prefix     Bytes  Data bits
-// 0          1      7
-// 10         2      14
-// 110        3      21
-// 1110       4      28
-// 11110      5      35
-// 111110     6      42
-// 11111100   9      64
-// 11111101   reserved
-// 11111110   reserved
-// 11111111   reserved
-int64_t Decoder::Decode(bool is_signed)
-{
-    int64_t val64;
-
-    if (end_ - next_ < kDecodingSpace)
-        FillBuffer();
-
-#if BYTE_ORDER == BIG_ENDIAN
-    uint8_t byte0 = *next_;
-
-    // Get the number of bytes to decode based on the first byte.
-    int len = prefix_to_len[byte0];
-
-    if (next_ + len > end_) {
-        fprintf(stderr, "%s: decoding past end of file.\n", filename_);
-        exit(1);
-    }
-
-    // Get the first data byte.
-    if (is_signed)
-        val64 = prefix_to_signed_data[byte0];
-    else
-        val64 = prefix_to_data[byte0];
-
-    next_ += 1;
-    for (int ii = 1; ii < len; ++ii) {
-        val64 = (val64 << 8) | *next_++;
-    }
-#else
-    // If we are on a little-endian machine, then use large, unaligned loads.
-    uint64_t data = *(reinterpret_cast<uint64_t*>(next_));
-    uint8_t byte0 = data;
-    data = bswap64(data);
-
-    // Get the number of bytes to decode based on the first byte.
-    int len = prefix_to_len[byte0];
-
-    if (next_ + len > end_) {
-        fprintf(stderr, "%s: decoding past end of file.\n", filename_);
-        exit(1);
-    }
-
-    // Get the first data byte.
-    if (is_signed)
-        val64 = prefix_to_signed_data[byte0];
-    else
-        val64 = prefix_to_data[byte0];
-
-    switch (len) {
-        case 1:
-            break;
-        case 2:
-            val64 = (val64 << 8) | ((data >> 48) & 0xffull);
-            break;
-        case 3:
-            val64 = (val64 << 16) | ((data >> 40) & 0xffffull);
-            break;
-        case 4:
-            val64 = (val64 << 24) | ((data >> 32) & 0xffffffull);
-            break;
-        case 5:
-            val64 = (val64 << 32) | ((data >> 24) & 0xffffffffull);
-            break;
-        case 6:
-            val64 = (val64 << 40) | ((data >> 16) & 0xffffffffffull);
-            break;
-        case 9:
-            data = *(reinterpret_cast<uint64_t*>(&next_[1]));
-            val64 = bswap64(data);
-            break;
-    }
-    next_ += len;
-#endif
-    return val64;
-}
diff --git a/emulator/qtools/decoder.h b/emulator/qtools/decoder.h
deleted file mode 100644
index 44905fd..0000000
--- a/emulator/qtools/decoder.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <inttypes.h>
-
-class Decoder {
- public:
-  Decoder();
-  ~Decoder();
-
-  void          Open(char *filename);
-  void          Close();
-  int64_t       Decode(bool is_signed);
-  void          Read(char *dest, int len);
-  bool          IsEOF()          { return (end_ == next_) && feof(fstream_); }
-
- private:
-  static const int kBufSize = 4096;
-  static const int kDecodingSpace = 9;
-
-  void          FillBuffer();
-
-  char          *filename_;
-  FILE          *fstream_;
-  uint8_t       buf_[kBufSize];
-  uint8_t       *next_;
-  uint8_t       *end_;
-};
diff --git a/emulator/qtools/dmtrace.cpp b/emulator/qtools/dmtrace.cpp
deleted file mode 100644
index c486c5f..0000000
--- a/emulator/qtools/dmtrace.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <string.h>
-#include <unistd.h>
-#include "dmtrace.h"
-
-static const short kVersion = 2;
-
-const DmTrace::Header DmTrace::header = {
-    0x574f4c53, kVersion, sizeof(DmTrace::Header), 0LL
-};
-
-static char *keyHeader = "*version\n" "2\n" "clock=thread-cpu\n";
-static char *keyThreadHeader = "*threads\n";
-static char *keyFunctionHeader = "*methods\n";
-static char *keyEnd = "*end\n";
-
-DmTrace::DmTrace() {
-    fData = NULL;
-    fTrace = NULL;
-    threads = new std::vector<ThreadRecord*>;
-    functions = new std::vector<FunctionRecord*>;
-}
-
-DmTrace::~DmTrace() {
-    delete threads;
-    delete functions;
-}
-
-void DmTrace::open(const char *dmtrace_file, uint64_t start_time)
-{
-    fTrace = fopen(dmtrace_file, "w");
-    if (fTrace == NULL) {
-        perror(dmtrace_file);
-        exit(1);
-    }
-
-    // Make a temporary file to write the data into.
-    char tmpData[32];
-    strcpy(tmpData, "/tmp/dmtrace-data-XXXXXX");
-    int data_fd = mkstemp(tmpData);
-    if (data_fd < 0) {
-        perror("Cannot create temporary file");
-        exit(1);
-    }
-
-    // Ensure it goes away on exit.
-    unlink(tmpData);
-    fData = fdopen(data_fd, "w+");
-    if (fData == NULL) {
-        perror("Can't make temp data file");
-        exit(1);
-    }
-
-    writeHeader(fData, start_time);
-}
-
-void DmTrace::close()
-{
-    if (fTrace == NULL)
-        return;
-    writeKeyFile(fTrace);
-
-    // Take down how much data we wrote to the temp data file.
-    long size = ftell(fData);
-    // Rewind the data file and append its contents to the trace file.
-    rewind(fData);
-    char *data = (char *)malloc(size);
-    fread(data, size, 1, fData);
-    fwrite(data, size, 1, fTrace);
-    free(data);
-    fclose(fData);
-    fclose(fTrace);
-}
-
-/*
- * Write values to the binary data file.
- */
-void DmTrace::write2LE(FILE* fstream, unsigned short val)
-{
-    putc(val & 0xff, fstream);
-    putc(val >> 8, fstream);
-}
-
-void DmTrace::write4LE(FILE* fstream, unsigned int val)
-{
-    putc(val & 0xff, fstream);
-    putc((val >> 8) & 0xff, fstream);
-    putc((val >> 16) & 0xff, fstream);
-    putc((val >> 24) & 0xff, fstream);
-}
-
-void DmTrace::write8LE(FILE* fstream, unsigned long long val)
-{
-    putc(val & 0xff, fstream);
-    putc((val >> 8) & 0xff, fstream);
-    putc((val >> 16) & 0xff, fstream);
-    putc((val >> 24) & 0xff, fstream);
-    putc((val >> 32) & 0xff, fstream);
-    putc((val >> 40) & 0xff, fstream);
-    putc((val >> 48) & 0xff, fstream);
-    putc((val >> 56) & 0xff, fstream);
-}
-
-void DmTrace::writeHeader(FILE *fstream, uint64_t startTime)
-{
-    write4LE(fstream, header.magic);
-    write2LE(fstream, header.version);
-    write2LE(fstream, header.offset);
-    write8LE(fstream, startTime);
-}
-
-void DmTrace::writeDataRecord(FILE *fstream, int threadId,
-                             unsigned int methodVal,
-                             unsigned int elapsedTime)
-{
-    write2LE(fstream, threadId);
-    write4LE(fstream, methodVal);
-    write4LE(fstream, elapsedTime);
-}
-
-void DmTrace::addFunctionEntry(int functionId, uint32_t cycle, uint32_t pid)
-{
-    writeDataRecord(fData, pid, functionId, cycle);
-}
-
-void DmTrace::addFunctionExit(int functionId, uint32_t cycle, uint32_t pid)
-{
-    writeDataRecord(fData, pid, functionId | 1, cycle);
-}
-
-void DmTrace::addFunction(int functionId, const char *name)
-{
-    FunctionRecord *rec = new FunctionRecord;
-    rec->id = functionId;
-    rec->name = name;
-    functions->push_back(rec);
-}
-
-void DmTrace::addFunction(int functionId, const char *clazz,
-                          const char *method, const char *sig)
-{
-    // Allocate space for all the strings, plus 2 tab separators plus null byte.
-    // We currently don't reclaim this space.
-    int len = strlen(clazz) + strlen(method) + strlen(sig) + 3;
-    char *name = new char[len];
-    sprintf(name, "%s\t%s\t%s", clazz, method, sig);
-
-    addFunction(functionId, name);
-}
-
-void DmTrace::parseAndAddFunction(int functionId, const char *name)
-{
-    // Parse the "name" string into "class", "method" and "signature".
-    // The "name" string should look something like this:
-    //   name = "java.util.LinkedList.size()I"
-    // and it will be parsed into this:
-    //   clazz = "java.util.LinkedList"
-    //   method = "size"
-    //   sig = "()I"
-
-    // Find the first parenthesis, the start of the signature.
-    char *paren = (char*)strchr(name, '(');
-
-    // If not found, then add the original name.
-    if (paren == NULL) {
-        addFunction(functionId, name);
-        return;
-    }
-
-    // Copy the signature
-    int len = strlen(paren) + 1;
-    char *sig = new char[len];
-    strcpy(sig, paren);
-
-    // Zero the parenthesis so that we can search backwards from the signature
-    *paren = 0;
-
-    // Search for the last period, the start of the method name
-    char *dot = (char*)strrchr(name, '.');
-
-    // If not found, then add the original name.
-    if (dot == NULL || dot == name) {
-        delete[] sig;
-        *paren = '(';
-        addFunction(functionId, name);
-        return;
-    }
-
-    // Copy the method, not including the dot
-    len = strlen(dot + 1) + 1;
-    char *method = new char[len];
-    strcpy(method, dot + 1);
-
-    // Zero the dot to delimit the class name
-    *dot = 0;
-
-    addFunction(functionId, name, method, sig);
-
-    // Free the space we allocated.
-    delete[] sig;
-    delete[] method;
-}
-
-void DmTrace::addThread(int threadId, const char *name)
-{
-    ThreadRecord *rec = new ThreadRecord;
-    rec->id = threadId;
-    rec->name = name;
-    threads->push_back(rec);
-}
-
-void DmTrace::updateName(int threadId, const char *name)
-{
-    std::vector<ThreadRecord*>::iterator iter;
-
-    for (iter = threads->begin(); iter != threads->end(); ++iter) {
-        if ((*iter)->id == threadId) {
-            (*iter)->name = name;
-            return;
-        }
-    }
-}
-
-void DmTrace::writeKeyFile(FILE *fstream)
-{
-    fwrite(keyHeader, strlen(keyHeader), 1, fstream);
-    writeThreads(fstream);
-    writeFunctions(fstream);
-    fwrite(keyEnd, strlen(keyEnd), 1, fstream);
-}
-
-void DmTrace::writeThreads(FILE *fstream)
-{
-    std::vector<ThreadRecord*>::iterator iter;
-
-    fwrite(keyThreadHeader, strlen(keyThreadHeader), 1, fstream);
-    for (iter = threads->begin(); iter != threads->end(); ++iter) {
-        fprintf(fstream, "%d\t%s\n", (*iter)->id, (*iter)->name);
-    }
-}
-
-void DmTrace::writeFunctions(FILE *fstream)
-{
-    std::vector<FunctionRecord*>::iterator iter;
-
-    fwrite(keyFunctionHeader, strlen(keyFunctionHeader), 1, fstream);
-    for (iter = functions->begin(); iter != functions->end(); ++iter) {
-        fprintf(fstream, "0x%x\t%s\n", (*iter)->id, (*iter)->name);
-    }
-}
diff --git a/emulator/qtools/dmtrace.h b/emulator/qtools/dmtrace.h
deleted file mode 100644
index 6e20921..0000000
--- a/emulator/qtools/dmtrace.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef DMTRACE_H
-#define DMTRACE_H
-
-#include <vector>
-
-class DmTrace {
-  public:
-    struct Header {
-        uint32_t        magic;
-        uint16_t        version;
-        uint16_t        offset;
-        uint64_t        date_time;
-    };
-
-    DmTrace();
-    ~DmTrace();
-
-    void        open(const char *dmtrace_file, uint64_t startTime);
-    void        close();
-    void        addFunctionEntry(int methodId, uint32_t cycle, uint32_t pid);
-    void        addFunctionExit(int methodId, uint32_t cycle, uint32_t pid);
-    void        addFunction(int functionId, const char *name);
-    void        addFunction(int functionId, const char *clazz, const char *method,
-                            const char *sig);
-    void        parseAndAddFunction(int functionId, const char *name);
-    void        addThread(int threadId, const char *name);
-    void        updateName(int threadId, const char *name);
-
-  private:
-    static const Header header;
-
-    struct ThreadRecord {
-        int             id;
-        const char      *name;
-    };
-
-    struct FunctionRecord {
-        int             id;
-        const char      *name;
-    };
-
-    void        write2LE(FILE* fstream, unsigned short val);
-    void        write4LE(FILE* fstream, unsigned int val);
-    void        write8LE(FILE* fstream, unsigned long long val);
-    void        writeHeader(FILE *fstream, uint64_t startTime);
-    void        writeDataRecord(FILE *fstream, int threadId,
-                                unsigned int methodVal,
-                                unsigned int elapsedTime);
-    void        writeKeyFile(FILE *fstream);
-    void        writeThreads(FILE *fstream);
-    void        writeFunctions(FILE *fstream);
-
-    FILE        *fData;
-    FILE        *fTrace;
-    std::vector<ThreadRecord*> *threads;
-    std::vector<FunctionRecord*> *functions;
-};
-
-#endif  // DMTRACE_H
diff --git a/emulator/qtools/dump_regions.cpp b/emulator/qtools/dump_regions.cpp
deleted file mode 100644
index 57389f9..0000000
--- a/emulator/qtools/dump_regions.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <string.h>
-#include "trace_reader.h"
-#include "parse_options.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_file\n", program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv) {
-    // Parse the options
-    ParseOptions(argc, argv);
-    if (argc - optind != 1) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[optind];
-    TraceReader<> *trace = new TraceReader<>;
-    trace->Open(trace_filename);
-    trace->SetRoot(root);
-
-    while (1) {
-        BBEvent event, ignored;
-        symbol_type *dummy_sym;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &dummy_sym))
-            break;
-    }
-
-    int num_procs;
-    ProcessState *processes = trace->GetProcesses(&num_procs);
-
-    ProcessState *pstate = &processes[0];
-    for (int ii = 0; ii < num_procs; ++ii, ++pstate) {
-        if (pstate->name == NULL)
-            pstate->name = "";
-        ProcessState *manager = pstate->addr_manager;
-        printf("pid %d regions: %d %s",
-               pstate->pid, manager->nregions, pstate->name);
-        for (int jj = 1; jj < pstate->argc; ++jj) {
-            printf(" %s", pstate->argv[jj]);
-        }
-        printf("\n");
-        trace->DumpRegions(stdout, pstate);
-    }
-
-    delete trace;
-    return 0;
-}
diff --git a/emulator/qtools/exc_dump.cpp b/emulator/qtools/exc_dump.cpp
deleted file mode 100644
index 166586f..0000000
--- a/emulator/qtools/exc_dump.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include "trace_reader_base.h"
-
-int main(int argc, char **argv) {
-    if (argc != 2) {
-        fprintf(stderr, "Usage: %s trace_file\n", argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[1];
-    TraceReaderBase *trace = new TraceReaderBase;
-    trace->Open(trace_filename);
-
-    while (1) {
-        uint64_t time, recnum, bb_num, bb_start_time;
-        uint32_t pc, target_pc;
-        int num_insns;
-
-        if (trace->ReadExc(&time, &pc, &recnum, &target_pc, &bb_num,
-                           &bb_start_time, &num_insns))
-            break;
-        printf("time: %lld rec: %llu pc: %08x target: %08x bb: %llu bb_start: %llu insns: %d\n",
-               time, recnum, pc, target_pc, bb_num, bb_start_time, num_insns);
-    }
-    return 0;
-}
diff --git a/emulator/qtools/gtrace.cpp b/emulator/qtools/gtrace.cpp
deleted file mode 100644
index 673d8a4..0000000
--- a/emulator/qtools/gtrace.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include "gtrace.h"
-
-// A buffer of zeros
-static char zeros[Gtrace::kGtraceEntriesPerBlock * sizeof(Gtrace::trace_entry)];
-
-Gtrace::Gtrace() {
-  gtrace_file_ = NULL;
-  ftrace_ = NULL;
-  fnames_ = NULL;
-  start_sec_ = 0;
-  pdate_ = 0;
-  ptime_ = 0;
-  num_entries_ = 0;
-  blockno_ = 1;
-  current_pid_ = 0;
-}
-
-Gtrace::~Gtrace() {
-  if (ftrace_) {
-    // Extend the trace file to a multiple of 8k. Otherwise gtracepost64
-    // complains.
-    long pos = ftell(ftrace_);
-    long pos_end = (pos + 0x1fff) & ~0x1fff;
-    if (pos_end > pos) {
-      char ch = 0;
-      fseek(ftrace_, pos_end - 1, SEEK_SET);
-      fwrite(&ch, 1, 1, ftrace_);
-    }
-    fclose(ftrace_);
-  }
-  if (fnames_)
-    fclose(fnames_);
-}
-
-void Gtrace::Open(const char *gtrace_file, uint32_t pdate, uint32_t ptime)
-{
-  ftrace_ = fopen(gtrace_file, "w");
-  if (ftrace_ == NULL) {
-    perror(gtrace_file);
-    exit(1);
-  }
-  gtrace_file_ = gtrace_file;
-
-  pdate_ = pdate;
-  ptime_ = ptime;
-  sprintf(gname_file_, "gname_%x_%06x.txt", pdate, ptime);
-  fnames_ = fopen(gname_file_, "w");
-  if (fnames_ == NULL) {
-    perror(gname_file_);
-    exit(1);
-  }
-  fprintf(fnames_, "# File# Proc# Line# Name\n");
-}
-
-void Gtrace::WriteFirstHeader(uint32_t start_sec, uint32_t pid)
-{
-  first_header fh;
-  current_pid_ = pid;
-  start_sec_ = start_sec;
-  FillFirstHeader(start_sec, pid, &fh);
-  fwrite(&fh, sizeof(fh), 1, ftrace_);
-  num_entries_ = 8;
-}
-
-void Gtrace::FillFirstHeader(uint32_t start_sec, uint32_t pid,
-                             first_header *fh) {
-  int cpu = 0;
-  int max_files = 16;
-  int max_procedures = 12;
-
-  fh->common.blockno = 0;
-  fh->common.entry_width = 8;
-  fh->common.block_tic = kBaseTic;
-  fh->common.block_time = start_sec;
-  //fh->common.usec_cpu = (start_usec << 8) | (cpu & 0xff);
-  fh->common.usec_cpu = cpu & 0xff;
-  fh->common.pid = pid;
-  fh->common.bug_count = 0;
-  fh->common.zero_count = 0;
-
-  fh->tic = kBaseTic + 1;
-  fh->one = 1;
-  fh->tics_per_second = kTicsPerSecond;
-  fh->trace_time = start_sec;
-  fh->version = 5;
-  fh->file_proc = (max_files << 8) | max_procedures;
-  fh->pdate = pdate_;
-  fh->ptime = ptime_;
-}
-
-void Gtrace::WriteBlockHeader(uint32_t cycle, uint32_t pid)
-{
-  int cpu = 0;
-  block_header bh;
-
-  bh.blockno = blockno_++;
-  bh.entry_width = 8;
-  bh.block_tic = cycle + kBaseTic;
-  bh.block_time = start_sec_ + cycle / kTicsPerSecond;
-  //bh.usec_cpu = (start_usec << 8) | (cpu & 0xff);
-  bh.usec_cpu = cpu & 0xff;
-  bh.pid = pid;
-  bh.bug_count = 0;
-  bh.zero_count = 0;
-  fwrite(&bh, sizeof(bh), 1, ftrace_);
-}
-
-void Gtrace::AddGtraceRecord(int filenum, int procnum, uint32_t cycle, uint32_t pid,
-                             int is_exit)
-{
-  trace_entry	entry;
-
-  if (current_pid_ != pid) {
-    current_pid_ = pid;
-
-    // We are switching to a new process id, so pad the current block
-    // with zeros.
-    int num_zeros = (kGtraceEntriesPerBlock - num_entries_) * sizeof(entry);
-    fwrite(zeros, num_zeros, 1, ftrace_);
-    WriteBlockHeader(cycle, pid);
-    num_entries_ = 4;
-  }
-
-  // If the current block is full, write out a new block header
-  if (num_entries_ == kGtraceEntriesPerBlock) {
-    WriteBlockHeader(cycle, pid);
-    num_entries_ = 4;
-  }
-
-  entry.cycle = cycle + kBaseTic;
-  entry.event = (filenum << 13) | (procnum << 1) | is_exit;
-  fwrite(&entry, sizeof(entry), 1, ftrace_);
-  num_entries_ += 1;
-}
-
-void Gtrace::AddProcEntry(int filenum, int procnum, uint32_t cycle, uint32_t pid)
-{
-  AddGtraceRecord(filenum, procnum, cycle, pid, 0);
-}
-
-void Gtrace::AddProcExit(int filenum, int procnum, uint32_t cycle, uint32_t pid)
-{
-  AddGtraceRecord(filenum, procnum, cycle, pid, 1);
-}
-
-void Gtrace::AddProcedure(int filenum, int procnum, const char *proc_name)
-{
-  fprintf(fnames_, "%d %d %d %s\n", filenum, procnum, procnum, proc_name);
-}
diff --git a/emulator/qtools/gtrace.h b/emulator/qtools/gtrace.h
deleted file mode 100644
index 542adc2..0000000
--- a/emulator/qtools/gtrace.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef GTRACE_H
-#define GTRACE_H
-
-class Gtrace {
- public:
-  static const int kGtraceEntriesPerBlock = 1024;
-  static const uint32_t kMillion = 1000000;
-  static const uint32_t kTicsPerSecond = 200 * kMillion;
-  static const int kBaseTic = 0x1000;
-
-  struct trace_entry {
-    uint32_t	cycle;
-    uint32_t	event;
-  };
-
-  struct block_header {
-    uint32_t	blockno;
-    uint32_t	entry_width;
-    uint32_t	block_tic;
-    uint32_t	block_time;
-    uint32_t	usec_cpu;
-    uint32_t	pid;
-    uint32_t	bug_count;
-    uint32_t	zero_count;
-  };
-
-  struct first_header {
-    block_header	common;
-    uint32_t		tic;
-    uint32_t		one;
-    uint32_t		tics_per_second;
-    uint32_t		trace_time;
-    uint32_t		version;
-    uint32_t		file_proc;
-    uint32_t		pdate;
-    uint32_t		ptime;
-  };
-
-  Gtrace();
-  ~Gtrace();
-
-  void		Open(const char *gtrace_file, uint32_t pdate, uint32_t ptime);
-  void		WriteFirstHeader(uint32_t start_sec, uint32_t pid);
-  void		AddProcedure(int filenum, int procnum, const char *proc_name);
-  void		AddProcEntry(int filenum, int procnum, uint32_t cycle, uint32_t pid);
-  void		AddProcExit(int filenum, int procnum, uint32_t cycle, uint32_t pid);
-
- private:
-  void		AddGtraceRecord(int filenum, int procnum, uint32_t cycle, uint32_t pid,
-                                int is_exit);
-  void		FillFirstHeader(uint32_t start_sec, uint32_t pid,
-                                first_header *fh);
-  void		WriteBlockHeader(uint32_t cycle, uint32_t pid);
-
-  const char	*gtrace_file_;
-  char		gname_file_[100];
-  FILE		*ftrace_;
-  FILE		*fnames_;
-  uint32_t	start_sec_;
-  uint32_t	pdate_;
-  uint32_t	ptime_;
-  int		num_entries_;
-  int		blockno_;
-  uint32_t	current_pid_;
-};
-
-#endif  // GTRACE_H
diff --git a/emulator/qtools/hash_table.h b/emulator/qtools/hash_table.h
deleted file mode 100644
index 4ea9ed5..0000000
--- a/emulator/qtools/hash_table.h
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef HASH_TABLE_H
-#define HASH_TABLE_H
-
-#include <string.h>
-#include <inttypes.h>
-
-template<class T>
-class HashTable {
-  public:
-    HashTable(int size, T default_value = T());
-    ~HashTable();
-
-    typedef struct entry {
-        entry    *next;
-        char     *key;
-        T        value;
-    } entry_type;
-
-    typedef T value_type;
-
-    void         Update(const char *key, T value);
-    bool         Remove(const char *key);
-    T            Find(const char *key);
-    entry_type*  GetFirst();
-    entry_type*  GetNext();
-
-  private:
-    uint32_t     HashFunction(const char *key);
-
-    int          size_;
-    int          mask_;
-    T            default_value_;
-    entry_type   **table_;
-    int          num_entries_;
-    int          current_index_;
-    entry_type   *current_ptr_;
-};
-
-template<class T>
-HashTable<T>::HashTable(int size, T default_value)
-{
-    int pow2;
-
-    // Round up size to a power of two
-    for (pow2 = 2; pow2 < size; pow2 <<= 1)
-        ;    // empty body
-
-    size_ = pow2;
-    mask_ = pow2 - 1;
-    default_value_ = default_value;
-
-    // Allocate a table of pointers and initialize them all to NULL.
-    table_ = new entry_type*[size_];
-    for (int ii = 0; ii < size_; ++ii)
-        table_[ii] = NULL;
-    num_entries_ = 0;
-    current_index_ = 0;
-    current_ptr_ = NULL;
-}
-
-template<class T>
-HashTable<T>::~HashTable()
-{
-    for (int ii = 0; ii < size_; ++ii) {
-        entry_type *ptr, *next;
-
-        // Delete all the pointers in the chain at this table position.
-        // Save the next pointer before deleting each entry so that we
-        // don't dereference part of a deallocated object.
-        for (ptr = table_[ii]; ptr; ptr = next) {
-            next = ptr->next;
-            delete[] ptr->key;
-            delete ptr;
-        }
-    }
-    delete[] table_;
-}
-
-// Professor Daniel J. Bernstein's hash function.  See
-// http://www.partow.net/programming/hashfunctions/
-template<class T>
-uint32_t HashTable<T>::HashFunction(const char *key)
-{
-    uint32_t hash = 5381;
-
-    int len = strlen(key);
-    for(int ii = 0; ii < len; ++key, ++ii)
-        hash = ((hash << 5) + hash) + *key;
-
-    return hash;
-}
-
-template<class T>
-void HashTable<T>::Update(const char *key, T value)
-{
-    // Hash the key to get the table position
-    int len = strlen(key);
-    int pos = HashFunction(key) & mask_;
-
-    // Search the chain for a matching key
-    for (entry_type *ptr = table_[pos]; ptr; ptr = ptr->next) {
-        if (strcmp(ptr->key, key) == 0) {
-            ptr->value = value;
-            return;
-        }
-    }
-
-    // Create a new hash entry and fill in the values
-    entry_type *ptr = new entry_type;
-
-    // Copy the string
-    ptr->key = new char[len + 1];
-    strcpy(ptr->key, key);
-    ptr->value = value;
-
-    // Insert the new entry at the beginning of the list
-    ptr->next = table_[pos];
-    table_[pos] = ptr;
-    num_entries_ += 1;
-}
-
-template<class T>
-bool HashTable<T>::Remove(const char *key)
-{
-    // Hash the key to get the table position
-    int len = strlen(key);
-    int pos = HashFunction(key) & mask_;
-
-    // Search the chain for a matching key and keep track of the previous
-    // element in the chain.
-    entry_type *prev = NULL;
-    for (entry_type *ptr = table_[pos]; ptr; prev = ptr, ptr = ptr->next) {
-        if (strcmp(ptr->key, key) == 0) {
-            if (prev == NULL) {
-                table_[pos] = ptr->next;
-            } else {
-                prev->next = ptr->next;
-            }
-            delete ptr->key;
-            delete ptr;
-            return true;
-        }
-    }
-    return false;
-}
-
-template<class T>
-typename HashTable<T>::value_type HashTable<T>::Find(const char *key)
-{
-    // Hash the key to get the table position
-    int pos = HashFunction(key) & mask_;
-
-    // Search the chain for a matching key
-    for (entry_type *ptr = table_[pos]; ptr; ptr = ptr->next) {
-        if (strcmp(ptr->key, key) == 0)
-            return ptr->value;
-    }
-
-    // If we get here, then we didn't find the key
-    return default_value_;
-}
-
-template<class T>
-typename HashTable<T>::entry_type* HashTable<T>::GetFirst()
-{
-    // Find the first non-NULL table entry.
-    for (current_index_ = 0; current_index_ < size_; ++current_index_) {
-        if (table_[current_index_])
-            break;
-    }
-
-    // If there are no table entries, then return NULL.
-    if (current_index_ == size_)
-        return NULL;
-
-    // Remember and return the current element.
-    current_ptr_ = table_[current_index_];
-    return current_ptr_;
-}
-
-template<class T>
-typename HashTable<T>::entry_type* HashTable<T>::GetNext()
-{
-    // If we already iterated part way through the hash table, then continue
-    // to the next element.
-    if (current_ptr_) {
-        current_ptr_ = current_ptr_->next;
-
-        // If we are pointing to a valid element, then return it.
-        if (current_ptr_)
-            return current_ptr_;
-
-        // Otherwise, start searching at the next table index.
-        current_index_ += 1;
-    }
-
-    // Find the next non-NULL table entry.
-    for (; current_index_ < size_; ++current_index_) {
-        if (table_[current_index_])
-            break;
-    }
-
-    // If there are no more non-NULL table entries, then return NULL.
-    if (current_index_ == size_) {
-        // Reset the current index so that we will start over from the
-        // beginning on the next call to GetNext().
-        current_index_ = 0;
-        return NULL;
-    }
-
-    // Remember and return the current element.
-    current_ptr_ = table_[current_index_];
-    return current_ptr_;
-}
-
-
-#endif  // HASH_TABLE_H
diff --git a/emulator/qtools/hist_trace.cpp b/emulator/qtools/hist_trace.cpp
deleted file mode 100644
index d2c6a90..0000000
--- a/emulator/qtools/hist_trace.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-
-static const int kMaxHistEntries = 256;
-static const int kMaxHistEntries2 = kMaxHistEntries /  2;
-int hist[kMaxHistEntries];
-int underflow, overflow;
-
-int main(int argc, char **argv) {
-  if (argc != 2) {
-    fprintf(stderr, "Usage: %s trace_file\n", argv[0]);
-    exit(1);
-  }
-
-  char *trace_filename = argv[1];
-  TraceReaderBase *trace = new TraceReaderBase;
-  trace->Open(trace_filename);
-
-  uint64_t prev_bb_num = 0;
-  uint64_t prev_time = 0;
-  int total = 0;
-  
-  while (1) {
-    BBEvent event;
-
-    if (trace->ReadBB(&event))
-      break;
-    int bb_diff = event.bb_num - prev_bb_num;
-    //int time_diff = event.time - prev_time;
-    //printf("bb_num: %llu prev: %llu, diff: %d\n",
-    // event.bb_num, prev_bb_num, bb_diff);
-    prev_bb_num = event.bb_num;
-    prev_time = event.time;
-
-    bb_diff += kMaxHistEntries2;
-    if (bb_diff < 0)
-      underflow += 1;
-    else if (bb_diff >= kMaxHistEntries)
-      overflow += 1;
-    else
-      hist[bb_diff] += 1;
-    total += 1;
-  }
-
-  int sum = 0;
-  double sum_per = 0;
-  double per = 0;
-  for (int ii = 0; ii < kMaxHistEntries; ++ii) {
-    if (hist[ii] == 0)
-      continue;
-    per = 100.0 * hist[ii] / total;
-    sum += hist[ii];
-    sum_per = 100.0 * sum / total;
-    printf(" %4d: %6d %6.2f %6.2f\n", ii - kMaxHistEntries2, hist[ii], per, sum_per);
-  }
-  per = 100.0 * underflow / total;
-  printf("under: %6d %6.2f\n", underflow, per);
-  per = 100.0 * overflow / total;
-  printf("over:  %6d %6.2f\n", overflow, per);
-  printf("total: %6d\n", total);
-  return 0;
-}
diff --git a/emulator/qtools/opcode.cpp b/emulator/qtools/opcode.cpp
deleted file mode 100644
index 41bef3a..0000000
--- a/emulator/qtools/opcode.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <inttypes.h>
-#include "opcode.h"
-
-// Note: this array depends on the Opcode enum defined in opcode.h
-uint32_t opcode_flags[] = {
-    0,                                             // OP_INVALID
-    0,                                             // OP_UNDEFINED
-    kCatAlu,                                       // OP_ADC
-    kCatAlu,                                       // OP_ADD
-    kCatAlu,                                       // OP_AND
-    kCatBranch,                                    // OP_B
-    kCatBranch | kCatBranchLink,                   // OP_BL
-    kCatAlu,                                       // OP_BIC
-    0,                                             // OP_BKPT
-    kCatBranch | kCatBranchLink | kCatBranchExch,  // OP_BLX
-    kCatBranch | kCatBranchExch,                   // OP_BX
-    kCatCoproc,                                    // OP_CDP
-    kCatAlu,                                       // OP_CLZ
-    kCatAlu,                                       // OP_CMN
-    kCatAlu,                                       // OP_CMP
-    kCatAlu,                                       // OP_EOR
-    kCatCoproc | kCatLoad,                         // OP_LDC
-    kCatLoad | kCatMultiple,                       // OP_LDM
-    kCatLoad | kCatWord,                           // OP_LDR
-    kCatLoad | kCatByte,                           // OP_LDRB
-    kCatLoad | kCatByte,                           // OP_LDRBT
-    kCatLoad | kCatHalf,                           // OP_LDRH
-    kCatLoad | kCatByte | kCatSigned,              // OP_LDRSB
-    kCatLoad | kCatHalf | kCatSigned,              // OP_LDRSH
-    kCatLoad | kCatWord,                           // OP_LDRT
-    kCatCoproc,                                    // OP_MCR
-    kCatAlu,                                       // OP_MLA
-    kCatAlu,                                       // OP_MOV
-    kCatCoproc,                                    // OP_MRC
-    0,                                             // OP_MRS
-    0,                                             // OP_MSR
-    kCatAlu,                                       // OP_MUL
-    kCatAlu,                                       // OP_MVN
-    kCatAlu,                                       // OP_ORR
-    0,                                             // OP_PLD
-    kCatAlu,                                       // OP_RSB
-    kCatAlu,                                       // OP_RSC
-    kCatAlu,                                       // OP_SBC
-    kCatAlu,                                       // OP_SMLAL
-    kCatAlu,                                       // OP_SMULL
-    kCatCoproc | kCatStore,                        // OP_STC
-    kCatStore | kCatMultiple,                      // OP_STM
-    kCatStore | kCatWord,                          // OP_STR
-    kCatStore | kCatByte,                          // OP_STRB
-    kCatStore | kCatByte,                          // OP_STRBT
-    kCatStore | kCatHalf,                          // OP_STRH
-    kCatStore | kCatWord,                          // OP_STRT
-    kCatAlu,                                       // OP_SUB
-    0,                                             // OP_SWI
-    kCatLoad | kCatStore,                          // OP_SWP
-    kCatLoad | kCatStore | kCatByte,               // OP_SWPB
-    kCatAlu,                                       // OP_TEQ
-    kCatAlu,                                       // OP_TST
-    kCatAlu,                                       // OP_UMLAL
-    kCatAlu,                                       // OP_UMULL
-
-    0,                                             // OP_THUMB_UNDEFINED,
-    kCatAlu,                                       // OP_THUMB_ADC,
-    kCatAlu,                                       // OP_THUMB_ADD,
-    kCatAlu,                                       // OP_THUMB_AND,
-    kCatAlu,                                       // OP_THUMB_ASR,
-    kCatBranch,                                    // OP_THUMB_B,
-    kCatAlu,                                       // OP_THUMB_BIC,
-    0,                                             // OP_THUMB_BKPT,
-    kCatBranch | kCatBranchLink,                   // OP_THUMB_BL,
-    kCatBranch | kCatBranchLink | kCatBranchExch,  // OP_THUMB_BLX,
-    kCatBranch | kCatBranchExch,                   // OP_THUMB_BX,
-    kCatAlu,                                       // OP_THUMB_CMN,
-    kCatAlu,                                       // OP_THUMB_CMP,
-    kCatAlu,                                       // OP_THUMB_EOR,
-    kCatLoad | kCatMultiple,                       // OP_THUMB_LDMIA,
-    kCatLoad | kCatWord,                           // OP_THUMB_LDR,
-    kCatLoad | kCatByte,                           // OP_THUMB_LDRB,
-    kCatLoad | kCatHalf,                           // OP_THUMB_LDRH,
-    kCatLoad | kCatByte | kCatSigned,              // OP_THUMB_LDRSB,
-    kCatLoad | kCatHalf | kCatSigned,              // OP_THUMB_LDRSH,
-    kCatAlu,                                       // OP_THUMB_LSL,
-    kCatAlu,                                       // OP_THUMB_LSR,
-    kCatAlu,                                       // OP_THUMB_MOV,
-    kCatAlu,                                       // OP_THUMB_MUL,
-    kCatAlu,                                       // OP_THUMB_MVN,
-    kCatAlu,                                       // OP_THUMB_NEG,
-    kCatAlu,                                       // OP_THUMB_ORR,
-    kCatLoad | kCatMultiple,                       // OP_THUMB_POP,
-    kCatStore | kCatMultiple,                      // OP_THUMB_PUSH,
-    kCatAlu,                                       // OP_THUMB_ROR,
-    kCatAlu,                                       // OP_THUMB_SBC,
-    kCatStore | kCatMultiple,                      // OP_THUMB_STMIA,
-    kCatStore | kCatWord,                          // OP_THUMB_STR,
-    kCatStore | kCatByte,                          // OP_THUMB_STRB,
-    kCatStore | kCatHalf,                          // OP_THUMB_STRH,
-    kCatAlu,                                       // OP_THUMB_SUB,
-    0,                                             // OP_THUMB_SWI,
-    kCatAlu,                                       // OP_THUMB_TST,
-
-    0,                                             // OP_END
-};
-
-const char *opcode_names[] = {
-    "invalid",
-    "undefined",
-    "adc",
-    "add",
-    "and",
-    "b",
-    "bl",
-    "bic",
-    "bkpt",
-    "blx",
-    "bx",
-    "cdp",
-    "clz",
-    "cmn",
-    "cmp",
-    "eor",
-    "ldc",
-    "ldm",
-    "ldr",
-    "ldrb",
-    "ldrbt",
-    "ldrh",
-    "ldrsb",
-    "ldrsh",
-    "ldrt",
-    "mcr",
-    "mla",
-    "mov",
-    "mrc",
-    "mrs",
-    "msr",
-    "mul",
-    "mvn",
-    "orr",
-    "pld",
-    "rsb",
-    "rsc",
-    "sbc",
-    "smlal",
-    "smull",
-    "stc",
-    "stm",
-    "str",
-    "strb",
-    "strbt",
-    "strh",
-    "strt",
-    "sub",
-    "swi",
-    "swp",
-    "swpb",
-    "teq",
-    "tst",
-    "umlal",
-    "umull",
-
-    "undefined",
-    "adc",
-    "add",
-    "and",
-    "asr",
-    "b",
-    "bic",
-    "bkpt",
-    "bl",
-    "blx",
-    "bx",
-    "cmn",
-    "cmp",
-    "eor",
-    "ldmia",
-    "ldr",
-    "ldrb",
-    "ldrh",
-    "ldrsb",
-    "ldrsh",
-    "lsl",
-    "lsr",
-    "mov",
-    "mul",
-    "mvn",
-    "neg",
-    "orr",
-    "pop",
-    "push",
-    "ror",
-    "sbc",
-    "stmia",
-    "str",
-    "strb",
-    "strh",
-    "sub",
-    "swi",
-    "tst",
-
-    NULL
-};
diff --git a/emulator/qtools/opcode.h b/emulator/qtools/opcode.h
deleted file mode 100644
index c8b67a6..0000000
--- a/emulator/qtools/opcode.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef OPCODE_H
-#define OPCODE_H
-
-#include <inttypes.h>
-
-// Note: this list of opcodes must match the list used to initialize
-// the opflags[] array in opcode.cpp.
-enum Opcode {
-    OP_INVALID,
-    OP_UNDEFINED,
-    OP_ADC,
-    OP_ADD,
-    OP_AND,
-    OP_B,
-    OP_BL,
-    OP_BIC,
-    OP_BKPT,
-    OP_BLX,
-    OP_BX,
-    OP_CDP,
-    OP_CLZ,
-    OP_CMN,
-    OP_CMP,
-    OP_EOR,
-    OP_LDC,
-    OP_LDM,
-    OP_LDR,
-    OP_LDRB,
-    OP_LDRBT,
-    OP_LDRH,
-    OP_LDRSB,
-    OP_LDRSH,
-    OP_LDRT,
-    OP_MCR,
-    OP_MLA,
-    OP_MOV,
-    OP_MRC,
-    OP_MRS,
-    OP_MSR,
-    OP_MUL,
-    OP_MVN,
-    OP_ORR,
-    OP_PLD,
-    OP_RSB,
-    OP_RSC,
-    OP_SBC,
-    OP_SMLAL,
-    OP_SMULL,
-    OP_STC,
-    OP_STM,
-    OP_STR,
-    OP_STRB,
-    OP_STRBT,
-    OP_STRH,
-    OP_STRT,
-    OP_SUB,
-    OP_SWI,
-    OP_SWP,
-    OP_SWPB,
-    OP_TEQ,
-    OP_TST,
-    OP_UMLAL,
-    OP_UMULL,
-
-    // Define thumb opcodes
-    OP_THUMB_UNDEFINED,
-    OP_THUMB_ADC,
-    OP_THUMB_ADD,
-    OP_THUMB_AND,
-    OP_THUMB_ASR,
-    OP_THUMB_B,
-    OP_THUMB_BIC,
-    OP_THUMB_BKPT,
-    OP_THUMB_BL,
-    OP_THUMB_BLX,
-    OP_THUMB_BX,
-    OP_THUMB_CMN,
-    OP_THUMB_CMP,
-    OP_THUMB_EOR,
-    OP_THUMB_LDMIA,
-    OP_THUMB_LDR,
-    OP_THUMB_LDRB,
-    OP_THUMB_LDRH,
-    OP_THUMB_LDRSB,
-    OP_THUMB_LDRSH,
-    OP_THUMB_LSL,
-    OP_THUMB_LSR,
-    OP_THUMB_MOV,
-    OP_THUMB_MUL,
-    OP_THUMB_MVN,
-    OP_THUMB_NEG,
-    OP_THUMB_ORR,
-    OP_THUMB_POP,
-    OP_THUMB_PUSH,
-    OP_THUMB_ROR,
-    OP_THUMB_SBC,
-    OP_THUMB_STMIA,
-    OP_THUMB_STR,
-    OP_THUMB_STRB,
-    OP_THUMB_STRH,
-    OP_THUMB_SUB,
-    OP_THUMB_SWI,
-    OP_THUMB_TST,
-
-    OP_END                // must be last
-};
-
-extern uint32_t opcode_flags[];
-extern const char *opcode_names[];
-
-// Define bit flags for the opcode categories
-static const uint32_t kCatByte          = 0x0001;
-static const uint32_t kCatHalf          = 0x0002;
-static const uint32_t kCatWord          = 0x0004;
-static const uint32_t kCatLong          = 0x0008;
-static const uint32_t kCatNumBytes      = (kCatByte | kCatHalf | kCatWord | kCatLong);
-static const uint32_t kCatMultiple      = 0x0010;
-static const uint32_t kCatSigned        = 0x0020;
-static const uint32_t kCatLoad          = 0x0040;
-static const uint32_t kCatStore         = 0x0080;
-static const uint32_t kCatMemoryRef     = (kCatLoad | kCatStore);
-static const uint32_t kCatAlu           = 0x0100;
-static const uint32_t kCatBranch        = 0x0200;
-static const uint32_t kCatBranchLink    = 0x0400;
-static const uint32_t kCatBranchExch    = 0x0800;
-static const uint32_t kCatCoproc        = 0x1000;
-static const uint32_t kCatLoadMultiple  = (kCatLoad | kCatMultiple);
-static const uint32_t kCatStoreMultiple = (kCatStore | kCatMultiple);
-
-inline bool isALU(Opcode op)    { return (opcode_flags[op] & kCatAlu) != 0; }
-inline bool isBranch(Opcode op) { return (opcode_flags[op] & kCatBranch) != 0; }
-inline bool isBranchLink(Opcode op) {
-    return (opcode_flags[op] & kCatBranchLink) != 0;
-}
-inline bool isBranchExch(Opcode op) {
-    return (opcode_flags[op] & kCatBranchExch) != 0;
-}
-inline bool isLoad(Opcode op)   { return (opcode_flags[op] & kCatLoad) != 0; }
-inline bool isLoadMultiple(Opcode op) {
-    return (opcode_flags[op] & kCatLoadMultiple) == kCatLoadMultiple;
-}
-inline bool isStoreMultiple(Opcode op) {
-    return (opcode_flags[op] & kCatStoreMultiple) == kCatStoreMultiple;
-}
-inline bool isStore(Opcode op)  { return (opcode_flags[op] & kCatStore) != 0; }
-inline bool isSigned(Opcode op) { return (opcode_flags[op] & kCatSigned) != 0; }
-inline bool isMemoryRef(Opcode op) {
-    return (opcode_flags[op] & kCatMemoryRef) != 0;
-}
-inline int getAccessSize(Opcode op) { return opcode_flags[op] & kCatNumBytes; }
-inline bool isCoproc(Opcode op) { return (opcode_flags[op] & kCatCoproc) != 0; }
-inline int getNumAccesses(Opcode op, uint32_t binary) {
-  extern int num_one_bits[];
-  int num_accesses = 0;
-  if (opcode_flags[op] & kCatNumBytes)
-    num_accesses = 1;
-  else if (opcode_flags[op] & kCatMultiple) {
-    num_accesses = num_one_bits[(binary >> 8) & 0xff]
-                   + num_one_bits[binary & 0xff];
-  }
-  return num_accesses;
-}
-
-#endif  // OPCODE_H
diff --git a/emulator/qtools/parse_options-inl.h b/emulator/qtools/parse_options-inl.h
deleted file mode 100644
index beb9df4..0000000
--- a/emulator/qtools/parse_options-inl.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef PARSE_OPTIONS_INL_H
-#define PARSE_OPTIONS_INL_H
-
-// Define a typedef for TraceReaderType and include "parse_options.h"
-// before including this header file in a C++ source file.
-//
-// For example:
-// 
-// struct symbol {
-//   int  elapsed;
-// };
-// 
-// typedef TraceReader<symbol> TraceReaderType;
-
-
-typedef TraceReaderType::symbol_type symbol_type;
-typedef TraceReaderType::region_type region_type;
-typedef TraceReaderType::ProcessState ProcessState;
-
-symbol_type *kernel_sym;
-symbol_type *library_sym;
-
-// Returns true if the given event is included (or not excluded)
-// from the list of valid events specified by the user on the
-// command line.
-inline bool IsValidEvent(BBEvent *event, symbol_type *sym)
-{
-  if (include_some_pids && pid_include_vector.GetBit(event->pid) == 0)
-      return false;
-  if (exclude_some_pids && pid_exclude_vector.GetBit(event->pid))
-      return false;
-  if (include_some_procedures) {
-    if (sym == NULL || included_procedures.Find(sym->name) == 0)
-      return false;
-  }
-  if (exclude_some_procedures) {
-    if (sym == NULL || excluded_procedures.Find(sym->name))
-      return false;
-  }
-  return true;
-}
-
-inline bool IsValidPid(int pid) {
-  if (include_some_pids && pid_include_vector.GetBit(pid) == 0)
-    return false;
-  if (exclude_some_pids && pid_exclude_vector.GetBit(pid))
-    return false;
-  return true;
-}
-
-inline symbol_type *GetSymbol(TraceReaderType *trace, int pid, uint32_t addr,
-                              uint64_t time)
-{
-  symbol_type *sym = trace->LookupFunction(pid, addr, time);
-
-  if (lump_kernel && (sym->region->flags & region_type::kIsKernelRegion)) {
-    if (kernel_sym == NULL) {
-      kernel_sym = sym;
-      sym->name = ":kernel";
-    } else {
-      sym = kernel_sym;
-    }
-  }
-
-  if (lump_libraries && (sym->region->flags & region_type::kIsLibraryRegion)) {
-    if (library_sym == NULL) {
-      library_sym = sym;
-      sym->name = ":libs";
-    } else {
-      sym = library_sym;
-    }
-  }
-
-  return sym;
-}
-
-inline bool IsIncludedProcedure(symbol_type *sym)
-{
-  if (include_kernel_syms && (sym->region->flags & region_type::kIsKernelRegion))
-    return true;
-  if (include_library_syms && (sym->region->flags & region_type::kIsLibraryRegion))
-    return true;
-  return included_procedures.Find(sym->name);
-}
-
-inline bool IsExcludedProcedure(symbol_type *sym)
-{
-  if (exclude_kernel_syms && (sym->region->flags & region_type::kIsKernelRegion))
-    return true;
-  if (exclude_library_syms && (sym->region->flags & region_type::kIsLibraryRegion))
-    return true;
-  return excluded_procedures.Find(sym->name);
-}
-
-// Returns true on end-of-file.
-inline bool GetNextValidEvent(TraceReaderType *trace,
-                              BBEvent *event,
-                              BBEvent *first_ignored_event,
-                              symbol_type **sym_ptr)
-{
-  symbol_type *sym = NULL;
-  first_ignored_event->time = 0;
-  if (trace->ReadBB(event))
-    return true;
-  bool recheck = true;
-  while (recheck) {
-    recheck = false;
-    if (include_some_pids) {
-      while (pid_include_vector.GetBit(event->pid) == 0) {
-        if (first_ignored_event->time == 0)
-          *first_ignored_event = *event;
-        if (trace->ReadBB(event))
-          return true;
-      }
-    } else if (exclude_some_pids) {
-      while (pid_exclude_vector.GetBit(event->pid)) {
-        if (first_ignored_event->time == 0)
-          *first_ignored_event = *event;
-        if (trace->ReadBB(event))
-          return true;
-      }
-    }
-
-    if (include_some_procedures) {
-      sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
-      while (!IsIncludedProcedure(sym)) {
-        if (first_ignored_event->time == 0)
-          *first_ignored_event = *event;
-        if (trace->ReadBB(event))
-          return true;
-        recheck = true;
-        sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
-      }
-    } else if (exclude_some_procedures) {
-      sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
-      while (IsExcludedProcedure(sym)) {
-        if (first_ignored_event->time == 0)
-          *first_ignored_event = *event;
-        if (trace->ReadBB(event))
-          return true;
-        recheck = true;
-        sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
-      }
-    }
-  }
-  if (sym == NULL)
-    sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
-
-  *sym_ptr = sym;
-  return false;
-}
-
-#endif  // PARSE_OPTIONS_INL_H
diff --git a/emulator/qtools/parse_options.cpp b/emulator/qtools/parse_options.cpp
deleted file mode 100644
index 395e9a1..0000000
--- a/emulator/qtools/parse_options.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include "bitvector.h"
-#include "parse_options.h"
-#include "hash_table.h"
-
-const char *root = "";
-bool lump_kernel;
-bool lump_libraries;
-Bitvector pid_include_vector(32768);
-Bitvector pid_exclude_vector(32768);
-bool include_some_pids;
-bool exclude_some_pids;
-
-HashTable<int> excluded_procedures(2000);
-HashTable<int> included_procedures(2000);
-bool exclude_some_procedures;
-bool include_some_procedures;
-
-bool exclude_kernel_syms;
-bool exclude_library_syms;
-bool include_kernel_syms;
-bool include_library_syms;
-bool demangle = true;
-
-static const char *OptionsUsageStr =
-    "  -e :kernel exclude all kernel symbols\n"
-    "  -e :libs   exclude all library symbols\n"
-    "  -e <func>  exclude function <func>\n"
-    "  -e <pid>   exclude process <pid>\n"
-    "  -i :kernel include all kernel symbols\n"
-    "  -i :libs   include all library symbols\n"
-    "  -i <func>  include function <func>\n"
-    "  -i <pid>   include process <pid>\n"
-    "  -l :kernel lump all the kernel symbols together\n"
-    "  -l :libs   lump all the library symbols together\n"
-    "  -m         do not demangle C++ symbols (m for 'mangle')\n"
-    "  -r <root>  use <root> as the path for finding ELF executables\n"
-    ;
-
-void OptionsUsage()
-{
-    fprintf(stderr, "%s", OptionsUsageStr);
-}
-
-void ParseOptions(int argc, char **argv)
-{
-    bool err = false;
-    while (!err) {
-        int opt = getopt(argc, argv, "+e:i:l:mr:");
-        if (opt == -1)
-            break;
-        switch (opt) {
-        case 'e':
-            if (*optarg == ':') {
-                if (strcmp(optarg, ":kernel") == 0)
-                    exclude_kernel_syms = true;
-                else if (strcmp(optarg, ":libs") == 0)
-                    exclude_library_syms = true;
-                else
-                    err = true;
-                excluded_procedures.Update(optarg, 1);
-                exclude_some_procedures = true;
-            } else if (isdigit(*optarg)) {
-                int bitnum = atoi(optarg);
-                pid_exclude_vector.SetBit(bitnum);
-                exclude_some_pids = true;
-            } else {
-                excluded_procedures.Update(optarg, 1);
-                exclude_some_procedures = true;
-            }
-            break;
-        case 'i':
-            if (*optarg == ':') {
-                if (strcmp(optarg, ":kernel") == 0)
-                    include_kernel_syms = true;
-                else if (strcmp(optarg, ":libs") == 0)
-                    include_library_syms = true;
-                else
-                    err = true;
-                included_procedures.Update(optarg, 1);
-                include_some_procedures = true;
-            } else if (isdigit(*optarg)) {
-                int bitnum = atoi(optarg);
-                pid_include_vector.SetBit(bitnum);
-                include_some_pids = true;
-            } else {
-                included_procedures.Update(optarg, 1);
-                include_some_procedures = true;
-            }
-            break;
-        case 'l':
-            if (strcmp(optarg, ":kernel") == 0)
-                lump_kernel = true;
-            else if (strcmp(optarg, ":libs") == 0)
-                lump_libraries = true;
-            else
-                err = true;
-            break;
-        case 'm':
-            demangle = false;
-            break;
-        case 'r':
-            root = optarg;
-            break;
-        default:
-            err = true;
-            break;
-        }
-    }
-
-    if (err) {
-        Usage(argv[0]);
-        exit(1);
-    }
-}
diff --git a/emulator/qtools/parse_options.h b/emulator/qtools/parse_options.h
deleted file mode 100644
index aacbb9e..0000000
--- a/emulator/qtools/parse_options.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef PARSE_OPTIONS_H
-#define PARSE_OPTIONS_H
-
-#include "bitvector.h"
-#include "hash_table.h"
-
-extern const char *root;
-extern bool lump_kernel;
-extern bool lump_libraries;
-extern Bitvector pid_include_vector;
-extern Bitvector pid_exclude_vector;
-extern bool include_some_pids;
-extern bool exclude_some_pids;
-
-extern HashTable<int> excluded_procedures;
-extern HashTable<int> included_procedures;
-extern bool exclude_some_procedures;
-extern bool include_some_procedures;
-
-extern bool exclude_kernel_syms;
-extern bool exclude_library_syms;
-extern bool include_kernel_syms;
-extern bool include_library_syms;
-extern bool demangle;
-
-extern void Usage(const char *program);
-extern void ParseOptions(int argc, char **argv);
-extern void OptionsUsage();
-
-#endif  // PARSE_OPTIONS_H
diff --git a/emulator/qtools/post_trace.cpp b/emulator/qtools/post_trace.cpp
deleted file mode 100644
index becfc2b..0000000
--- a/emulator/qtools/post_trace.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-
-typedef struct MyStaticRec {
-  StaticRec bb;
-  uint32_t  *insns;
-} MyStaticRec;
-
-const int kNumPids = 32768;
-char usedPids[kNumPids];
-
-int main(int argc, char **argv) {
-  uint32_t insns[kMaxInsnPerBB];
-
-  if (argc != 2) {
-    fprintf(stderr, "Usage: %s trace_file\n", argv[0]);
-    exit(1);
-  }
-
-  char *trace_filename = argv[1];
-  TraceReaderBase *trace = new TraceReaderBase;
-  trace->SetPostProcessing(true);
-  trace->Open(trace_filename);
-
-  // Count the number of static basic blocks and instructions.
-  uint64_t num_static_bb = 0;
-  uint64_t num_static_insn = 0;
-  while (1) {
-    StaticRec static_rec;
-
-    if (trace->ReadStatic(&static_rec))
-      break;
-    if (static_rec.bb_num != num_static_bb) {
-      fprintf(stderr,
-              "Error: basic block numbers out of order; expected %lld, got %lld\n",
-              num_static_bb, static_rec.bb_num);
-      exit(1);
-    }
-    num_static_bb += 1;
-    num_static_insn += static_rec.num_insns;
-    trace->ReadStaticInsns(static_rec.num_insns, insns);
-  }
-  trace->Close();
-
-  // Allocate space for all of the static blocks
-  MyStaticRec *blocks = new MyStaticRec[num_static_bb];
-
-  // Read the static blocks again and save pointers to them
-  trace->Open(trace_filename);
-  for (uint32_t ii = 0; ii < num_static_bb; ++ii) {
-    trace->ReadStatic(&blocks[ii].bb);
-    uint32_t num_insns = blocks[ii].bb.num_insns;
-    if (num_insns > 0) {
-      blocks[ii].insns = new uint32_t[num_insns];
-      trace->ReadStaticInsns(num_insns, blocks[ii].insns);
-    }
-  }
-
-  // Check the last basic block.  If it contains a special undefined
-  // instruction, then truncate the basic block at that point.
-  uint32_t num_insns = blocks[num_static_bb - 1].bb.num_insns;
-  uint32_t *insn_ptr = blocks[num_static_bb - 1].insns;
-  for (uint32_t ii = 0; ii < num_insns; ++ii, ++insn_ptr) {
-    if (*insn_ptr == 0xe6c00110) {
-      uint32_t actual_num_insns = ii + 1;
-      blocks[num_static_bb - 1].bb.num_insns = actual_num_insns;
-      num_static_insn -= (num_insns - actual_num_insns);
-
-      // Write the changes back to the trace file
-      trace->TruncateLastBlock(actual_num_insns);
-      break;
-    }
-  }
-  TraceHeader *header = trace->GetHeader();
-  strcpy(header->ident, TRACE_IDENT);
-  header->num_static_bb = num_static_bb;
-  header->num_dynamic_bb = 0;
-  header->num_static_insn = num_static_insn;
-  header->num_dynamic_insn = 0;
-  trace->WriteHeader(header);
-
-  // Reopen the trace file in order to force the trace manager to reread
-  // the static blocks now that we have written that information to the
-  // header.
-  trace->Close();
-  trace->Open(trace_filename);
-
-  // Count the number of dynamic executions of basic blocks and instructions.
-  // Also keep track of which process ids are used.
-  uint64_t num_dynamic_bb = 0;
-  uint64_t num_dynamic_insn = 0;
-  while (1) {
-    BBEvent event;
-
-    if (trace->ReadBB(&event))
-      break;
-    if (event.bb_num >= num_static_bb) {
-      fprintf(stderr,
-              "Error: basic block number (%lld) too large (num blocks: %lld)\n",
-              event.bb_num, num_static_bb);
-      exit(1);
-    }
-    usedPids[event.pid] = 1;
-    num_dynamic_bb += 1;
-    num_dynamic_insn += event.num_insns;
-  }
-
-  // Count the number of process ids that are used and remember the first
-  // unused pid.
-  int numUsedPids = 0;
-  int unusedPid = -1;
-  for (int pid = 0; pid < kNumPids; pid++) {
-      if (usedPids[pid] == 1) {
-          numUsedPids += 1;
-      } else if (unusedPid == -1) {
-          unusedPid = pid;
-      }
-  }
-
-  // Rewrite the header with the dynamic counts
-  header->num_dynamic_bb = num_dynamic_bb;
-  header->num_dynamic_insn = num_dynamic_insn;
-  header->num_used_pids = numUsedPids;
-  header->first_unused_pid = unusedPid;
-  trace->WriteHeader(header);
-  trace->Close();
-
-  printf("Static basic blocks: %llu, Dynamic basic blocks: %llu\n",
-         num_static_bb, num_dynamic_bb);
-  printf("Static instructions: %llu, Dynamic instructions: %llu\n",
-         num_static_insn, num_dynamic_insn);
-
-  double elapsed_secs = header->elapsed_usecs / 1000000.0;
-  double insn_per_sec = 0;
-  if (elapsed_secs != 0)
-    insn_per_sec = num_dynamic_insn / elapsed_secs;
-  const char *suffix = "";
-  if (insn_per_sec >= 1000000) {
-    insn_per_sec /= 1000000.0;
-    suffix = "M";
-  } else if (insn_per_sec > 1000) {
-    insn_per_sec /= 1000.0;
-    suffix = "K";
-  }
-  printf("Elapsed seconds: %.2f, simulated instructions/sec: %.1f%s\n",
-         elapsed_secs, insn_per_sec, suffix);
-  return 0;
-}
diff --git a/emulator/qtools/profile_pid.cpp b/emulator/qtools/profile_pid.cpp
deleted file mode 100644
index 11acbf9..0000000
--- a/emulator/qtools/profile_pid.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <string.h>
-#include "trace_reader.h"
-#include "parse_options.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-// This function is called from quicksort to compare the cpu time
-// of processes and sort into decreasing order.
-int cmp_dec_cpu_time(const void *a, const void *b) {
-  ProcessState *proc1, *proc2;
-
-  proc1 = (ProcessState*)a;
-  proc2 = (ProcessState*)b;
-  if (proc1 == NULL) {
-    if (proc2 == NULL)
-      return 0;
-    return 1;
-  }
-  if (proc2 == NULL)
-    return -1;
-  if (proc1->cpu_time < proc2->cpu_time)
-    return 1;
-  if (proc1->cpu_time > proc2->cpu_time)
-    return -1;
-  // If the cpu_time times are the same, then sort into increasing
-  // order of pid.
-  return proc1->pid - proc2->pid;
-}
-
-void Usage(const char *program)
-{
-  fprintf(stderr, "Usage: %s [options] trace_file\n", program);
-  OptionsUsage();
-}
-
-int main(int argc, char **argv) {
-  // Parse the options
-  ParseOptions(argc, argv);
-  if (argc - optind != 1) {
-    Usage(argv[0]);
-    exit(1);
-  }
-
-  char *trace_filename = argv[optind];
-  TraceReader<> *trace = new TraceReader<>;
-  trace->Open(trace_filename);
-  trace->SetRoot(root);
-
-  while (1) {
-    BBEvent event, ignored;
-    symbol_type *dummy_sym;
-
-    if (GetNextValidEvent(trace, &event, &ignored, &dummy_sym))
-      break;
-  }
-
-  int num_procs;
-  ProcessState *processes = trace->GetProcesses(&num_procs);
-  qsort(processes, num_procs, sizeof(ProcessState), cmp_dec_cpu_time);
-
-  uint64_t total_time = 0;
-  for (int ii = 0; ii < num_procs; ++ii) {
-    total_time += processes[ii].cpu_time;
-  }
-
-  uint64_t sum_time = 0;
-  printf("  pid parent   cpu_time      %%      %% flags argv\n"); 
-  ProcessState *pstate = &processes[0];
-  for (int ii = 0; ii < num_procs; ++ii, ++pstate) {
-    sum_time += pstate->cpu_time;
-    double per = 100.0 * pstate->cpu_time / total_time;
-    double sum_per = 100.0 * sum_time / total_time;
-    const char *print_flags = "";
-    if ((pstate->flags & ProcessState::kCalledExec) == 0)
-      print_flags = "T";
-    if (pstate->name == NULL)
-      pstate->name = "";
-    printf("%5d  %5d %10llu %6.2f %6.2f %5s %s",
-           pstate->pid, pstate->parent_pid, pstate->cpu_time,
-           per, sum_per, print_flags, pstate->name);
-    for (int jj = 1; jj < pstate->argc; ++jj) {
-      printf(" %s", pstate->argv[jj]);
-    }
-    printf("\n");
-  }
-  delete trace;
-  return 0;
-}
diff --git a/emulator/qtools/profile_trace.cpp b/emulator/qtools/profile_trace.cpp
deleted file mode 100644
index 0b056cc..0000000
--- a/emulator/qtools/profile_trace.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-#include "parse_options.h"
-
-const int kMillion = 1000000;
-const int kMHz = 200 * kMillion;
-
-struct symbol {
-    int         count;      // number of times a function is executed
-    uint64_t    elapsed;    // elapsed time for this function
-};
-
-typedef TraceReader<symbol> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-static const uint32_t kOffsetThreshold = 0x100000;
-
-// This comparison function is called from qsort() to sort
-// symbols into decreasing elapsed time.
-int cmp_sym_elapsed(const void *a, const void *b) {
-    const symbol_type *syma, *symb;
-    uint64_t elapsed1, elapsed2;
-
-    syma = static_cast<symbol_type const *>(a);
-    symb = static_cast<symbol_type const *>(b);
-    elapsed1 = syma->elapsed;
-    elapsed2 = symb->elapsed;
-    if (elapsed1 < elapsed2)
-        return 1;
-    if (elapsed1 == elapsed2)
-        return strcmp(syma->name, symb->name);
-    return -1;
-}
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_file elf_file\n", program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv)
-{
-    ParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReader<symbol> *trace = new TraceReader<symbol>;
-    trace->Open(trace_filename);
-    trace->SetDemangle(demangle);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    symbol_type dummy;
-    dummy.count = 0;
-    dummy.elapsed = 0;
-    symbol_type *prev_sym = &dummy;
-    uint64_t prev_bb_time = 0;
-    while (1) {
-        symbol_type *sym;
-        BBEvent event;
-        BBEvent first_ignored_event;
-
-        bool eof = GetNextValidEvent(trace, &event, &first_ignored_event, &sym);
-
-        // Assign the elapsed time to the previous function symbol
-        uint64_t elapsed = 0;
-        if (first_ignored_event.time != 0)
-            elapsed = first_ignored_event.time - prev_bb_time;
-        else if (!eof)
-            elapsed = event.time - prev_bb_time;
-        prev_sym->elapsed += elapsed;
-
-        if (eof)
-            break;
-
-        prev_bb_time = event.time;
-        sym->count += 1;
-        prev_sym = sym;
-#if 0
-        printf("t%lld bb_num: %d, bb_addr: 0x%x func: %s, addr: 0x%x, count: %d\n",
-               bb_time, bb_num, bb_addr, sym->name, sym->addr, sym->count);
-#endif
-    }
-
-    int nsyms;
-    symbol_type *syms = trace->GetSymbols(&nsyms);
-
-    // Sort the symbols into decreasing order of elapsed time
-    qsort(syms, nsyms, sizeof(symbol_type), cmp_sym_elapsed);
-
-    // Add up all the cycles
-    uint64_t total = 0;
-    symbol_type *sym = syms;
-    for (int ii = 0; ii < nsyms; ++ii, ++sym) {
-        total += sym->elapsed;
-    }
-
-    double secs = 1.0 * total / kMHz;
-    printf("Total seconds: %.2f, total cycles: %lld, MHz: %d\n\n",
-           secs, total, kMHz / kMillion);
-
-    uint64_t sum = 0;
-    printf("Elapsed secs Elapsed cyc      %%      %%    Function\n");
-    sym = syms;
-    for (int ii = 0; ii < nsyms; ++ii, ++sym) {
-        if (sym->elapsed == 0)
-            break;
-        sum += sym->elapsed;
-        double per = 100.0 * sym->elapsed / total;
-        double sum_per = 100.0 * sum / total;
-        double secs = 1.0 * sym->elapsed / kMHz;
-        const char *ksym = " ";
-        if (sym->region->flags & region_type::kIsKernelRegion)
-            ksym = "k";
-        printf("%12.2f %11lld %6.2f %6.2f  %s %s\n",
-               secs, sym->elapsed, per, sum_per, ksym, sym->name);
-    }
-    delete[] syms;
-    delete trace;
-
-    return 0;
-}
diff --git a/emulator/qtools/q2dm.cpp b/emulator/qtools/q2dm.cpp
deleted file mode 100644
index 74dbaeb..0000000
--- a/emulator/qtools/q2dm.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "bitvector.h"
-#include "parse_options.h"
-#include "dmtrace.h"
-#include "armdis.h"
-
-struct symbol {
-    uint32_t id;
-};
-
-typedef TraceReader<symbol> TraceReaderType;
-
-#include "parse_options-inl.h"
-#include "callstack.h"
-
-DmTrace *dmtrace;
-
-class MyFrame : public StackFrame<symbol_type> {
-  public:
-    void push(int stackLevel, uint64_t time, CallStackBase *base);
-    void pop(int stackLevel, uint64_t time, CallStackBase *base);
-};
-
-typedef CallStack<MyFrame> CallStackType;
-
-static const int kNumStackFrames = 500;
-static const int kMaxThreads = (32 * 1024);
-uint64_t thread_time[kMaxThreads];
-
-class FunctionStack {
-  public:
-    FunctionStack() {
-        top = 0;
-    }
-    void push(symbol_type *sym) {
-        if (top >= kNumStackFrames)
-            return;
-        frames[top] = sym;
-        top += 1;
-    }
-
-    symbol_type* pop() {
-        if (top <= 0) {
-            return NULL;
-        }
-        top -= 1;
-        return frames[top];
-    }
-
-    void showStack() {
-        fprintf(stderr, "top %d\n", top);
-        for (int ii = 0; ii < top; ii++) {
-            fprintf(stderr, "  %d: %s\n", ii, frames[ii]->name);
-        }
-    }
-
-  private:
-    int top;
-    symbol_type *frames[kNumStackFrames];
-};
-
-FunctionStack *dmtrace_stack[kMaxThreads];
-
-void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
-{
-    int pid = base->getId();
-    CallStackType *stack = (CallStackType *) base;
-
-#if 0
-    fprintf(stderr, "native push t %llu p %d s %d fid %d 0x%x %s\n",
-            stack->getGlobalTime(time), pid, stackLevel,
-            function->id, function->addr, function->name);
-#endif
-
-    FunctionStack *fstack = dmtrace_stack[pid];
-    if (fstack == NULL) {
-        fstack = new FunctionStack();
-        dmtrace_stack[pid] = fstack;
-    }
-
-    fstack->push(function);
-    thread_time[pid] = time;
-    dmtrace->addFunctionEntry(function->id, time, pid);
-}
-
-void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
-{
-    int pid = base->getId();
-    CallStackType *stack = (CallStackType *) base;
-
-#if 0
-    fprintf(stderr, "native pop  t %llu p %d s %d fid %d 0x%x %s\n",
-            stack->getGlobalTime(time), pid, stackLevel,
-            function->id, function->addr, function->name);
-#endif
-
-    FunctionStack *fstack = dmtrace_stack[pid];
-    if (fstack == NULL) {
-        fstack = new FunctionStack();
-        dmtrace_stack[pid] = fstack;
-    }
-
-    symbol_type *sym = fstack->pop();
-    if (sym != NULL && sym != function) {
-        fprintf(stderr, "Error: q2dm function mismatch at time %llu pid %d sym %s\n",
-                stack->getGlobalTime(time), pid, sym->name);
-        fstack->showStack();
-        exit(1);
-    }
-
-    thread_time[pid] = time;
-    dmtrace->addFunctionExit(function->id, time, pid);
-}
-
-uint32_t nextFunctionId = 4;
-CallStackType *stacks[kMaxThreads];
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_name elf_file dmtrace_name\n",
-            program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv)
-{
-    bool useKernelStack = true;
-
-    ParseOptions(argc, argv);
-    if (argc - optind != 3) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *qemu_trace_file = argv[optind++];
-    char *elf_file = argv[optind++];
-    char *dmtrace_file = argv[optind++];
-    TraceReaderType *trace = new TraceReaderType;
-    trace->Open(qemu_trace_file);
-    trace->SetDemangle(demangle);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-    TraceHeader *qheader = trace->GetHeader();
-    uint64_t startTime = qheader->start_sec;
-    startTime = (startTime << 32) | qheader->start_usec;
-    int kernelPid = qheader->first_unused_pid;
-
-    dmtrace = new DmTrace;
-    dmtrace->open(dmtrace_file, startTime);
-
-    bool inKernel = false;
-    CallStackType *kernelStack = NULL;
-    if (useKernelStack) {
-        // Create a fake kernel thread stack where we will put all the kernel
-        // code.
-        kernelStack = new CallStackType(kernelPid, kNumStackFrames, trace);
-        dmtrace->addThread(kernelPid, "(kernel)");
-    }
-
-    CallStackType *prevStack = NULL;
-    BBEvent event;
-    while (1) {
-        BBEvent ignored;
-        symbol_type *function;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &function))
-            break;
-        if (event.bb_num == 0)
-            break;
-#if 0
-        fprintf(stderr, "event t %llu p %d %s\n",
-                event.time, event.pid, function->name);
-#endif
-
-        CallStackType *pStack;
-        if (useKernelStack) {
-            uint32_t flags = function->region->flags;
-            uint32_t region_mask = region_type::kIsKernelRegion
-                    | region_type::kIsUserMappedRegion;
-            if ((flags & region_mask) == region_type::kIsKernelRegion) {
-                // Use the kernel stack
-                pStack = kernelStack;
-                inKernel = true;
-            } else {
-                // If we were just in the kernel then pop off all of the
-                // stack frames for the kernel thread.
-                if (inKernel == true) {
-                    inKernel = false;
-                    kernelStack->popAll(event.time);
-                }
-                
-                // Get the stack for the current thread
-                pStack = stacks[event.pid];
-            }
-        } else {
-            // Get the stack for the current thread
-            pStack = stacks[event.pid];
-        }
-
-        // If the stack does not exist, then allocate a new one.
-        if (pStack == NULL) {
-            pStack = new CallStackType(event.pid, kNumStackFrames, trace);
-            stacks[event.pid] = pStack;
-            const char *name = trace->GetProcessName(event.pid);
-            dmtrace->addThread(event.pid, name);
-        }
-
-        if (prevStack != pStack) {
-            pStack->threadStart(event.time);
-            if (prevStack)
-                prevStack->threadStop(event.time);
-        }
-        prevStack = pStack;
-
-        // If we have never seen this function before, then add it to the
-        // list of known functions.
-        if (function->id == 0) {
-            function->id = nextFunctionId;
-            nextFunctionId += 4;
-            uint32_t flags = function->region->flags;
-            const char *name = function->name;
-            if (flags & region_type::kIsKernelRegion) {
-                // To distinguish kernel function names from user library
-                // names, add a marker to the name.
-                int len = strlen(name) + strlen(" [kernel]") + 1;
-                char *kernelName = new char[len];
-                strcpy(kernelName, name);
-                strcat(kernelName, " [kernel]");
-                name = kernelName;
-            }
-            dmtrace->parseAndAddFunction(function->id, name);
-        }
-
-        // Update the stack
-        pStack->updateStack(&event, function);
-    }
-
-    if (prevStack == NULL) {
-        fprintf(stderr, "Error: no events in trace.\n");
-        exit(1);
-    }
-    prevStack->threadStop(event.time);
-    for (int ii = 0; ii < kMaxThreads; ++ii) {
-        if (stacks[ii]) {
-            stacks[ii]->threadStart(event.time);
-            stacks[ii]->popAll(event.time);
-        }
-    }
-    if (useKernelStack) {
-        kernelStack->popAll(event.time);
-    }
-
-    // Read the pid events to find the names of the processes
-    while (1) {
-        PidEvent pid_event;
-        if (trace->ReadPidEvent(&pid_event))
-            break;
-        if (pid_event.rec_type == kPidName) {
-            dmtrace->updateName(pid_event.pid, pid_event.path);
-        }
-    }
-
-    dmtrace->close();
-    delete dmtrace;
-    delete trace;
-    return 0;
-}
diff --git a/emulator/qtools/q2g.cpp b/emulator/qtools/q2g.cpp
deleted file mode 100644
index 6b2ae92..0000000
--- a/emulator/qtools/q2g.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "gtrace.h"
-#include "bitvector.h"
-#include "parse_options.h"
-
-struct symbol {
-  int		filenum;	// the file number (for gtrace)
-  int		procnum;	// the procedure number (for gtrace)
-};
-
-typedef TraceReader<symbol> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-const int kMaxProcNum = 4095;
-int next_filenum = 1;
-int next_procnum = 1;
-
-void Usage(const char *program)
-{
-  fprintf(stderr, "Usage: %s [options] trace_file elf_file gtrace_file\n",
-          program);
-  OptionsUsage();
-}
-
-int main(int argc, char **argv)
-{
-  ParseOptions(argc, argv);
-  if (argc - optind != 3) {
-    Usage(argv[0]);
-    exit(1);
-  }
-
-  char *qemu_trace_file = argv[optind++];
-  char *elf_file = argv[optind++];
-  char *gtrace_file = argv[optind++];
-  TraceReader<symbol> *trace = new TraceReader<symbol>;
-  trace->Open(qemu_trace_file);
-  trace->ReadKernelSymbols(elf_file);
-  trace->SetRoot(root);
-  TraceHeader *qheader = trace->GetHeader();
-
-  // Get the first valid event to get the process id for the gtrace header.
-  BBEvent event;
-  BBEvent ignored;
-  symbol_type *sym;
-  if (GetNextValidEvent(trace, &event, &ignored, &sym))
-    return 0;
-
-  Gtrace *gtrace = new Gtrace;
-  gtrace->Open(gtrace_file, qheader->pdate, qheader->ptime);
-  gtrace->WriteFirstHeader(qheader->start_sec, event.pid);
-
-  symbol_type *prev_sym = NULL;
-  bool eof = false;
-  while (!eof) {
-    if (sym != prev_sym) {
-      // This procedure is different from the previous procedure.
-
-      // If we have never seen this symbol before, then add it to the
-      // list of known procedures.
-      if (sym->filenum == 0) {
-        sym->filenum = next_filenum;
-        sym->procnum = next_procnum;
-        gtrace->AddProcedure(sym->filenum, sym->procnum, sym->name);
-        next_procnum += 1;
-        if (next_procnum > kMaxProcNum) {
-          next_filenum += 1;
-          next_procnum = 1;
-        }
-      }
-
-      // If we haven't yet recorded the procedure exit for the previous
-      // procedure, then do it now.
-      if (prev_sym) {
-        gtrace->AddProcExit(prev_sym->filenum, prev_sym->procnum, event.time,
-                            event.pid);
-      }
-
-      // If this is not the terminating record, then record a procedure
-      // entry.
-      if (event.bb_num != 0) {
-        gtrace->AddProcEntry(sym->filenum, sym->procnum, event.time, event.pid);
-        prev_sym = sym;
-      }
-    }
-
-    eof = GetNextValidEvent(trace, &event, &ignored, &sym);
-    if (ignored.time != 0 && prev_sym) {
-      // We read an event that we are ignoring.
-      // If we haven't already recorded a procedure exit, then do so.
-      gtrace->AddProcExit(prev_sym->filenum, prev_sym->procnum, ignored.time,
-                          ignored.pid);
-      prev_sym = NULL;
-    }
-  }
-
-  delete gtrace;
-  delete trace;
-  return 0;
-}
diff --git a/emulator/qtools/read_addr.cpp b/emulator/qtools/read_addr.cpp
deleted file mode 100644
index 1c8c20f..0000000
--- a/emulator/qtools/read_addr.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-
-int main(int argc, char **argv) {
-  if (argc != 2) {
-    fprintf(stderr, "Usage: %s trace_file\n", argv[0]);
-    exit(1);
-  }
-
-  char *trace_filename = argv[1];
-  TraceReaderBase *trace = new TraceReaderBase;
-  trace->Open(trace_filename);
-
-  while (1) {
-    uint64_t time;
-    uint32_t addr;
-    int flags;
-
-    if (trace->ReadAddr(&time, &addr, &flags))
-      break;
-    const char *op = "ld";
-    if (flags == 1)
-        op = "st";
-    printf("%lld 0x%08x %s\n", time, addr, op);
-  }
-  return 0;
-}
diff --git a/emulator/qtools/read_elf.cpp b/emulator/qtools/read_elf.cpp
deleted file mode 100644
index 1d1a74a..0000000
--- a/emulator/qtools/read_elf.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/*************************************************************************
-    Copyright (C) 2002,2003,2004,2005 Wei Qin
-    See file COPYING for more information.
-
-    This program is free software; you can redistribute it and/or modify    
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*************************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include "read_elf.h"
-
-#define SwapHalf(a) (((a & 0x00ff) << 8) | ((a & 0xff00) >> 8))
-#define SwapWord(a) (((a & 0xff000000) >> 24) | ((a & 0x00ff0000) >> 8) | ((a & 0x0000ff00) << 8) | ((a & 0x000000ff) << 24))
-#define SwapAddr(a) SwapWord(a)
-#define SwapOff(a) SwapWord(a)
-#define SwapSection(a) SwapHalf(a)
-
-int LittleEndian()
-{
-  Elf32_Word a = 0x01020304;
-  return *(char *) &a == 0x04;
-}
-
-void SwapElfHeader(Elf32_Ehdr *hdr)
-{
-  hdr->e_type = SwapHalf(hdr->e_type);
-  hdr->e_machine = SwapHalf(hdr->e_machine);
-  hdr->e_version = SwapWord(hdr->e_version);
-  hdr->e_entry = SwapAddr(hdr->e_entry);
-  hdr->e_phoff = SwapOff(hdr->e_phoff);
-  hdr->e_shoff = SwapOff(hdr->e_shoff);
-  hdr->e_flags = SwapWord(hdr->e_flags);
-  hdr->e_ehsize = SwapHalf(hdr->e_ehsize);
-  hdr->e_phentsize = SwapHalf(hdr->e_phentsize);
-  hdr->e_phnum = SwapHalf(hdr->e_phnum);
-  hdr->e_shentsize = SwapHalf(hdr->e_shentsize);
-  hdr->e_shnum = SwapHalf(hdr->e_shnum);
-  hdr->e_shstrndx = SwapHalf(hdr->e_shstrndx);
-}
-
-void SwapSectionHeader(Elf32_Shdr *shdr)
-{
-  shdr->sh_name = SwapWord(shdr->sh_name);
-  shdr->sh_type = SwapWord(shdr->sh_type);
-  shdr->sh_flags = SwapWord(shdr->sh_flags);
-  shdr->sh_addr = SwapAddr(shdr->sh_addr);
-  shdr->sh_offset = SwapOff(shdr->sh_offset);
-  shdr->sh_size = SwapWord(shdr->sh_size);
-  shdr->sh_link = SwapWord(shdr->sh_link);
-  shdr->sh_info = SwapWord(shdr->sh_info);
-  shdr->sh_addralign = SwapWord(shdr->sh_addralign);
-  shdr->sh_entsize = SwapWord(shdr->sh_entsize);
-}
-
-void SwapElfSymbol(Elf32_Sym *sym)
-{
-    sym->st_name = SwapWord(sym->st_name);
-    sym->st_value = SwapAddr(sym->st_value);
-    sym->st_size = SwapWord(sym->st_size);
-    sym->st_shndx = SwapSection(sym->st_shndx);
-}
-
-void AdjustElfHeader(Elf32_Ehdr *hdr)
-{
-  switch(hdr->e_ident[EI_DATA])
-  {
-    case ELFDATA2LSB:
-      if (!LittleEndian())
-        SwapElfHeader(hdr);
-      break;
-    case ELFDATA2MSB:
-      if (LittleEndian())
-        SwapElfHeader(hdr);
-      break;
-  }
-}
-
-void AdjustSectionHeader(Elf32_Ehdr *hdr, Elf32_Shdr *shdr)
-{
-  switch(hdr->e_ident[EI_DATA])
-  {
-    case ELFDATA2LSB:
-      if (!LittleEndian())
-        SwapSectionHeader(shdr);
-      break;
-    case ELFDATA2MSB:
-      if (LittleEndian())
-        SwapSectionHeader(shdr);
-      break;
-  }
-}
-
-void AdjustElfSymbols(Elf32_Ehdr *hdr, Elf32_Sym *elf_symbols, int num_entries)
-{
-    if (hdr->e_ident[EI_DATA] == ELFDATA2LSB && LittleEndian())
-        return;
-    if (hdr->e_ident[EI_DATA] == ELFDATA2MSB && !LittleEndian())
-        return;
-    for (int ii = 0; ii < num_entries; ++ii) {
-        SwapElfSymbol(&elf_symbols[ii]);
-    }
-}
-
-Elf32_Ehdr *ReadElfHeader(FILE *fobj)
-{
-  Elf32_Ehdr *hdr = new Elf32_Ehdr;
-  int rval = fread(hdr, sizeof(Elf32_Ehdr), 1, fobj);
-  if (rval != 1) {
-    delete hdr;
-    return NULL;
-  }
-  if (hdr->e_ident[EI_MAG0] != 0x7f || hdr->e_ident[EI_MAG1] != 'E' ||
-      hdr->e_ident[EI_MAG2] != 'L' || hdr->e_ident[EI_MAG3] != 'F') {
-    delete hdr;
-    return NULL;
-  }
-  AdjustElfHeader(hdr);
-  return hdr;
-}
-
-Elf32_Shdr *ReadSectionHeaders(Elf32_Ehdr *hdr, FILE *f)
-{
-  int i;
-  unsigned long sz = hdr->e_shnum * hdr->e_shentsize;
-  assert(sizeof(Elf32_Shdr) == hdr->e_shentsize);
-  Elf32_Shdr *shdr = new Elf32_Shdr[hdr->e_shnum];
-
-  if (fseek(f, hdr->e_shoff, SEEK_SET) != 0)
-  {
-    delete[] shdr;
-    return NULL;
-  }
-  if (fread(shdr, sz, 1, f) != 1)
-  {
-    delete[] shdr;
-    return NULL;
-  }
-
-  for(i = 0; i < hdr->e_shnum; i++)
-    AdjustSectionHeader(hdr, shdr + i);
-
-  return shdr;
-}
-
-
-char *ReadStringTable(Elf32_Ehdr *hdr, Elf32_Shdr *shdr_table, FILE *f)
-{
-  Elf32_Shdr *shdr = shdr_table + hdr->e_shstrndx;
-  char *string_table;
-
-  string_table = new char[shdr->sh_size];
-  fseek(f, shdr->sh_offset, SEEK_SET);
-  fread(string_table, shdr->sh_size, 1, f);
-
-  return string_table;
-}
-
-int ReadSection(Elf32_Shdr *shdr, void *buffer, FILE *f)
-{
-  if (fseek(f, shdr->sh_offset, SEEK_SET) != 0)
-    return -1;
-  if (fread(buffer, shdr->sh_size, 1, f) != 1)
-    return -1;
-  return 0;
-}
-
-char *GetSymbolName(Elf32_Half index, char *string_table)
-{
-  return string_table + index;
-}
-
-Elf32_Shdr *FindSymbolTableSection(Elf32_Ehdr *hdr,
-                                   Elf32_Shdr *shdr,
-                                   char *string_table)
-{
-  for(int ii = 0; ii < hdr->e_shnum; ii++) {
-    if (shdr[ii].sh_type == SHT_SYMTAB &&
-       strcmp(GetSymbolName(shdr[ii].sh_name, string_table),
-              ".symtab") == 0)
-    {
-      return &shdr[ii];
-    }
-  }
-  return NULL;
-}
-
-Elf32_Shdr *FindSymbolStringTableSection(Elf32_Ehdr *hdr,
-                                         Elf32_Shdr *shdr,
-                                         char *string_table)
-{
-  for(int ii = 0; ii < hdr->e_shnum; ii++) {
-    if (shdr[ii].sh_type == SHT_STRTAB &&
-       strcmp(GetSymbolName(shdr[ii].sh_name, string_table),
-              ".strtab") == 0)
-    {
-      return &shdr[ii];
-    }
-  }
-  return NULL;
-}
diff --git a/emulator/qtools/read_elf.h b/emulator/qtools/read_elf.h
deleted file mode 100644
index 72266c3..0000000
--- a/emulator/qtools/read_elf.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef READ_ELF_H
-#define READ_ELF_H
-
-#include <stdio.h>
-#include <elf.h>
-
-Elf32_Ehdr *ReadElfHeader(FILE *fobj);
-Elf32_Shdr *ReadSectionHeaders(Elf32_Ehdr *hdr, FILE *fobj);
-char *ReadStringTable(Elf32_Ehdr *hdr, Elf32_Shdr *shdr, FILE *fobj);
-Elf32_Shdr *FindSymbolTableSection(Elf32_Ehdr *hdr,
-                                   Elf32_Shdr *shdr,
-                                   char *string_table);
-Elf32_Shdr *FindSymbolStringTableSection(Elf32_Ehdr *hdr,
-                                         Elf32_Shdr *shdr,
-                                         char *string_table);
-int ReadSection(Elf32_Shdr *shdr, void *buffer, FILE *f);
-void AdjustElfSymbols(Elf32_Ehdr *hdr, Elf32_Sym *elf_symbols,
-                      int num_entries);
-
-#endif /* READ_ELF_H */
diff --git a/emulator/qtools/read_method.cpp b/emulator/qtools/read_method.cpp
deleted file mode 100644
index 6aa0c1a..0000000
--- a/emulator/qtools/read_method.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-#include "parse_options.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-struct frame {
-    uint64_t    time;
-    uint32_t    addr;
-    const char  *name;
-    bool        isNative;
-
-    frame(uint64_t time, uint32_t addr, const char *name, bool isNative) {
-        this->time = time;
-        this->addr = addr;
-        this->name = name;
-        this->isNative = isNative;
-    }
-};
-
-class Stack {
-    static const int kMaxFrames = 1000;
-    int top;
-    frame *frames[kMaxFrames];
-
-public:
-    Stack() {
-        top = 0;
-    }
-
-    void        push(frame *pframe);
-    frame*      pop();
-    void        dump();
-};
-
-void Stack::push(frame *pframe) {
-    if (top == kMaxFrames) {
-        fprintf(stderr, "Error: stack overflow\n");
-        exit(1);
-    }
-    frames[top] = pframe;
-    top += 1;
-}
-
-frame *Stack::pop() {
-    if (top <= 0)
-        return NULL;
-    top -= 1;
-    return frames[top];
-}
-
-void Stack::dump() {
-    frame *pframe;
-
-    for (int ii = 0; ii < top; ii++) {
-        pframe = frames[ii];
-        const char *native = pframe->isNative ? "n" : " ";
-        printf(" %s %d: %llu 0x%x %s\n",
-               native, ii, pframe->time, pframe->addr,
-               pframe->name == NULL ? "" : pframe->name);
-    }
-}
-
-static const int kMaxThreads = (32 * 1024);
-Stack *stacks[kMaxThreads];
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
-            program);
-    OptionsUsage();
-}
-
-int main(int argc, char **argv) {
-    ParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *qemu_trace_file = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReaderType *trace = new TraceReaderType;
-    trace->Open(qemu_trace_file);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    while (1) {
-        MethodRec method_record;
-        symbol_type *sym;
-        TraceReaderType::ProcessState *proc;
-        frame *pframe;
-
-        if (trace->ReadMethodSymbol(&method_record, &sym, &proc))
-            break;
-
-        if (!IsValidPid(proc->pid))
-            continue;
-
-        if (sym != NULL) {
-            printf("%lld p %d 0x%x %d %s\n",
-                   method_record.time, proc->pid, method_record.addr,
-                   method_record.flags, sym->name);
-        } else {
-            printf("%lld p %d 0x%x %d\n",
-                   method_record.time, proc->pid, method_record.addr,
-                   method_record.flags);
-        }
-
-        // Get the stack for the current thread
-        Stack *pStack = stacks[proc->pid];
-
-        // If the stack does not exist, then allocate a new one.
-        if (pStack == NULL) {
-            pStack = new Stack();
-            stacks[proc->pid] = pStack;
-        }
-
-        int flags = method_record.flags;
-        if (flags == kMethodEnter || flags == kNativeEnter) {
-            pframe = new frame(method_record.time, method_record.addr,
-                               sym == NULL ? NULL: sym->name,
-                               method_record.flags == kNativeEnter);
-            pStack->push(pframe);
-        } else {
-            pframe = pStack->pop();
-            delete pframe;
-        }
-        pStack->dump();
-    }
-    return 0;
-}
diff --git a/emulator/qtools/read_pid.cpp b/emulator/qtools/read_pid.cpp
deleted file mode 100644
index a2d69d4..0000000
--- a/emulator/qtools/read_pid.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include "trace_reader.h"
-
-int main(int argc, char **argv) {
-  if (argc != 2) {
-    fprintf(stderr, "Usage: %s trace_file\n", argv[0]);
-    exit(1);
-  }
-
-  char *trace_filename = argv[1];
-  TraceReaderBase *trace = new TraceReaderBase;
-  trace->Open(trace_filename);
-
-  while (1) {
-    PidEvent event;
-    if (trace->ReadPidEvent(&event))
-      break;
-    switch (event.rec_type) {
-      case kPidFork:
-        printf("t%lld fork tgid %d pid %d\n", event.time, event.tgid, event.pid);
-        break;
-      case kPidClone:
-        printf("t%lld clone tgid %d pid %d\n", event.time, event.tgid, event.pid);
-        break;
-      case kPidSwitch:
-        printf("t%lld switch %d\n", event.time, event.pid);
-        break;
-      case kPidExit:
-        printf("t%lld exit %d\n", event.time, event.pid);
-        break;
-      case kPidMmap:
-        printf("t%lld mmap %08x - %08x, offset %08x '%s'\n",
-               event.time, event.vstart, event.vend, event.offset, event.path);
-        delete[] event.path;
-        break;
-      case kPidMunmap:
-        printf("t%lld munmap %08x - %08x\n",
-               event.time, event.vstart, event.vend);
-        break;
-      case kPidSymbolAdd:
-        printf("t%lld add sym %08x '%s'\n",
-               event.time, event.vstart, event.path);
-        delete[] event.path;
-        break;
-      case kPidSymbolRemove:
-        printf("t%lld remove %08x\n", event.time, event.vstart);
-        break;
-      case kPidExec:
-        printf("t%lld argc: %d\n", event.time, event.argc);
-        for (int ii = 0; ii < event.argc; ++ii) {
-          printf("  argv[%d]: %s\n", ii, event.argv[ii]);
-          delete[] event.argv[ii];
-        }
-        delete[] event.argv;
-        break;
-      case kPidKthreadName:
-        printf("t%lld kthread tgid %d pid %d %s\n",
-               event.time, event.tgid, event.pid, event.path);
-        delete[] event.path;
-        break;
-      case kPidName:
-        printf("t%lld name %d %s\n",
-               event.time, event.pid, event.path);
-        delete[] event.path;
-        break;
-    }
-  }
-  return 0;
-}
diff --git a/emulator/qtools/read_trace.cpp b/emulator/qtools/read_trace.cpp
deleted file mode 100644
index fb4917c..0000000
--- a/emulator/qtools/read_trace.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "armdis.h"
-#include "parse_options.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-
-static const uint32_t kOffsetThreshold = 0x100000;
-static uint64_t startTime = 0;
-
-void Usage(const char *program)
-{
-    fprintf(stderr,
-            "Usage: %s [options] [-- -s start_time] trace_file elf_file\n",
-            program);
-    OptionsUsage();
-}
-
-
-bool localParseOptions(int argc, char **argv)
-{
-    bool err = false;
-    while (!err) {
-        int opt = getopt(argc, argv, "+s:");
-        if (opt == -1)
-            break;
-        switch (opt) {
-        case 's':
-            startTime = strtoull(optarg, NULL, 0);
-            break;
-        default:
-            err = true;
-            break;
-        }
-    }
-    return err;
-}
-
-int main(int argc, char **argv) {
-    // Parse the options
-    ParseOptions(argc, argv);
-    localParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *trace_filename = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReader<> *trace = new TraceReader<>;
-    trace->Open(trace_filename);
-    trace->SetDemangle(demangle);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    while (1) {
-        symbol_type *sym;
-        char buf[1024];
-        BBEvent event;
-        BBEvent ignored;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &sym))
-            break;
-#if 0
-        fprintf(stderr, "t%llu bb %lld %d\n",
-                event.time, event.bb_num, event.num_insns);
-#endif
-
-        uint32_t *insns = event.insns;
-        uint32_t addr = event.bb_addr;
-        uint32_t offset = addr - sym->addr - sym->region->base_addr;
-        symbol_type *vm_sym = sym->vm_sym;
-        const char *vm_name = NULL;
-        if (vm_sym != NULL) {
-            vm_name = vm_sym->name;
-            offset = addr - vm_sym->addr - vm_sym->region->base_addr;
-        }
-#if 0
-        if (strcmp(sym->name, "(unknown)") == 0 || offset > kOffsetThreshold) {
-            ProcessState *process = trace->GetCurrentProcess();
-            ProcessState *manager = process->addr_manager;
-            for (int ii = 0; ii < manager->nregions; ++ii) {
-                printf("  %2d: %08x - %08x base: %08x offset: %u nsyms: %4d flags: 0x%x %s\n",
-                       ii,
-                       manager->regions[ii]->vstart,
-                       manager->regions[ii]->vend,
-                       manager->regions[ii]->base_addr,
-                       manager->regions[ii]->file_offset,
-                       manager->regions[ii]->nsymbols,
-                       manager->regions[ii]->flags,
-                       manager->regions[ii]->path);
-                int nsymbols = manager->regions[ii]->nsymbols;
-                for (int jj = 0; jj < 10 && jj < nsymbols; ++jj) {
-                    printf("    %08x %s\n",
-                           manager->regions[ii]->symbols[jj].addr,
-                           manager->regions[ii]->symbols[jj].name);
-                }
-            }
-        }
-#endif
-#if 1
-        for (int ii = 0; ii < event.num_insns; ++ii) {
-            uint64_t sim_time = trace->ReadInsnTime(event.time);
-            if (sim_time < startTime)
-                continue;
-
-            uint32_t insn = insns[ii];
-            char *disasm;
-            int bytes;
-            if (vm_name != NULL) {
-                sprintf(buf, "%s+%02x: %s", vm_name, offset, sym->name);
-            } else {
-                sprintf(buf, "%s+%02x", sym->name, offset);
-            }
-
-            if (insn_is_thumb(insn)) {
-                bytes = 2;
-                insn = insn_unwrap_thumb(insn);
-
-                // thumb_pair is true if this is the first of a pair of
-                // thumb instructions (BL or BLX).
-                bool thumb_pair = ((insn & 0xf800) == 0xf000);
-
-                // Get the next thumb instruction (if any) because we may need
-                // it for the case where insn is BL or BLX.
-                uint32_t insn2 = 0;
-                if (thumb_pair && (ii + 1 < event.num_insns)) {
-                    insn2 = insns[ii + 1];
-                    insn2 = insn_unwrap_thumb(insn2);
-                    bytes = 4;
-                    ii += 1;
-                }
-                disasm = disasm_insn_thumb(addr, insn, insn2, NULL);
-                if (thumb_pair) {
-                    printf("%llu p%-4d %08x %04x %04x %-30s %s\n",
-                           sim_time, event.pid, addr, insn, insn2, buf, disasm);
-                } else {
-                    printf("%llu p%-4d %08x     %04x %-30s %s\n",
-                           sim_time, event.pid, addr, insn, buf, disasm);
-                }
-            } else {
-                bytes = 4;
-                disasm = Arm::disasm(addr, insn, NULL);
-                printf("%llu p%-4d %08x %08x %-30s %s\n",
-                       sim_time, event.pid, addr, insn, buf, disasm);
-            }
-            //printf("t%llu \t%08x\n", sim_time, addr);
-            addr += bytes;
-            offset += bytes;
-        }
-#endif
-#if 0
-        assert(offset < kOffsetThreshold);
-#endif
-    }
-
-    delete trace;
-    return 0;
-}
diff --git a/emulator/qtools/stack_dump.cpp b/emulator/qtools/stack_dump.cpp
deleted file mode 100644
index f685cd0..0000000
--- a/emulator/qtools/stack_dump.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "trace_reader.h"
-#include "bitvector.h"
-#include "parse_options.h"
-#include "armdis.h"
-
-typedef TraceReader<> TraceReaderType;
-
-#include "parse_options-inl.h"
-#include "callstack.h"
-
-static uint64_t debugTime;
-static uint64_t dumpTime = 0;
-
-class MyFrame : public StackFrame<symbol_type> {
-  public:
-    void    push(int stackLevel, uint64_t time, CallStackBase *base);
-    void    pop(int stackLevel, uint64_t time, CallStackBase *base);
-    void    getFrameType(char *type);
-};
-
-typedef CallStack<MyFrame> CallStackType;
-
-void MyFrame::getFrameType(char *type)
-{
-    strcpy(type, "----");
-    if (flags & kCausedException)
-        type[0] = 'e';
-    if (flags & kInterpreted)
-        type[1] = 'm';
-    if (function->region->flags & region_type::kIsKernelRegion)
-        type[2] = 'k';
-    if (function->flags & symbol_type::kIsVectorTable)
-        type[3] = 'v';
-}
-
-void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
-{
-    char type[5];
-
-    if (dumpTime > 0)
-        return;
-
-    getFrameType(type);
-    printf("%llu en thr %d %s %3d", time, base->getId(), type, stackLevel);
-    for (int ii = 0; ii < stackLevel; ++ii)
-        printf(".");
-    printf(" 0x%08x %s\n", addr, function->name);
-}
-
-void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
-{
-    char type[5];
-
-    if (dumpTime > 0)
-        return;
-
-    getFrameType(type);
-    printf("%llu x  thr %d %s %3d", time, base->getId(), type, stackLevel);
-    for (int ii = 0; ii < stackLevel; ++ii)
-        printf(".");
-    printf(" 0x%08x %s\n", addr, function->name);
-}
-
-static const int kNumStackFrames = 500;
-static const int kMaxThreads = (32 * 1024);
-CallStackType *stacks[kMaxThreads];
-
-void Usage(const char *program)
-{
-    fprintf(stderr, "Usage: %s [options] [-- -d dumpTime] trace_name elf_file\n",
-            program);
-    OptionsUsage();
-}
-
-bool localParseOptions(int argc, char **argv)
-{
-    bool err = false;
-    while (!err) {
-        int opt = getopt(argc, argv, "+d:");
-        if (opt == -1)
-            break;
-        switch (opt) {
-        case 'd':
-            dumpTime = strtoull(optarg, NULL, 0);
-            break;
-        default:
-            err = true;
-            break;
-        }
-    }
-    return err;
-}
-
-int main(int argc, char **argv)
-{
-    ParseOptions(argc, argv);
-    localParseOptions(argc, argv);
-    if (argc - optind != 2) {
-        Usage(argv[0]);
-        exit(1);
-    }
-
-    char *qemu_trace_file = argv[optind++];
-    char *elf_file = argv[optind++];
-    TraceReaderType *trace = new TraceReaderType;
-    trace->Open(qemu_trace_file);
-    trace->ReadKernelSymbols(elf_file);
-    trace->SetRoot(root);
-
-    BBEvent event;
-    while (1) {
-        BBEvent ignored;
-        symbol_type *function;
-
-        if (GetNextValidEvent(trace, &event, &ignored, &function))
-            break;
-        if (event.bb_num == 0)
-            break;
-
-        // Get the stack for the current thread
-        CallStackType *pStack = stacks[event.pid];
-
-        // If the stack does not exist, then allocate a new one.
-        if (pStack == NULL) {
-            pStack = new CallStackType(event.pid, kNumStackFrames, trace);
-            stacks[event.pid] = pStack;
-        }
-        if (debugTime != 0 && event.time >= debugTime)
-            printf("debug time: %lld\n", debugTime);
-
-        // Update the stack
-        pStack->updateStack(&event, function);
-
-        // If the user requested a stack dump at a certain time,
-        // and we are at that time, then dump the stack and exit.
-        if (dumpTime > 0 && event.time >= dumpTime) {
-            pStack->showStack(stdout);
-            break;
-        }
-    }
-
-    for (int ii = 0; ii < kMaxThreads; ++ii) {
-        if (stacks[ii])
-            stacks[ii]->popAll(event.time);
-    }
-
-    delete trace;
-    return 0;
-}
diff --git a/emulator/qtools/tests/common_head.mk b/emulator/qtools/tests/common_head.mk
deleted file mode 100644
index e8170e9..0000000
--- a/emulator/qtools/tests/common_head.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-CC := arm-elf-gcc
-LD := arm-elf-ld
-AS := arm-elf-as
-OBJCOPY := arm-elf-objcopy
-OBJDUMP := arm-elf-objdump
-
-OPT := -g
-CFLAGS := $(OPT) -mcpu=arm9
-
-.SUFFIXES: .dis .bin .elf
-
-.c.elf:
-	$(CC) $(CFLAGS)  -Xlinker --script ../tests.ld -o $@ $< -nostdlib
-
-.c.s:
-	$(CC) $(CFLAGS) -static -S $<
-
-.S.elf:
-	$(CC) $(CFLAGS) -Xlinker --script ../tests.ld -nostdlib -o $@ $<
-
-.elf.dis:
-	$(OBJDUMP) -adx $< > $@
-
-.elf.bin:
-	$(OBJCOPY) -O binary $< $@
diff --git a/emulator/qtools/tests/common_tail.mk b/emulator/qtools/tests/common_tail.mk
deleted file mode 100644
index be1c141..0000000
--- a/emulator/qtools/tests/common_tail.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-
-clean:
-	rm -f *.elf *.dis *.bin *.o *~ a.out
diff --git a/emulator/qtools/tests/gtrace/Makefile b/emulator/qtools/tests/gtrace/Makefile
deleted file mode 100644
index 1d2050c..0000000
--- a/emulator/qtools/tests/gtrace/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-include ../common_head.mk
-
-P4ROOT=/work/android
-QEMU=$(P4ROOT)/device/tools/qemu/arm-softmmu/qemu-system-arm
-QTOOLS=$(P4ROOT)/device/tools/qtools
-
-all: test.elf test.bin test.dis
-
-trace: test.elf test.bin
-	$(QEMU) -QEMU -kernel test.bin -trace foo
-	$(QTOOLS)/post_trace foo
-	$(QTOOLS)/read_trace foo test.elf > t1
-
-gtrace: trace
-	$(QTOOLS)/q2g -r $(P4ROOT)/device/out/linux-arm-release/symbols foo test.elf foo.gtrace
-	gtracepost64 foo.gtrace > t2
-
-include ../common_tail.mk
diff --git a/emulator/qtools/tests/gtrace/test.c b/emulator/qtools/tests/gtrace/test.c
deleted file mode 100644
index e56a0f1..0000000
--- a/emulator/qtools/tests/gtrace/test.c
+++ /dev/null
@@ -1,201 +0,0 @@
-#include "../macros.h"
-
-int foo1();
-int foo2();
-void bar();
-int child1();
-int child2();
-int child3();
-int child4();
-int child5();
-
-int global;
-
-void start()
-{
-  // Set the stack pointer
-  asm("  mov r13,#0x200000");
-  PRINT_STR("hello\n");
-  TRACE_INIT_NAME(701, "proc_foo");
-  TRACE_INIT_NAME(702, "proc_bar");
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-  TRACE_SWITCH(702);
-  if (global++ > 0)
-      global++;
-  bar();
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo2();
-  TRACE_SWITCH(703);
-  if (global++ > 0)
-      global++;
-  foo1();
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(704);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(705);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(706);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(707);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(708);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(709);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(701);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_SWITCH(710);
-  if (global++ > 0)
-      global++;
-  foo1();
-
-  TRACE_STOP_EMU();
-}
-
-int foo1()
-{
-  int a = 0;
-
-  int ii;
-  for (ii = 0; ii < 3; ++ii) {
-    a += child1();
-    a += child2();
-    a += child3();
-  }
-  return a;
-}
-
-int foo2()
-{
-  int a = 0;
-
-  int ii;
-  for (ii = 0; ii < 2; ++ii) {
-    a += child3();
-    a += child4();
-    a += child5();
-  }
-  return a;
-}
-
-#define kStride 64
-void bar()
-{
-  int a = 0;
-
-  static char mem[1000 * kStride];
-
-  int ii, jj;
-
-  for (ii = 0; ii < 4; ++ii) {
-    for (jj = 0; jj < 10; ++jj)
-      a += mem[jj * kStride];
-    foo1();
-    foo2();
-  }
-}
-
-int child1()
-{
-  int a = 0;
-
-  int ii;
-  for (ii = 0; ii < 2; ++ii)
-    a += ii;
-  return a;
-}
-
-int child2()
-{
-  int a = 0;
-
-  int ii;
-  for (ii = 0; ii < 4; ++ii)
-    a += ii;
-  return a;
-}
-
-int child3()
-{
-  int a = 0;
-
-  int ii;
-  for (ii = 0; ii < 6; ++ii)
-    a += ii;
-  return a;
-}
-
-int child4()
-{
-  int a = 0;
-
-  int ii;
-  for (ii = 0; ii < 8; ++ii)
-    a += ii;
-  return a;
-}
-
-int child5()
-{
-  int a = 0;
-
-  int ii;
-  for (ii = 0; ii < 10; ++ii)
-    a += ii;
-  return a;
-}
diff --git a/emulator/qtools/tests/macros.h b/emulator/qtools/tests/macros.h
deleted file mode 100644
index 066374b..0000000
--- a/emulator/qtools/tests/macros.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef _TEST_TRACE_C_H_
-#define _TEST_TRACE_C_H_
-
-/* the base address of trace device */
-#define TRACE_DEV_BASE_ADDR             0x21000000
-
-/*the register addresses of the trace device */
-#define TRACE_DEV_REG_SWITCH            0
-#define TRACE_DEV_REG_FORK              1
-#define TRACE_DEV_REG_EXECVE_PID        2
-#define TRACE_DEV_REG_EXECVE_VMSTART    3
-#define TRACE_DEV_REG_EXECVE_VMEND      4
-#define TRACE_DEV_REG_EXECVE_OFFSET     5
-#define TRACE_DEV_REG_EXECVE_EXEPATH    6
-#define TRACE_DEV_REG_EXIT              7
-#define TRACE_DEV_REG_CMDLINE           8
-#define TRACE_DEV_REG_CMDLINE_LEN       9
-#define TRACE_DEV_REG_MMAP_EXEPATH      10
-#define TRACE_DEV_REG_INIT_PID          11
-#define TRACE_DEV_REG_INIT_NAME         12
-#define TRACE_DEV_REG_CLONE             13
-#define TRACE_DEV_REG_DYN_SYM           50
-#define TRACE_DEV_REG_DYN_SYM_ADDR      51
-#define TRACE_DEV_REG_PRINT_STR         60
-#define TRACE_DEV_REG_PRINT_NUM_DEC     61
-#define TRACE_DEV_REG_PRINT_NUM_HEX     62
-#define TRACE_DEV_REG_STOP_EMU          90
-#define TRACE_DEV_REG_ENABLE            100
-#define TRACE_DEV_REG_DISABLE           101
-
-/* write a word to a trace device register */
-#define DEV_WRITE_WORD(addr,value)\
-    (*(volatile unsigned long *)(TRACE_DEV_BASE_ADDR + ((addr) << 2)) = (value))
-
-/*************************************************************/
-/* generates test events */
-
-/* context switch */
-#define TRACE_SWITCH(pid)            DEV_WRITE_WORD(TRACE_DEV_REG_SWITCH, (pid))
-/* fork */
-#define TRACE_FORK(pid)              DEV_WRITE_WORD(TRACE_DEV_REG_FORK, (pid))
-/* clone */
-#define TRACE_CLONE(pid)             DEV_WRITE_WORD(TRACE_DEV_REG_CLONE, (pid))
-/* dump name and path of threads executed before trace device created */
-#define TRACE_INIT_NAME(pid,path)\
-do {\
-    DEV_WRITE_WORD(TRACE_DEV_REG_INIT_PID, (pid));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_INIT_NAME, (unsigned long)(path));\
-}while(0)
-/* dump exec mapping of threads executed before trace device created */
-#define TRACE_INIT_EXEC(vstart,vend,eoff,path)\
-do {\
-    DEV_WRITE_WORD(TRACE_DEV_REG_EXECVE_VMSTART, (vstart));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_EXECVE_VMEND, (vend));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_EXECVE_OFFSET, (eoff));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_EXECVE_EXEPATH, (unsigned long)(path));\
-}while(0)
-/* mmap */
-#define TRACE_MMAP(vstart,vend,eoff,path)\
-do {\
-    DEV_WRITE_WORD(TRACE_DEV_REG_EXECVE_VMSTART, (vstart));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_EXECVE_VMEND, (vend));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_EXECVE_OFFSET, (eoff));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_MMAP_EXEPATH, (unsigned long)(path));\
-}while(0)
-/* execve */
-#define TRACE_EXECVE(cmdlen,cmd)\
-do {\
-    DEV_WRITE_WORD(TRACE_DEV_REG_CMDLINE_LEN, (cmdlen));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_CMDLINE, (unsigned long)(cmd));\
-}while(0)
-/* exit */
-#define TRACE_EXIT(retv)             DEV_WRITE_WORD(TRACE_DEV_REG_EXIT, (retv))
-
-/* other commands */
-
-/* stop emulation */
-#define TRACE_STOP_EMU()             DEV_WRITE_WORD(TRACE_DEV_REG_STOP_EMU, 1)
-/* enable/disable tracing */
-#define TRACE_ENABLE_TRACING()       DEV_WRITE_WORD(TRACE_DEV_REG_ENABLE, 1)
-#define TRACE_DISABLE_TRACING()      DEV_WRITE_WORD(TRACE_DEV_REG_DISABLE, 1)
-/* dynamic symbols */
-#define TRACE_DYN_SYM(addr,sym)\
-do {\
-    DEV_WRITE_WORD(TRACE_DEV_REG_DYN_SYM_ADDR, (addr));\
-    DEV_WRITE_WORD(TRACE_DEV_REG_DYN_SYM, (unsigned long)(sym));\
-}while(0)
-/* prints */
-#define PRINT_STR(str)         DEV_WRITE_WORD(TRACE_DEV_REG_PRINT_STR, (unsigned long)(str))
-#define PRINT_NUM_DEC(num)     DEV_WRITE_WORD(TRACE_DEV_REG_PRINT_NUM_DEC, (num))
-#define PRINT_NUM_HEX(num)     DEV_WRITE_WORD(TRACE_DEV_REG_PRINT_NUM_HEX, (num))
-
-#endif
diff --git a/emulator/qtools/tests/tests.ld b/emulator/qtools/tests/tests.ld
deleted file mode 100644
index 05fe41b..0000000
--- a/emulator/qtools/tests/tests.ld
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTIONS {
-  TEXT_START = 0x00010000 ;
-  DATA_START = 0x00200000 ;
-  handlers 0x0 : { *(handlers) }
-  .text TEXT_START : { *(.text) }
-  .data DATA_START : { *(.data) }
-  .bss  : { *(.bss) *(COMMON) }
-  p00300000 0x00300000 : { *(p00300000) }
-  p00400000 0x00400000 : { *(p00400000) }
-}
diff --git a/emulator/qtools/thumbdis.cpp b/emulator/qtools/thumbdis.cpp
deleted file mode 100644
index 07c482f..0000000
--- a/emulator/qtools/thumbdis.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-/* Instruction printing code for the ARM
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
-   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
-   Modification by James G. Smith (jsmith@cygnus.co.uk)
-
-This file is part of libopcodes. 
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your option)
-any later version. 
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-more details. 
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-/* Modified to fit into the qtools framework.  The main differences are:
- *
- * - The disassembly function returns a string instead of writing it to a
- * file stream.
- *
- * - All the references to the struct "disassemble_info" have been removed.
- *
- * - A set of enums for the thumb opcodes have been defined, along with a
- * "decode()" function that maps a thumb instruction to an opcode enum.
- *
- * - Eliminated uses of the special characters ', `, and ? from the
- * thumb_opcodes[] table so that we can easily specify separate opcodes
- * for distinct instructions.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include "opcode.h"
-
-
-struct thumb_opcode
-{
-    unsigned short value, mask;  /* recognise instruction if (op&mask)==value */
-    Opcode opcode;
-    const char * assembler;      /* how to disassemble this instruction */
-};
-
-/* format of the assembler string :
-   
-   %%                   %
-   %<bitfield>d         print the bitfield in decimal
-   %<bitfield>x         print the bitfield in hex
-   %<bitfield>X         print the bitfield as 1 hex digit without leading "0x"
-   %<bitfield>r         print as an ARM register
-   %<bitfield>f         print a floating point constant if >7 else a
-                          floating point register
-   %<code>y             print a single precision VFP reg.
-                          Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
-   %<code>z             print a double precision VFP reg
-                          Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
-   %c                   print condition code (always bits 28-31)
-   %P                   print floating point precision in arithmetic insn
-   %Q                   print floating point precision in ldf/stf insn
-   %R                   print floating point rounding mode
-   %<bitnum>'c          print specified char iff bit is one
-   %<bitnum>`c          print specified char iff bit is zero
-   %<bitnum>?ab         print a if bit is one else print b
-   %p                   print 'p' iff bits 12-15 are 15
-   %t                   print 't' iff bit 21 set and bit 24 clear
-   %o                   print operand2 (immediate or register + shift)
-   %a                   print address for ldr/str instruction
-   %s                   print address for ldr/str halfword/signextend instruction
-   %b                   print branch destination
-   %B                   print arm BLX(1) destination
-   %A                   print address for ldc/stc/ldf/stf instruction
-   %m                   print register mask for ldm/stm instruction
-   %C                   print the PSR sub type.
-   %F                   print the COUNT field of a LFM/SFM instruction.
-Thumb specific format options:
-   %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
-   %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
-   %<bitfield>I         print bitfield as a signed decimal
-                          (top bit of range being the sign bit)
-   %M                   print Thumb register mask
-   %N                   print Thumb register mask (with LR)
-   %O                   print Thumb register mask (with PC)
-   %T                   print Thumb condition code (always bits 8-11)
-   %I                   print cirrus signed shift immediate: bits 0..3|4..6
-   %<bitfield>B         print Thumb branch destination (signed displacement)
-   %<bitfield>W         print (bitfield * 4) as a decimal
-   %<bitfield>H         print (bitfield * 2) as a decimal
-   %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
-*/
-
-
-static struct thumb_opcode thumb_opcodes[] =
-{
-    /* Thumb instructions.  */
-
-    /* ARM V5 ISA extends Thumb.  */
-    {0xbe00, 0xff00, OP_THUMB_BKPT, "bkpt\t%0-7x"},
-    {0x4780, 0xff87, OP_THUMB_BLX, "blx\t%3-6r"},  /* note: 4 bit register number.  */
-    /* Format 5 instructions do not update the PSR.  */
-    {0x1C00, 0xFFC0, OP_THUMB_MOV, "mov\t%0-2r, %3-5r"},
-    /* Format 4.  */
-    {0x4000, 0xFFC0, OP_THUMB_AND, "and\t%0-2r, %3-5r"},
-    {0x4040, 0xFFC0, OP_THUMB_EOR, "eor\t%0-2r, %3-5r"},
-    {0x4080, 0xFFC0, OP_THUMB_LSL, "lsl\t%0-2r, %3-5r"},
-    {0x40C0, 0xFFC0, OP_THUMB_LSR, "lsr\t%0-2r, %3-5r"},
-    {0x4100, 0xFFC0, OP_THUMB_ASR, "asr\t%0-2r, %3-5r"},
-    {0x4140, 0xFFC0, OP_THUMB_ADC, "adc\t%0-2r, %3-5r"},
-    {0x4180, 0xFFC0, OP_THUMB_SBC, "sbc\t%0-2r, %3-5r"},
-    {0x41C0, 0xFFC0, OP_THUMB_ROR, "ror\t%0-2r, %3-5r"},
-    {0x4200, 0xFFC0, OP_THUMB_TST, "tst\t%0-2r, %3-5r"},
-    {0x4240, 0xFFC0, OP_THUMB_NEG, "neg\t%0-2r, %3-5r"},
-    {0x4280, 0xFFC0, OP_THUMB_CMP, "cmp\t%0-2r, %3-5r"},
-    {0x42C0, 0xFFC0, OP_THUMB_CMN, "cmn\t%0-2r, %3-5r"},
-    {0x4300, 0xFFC0, OP_THUMB_ORR, "orr\t%0-2r, %3-5r"},
-    {0x4340, 0xFFC0, OP_THUMB_MUL, "mul\t%0-2r, %3-5r"},
-    {0x4380, 0xFFC0, OP_THUMB_BIC, "bic\t%0-2r, %3-5r"},
-    {0x43C0, 0xFFC0, OP_THUMB_MVN, "mvn\t%0-2r, %3-5r"},
-    /* format 13 */
-    {0xB000, 0xFF80, OP_THUMB_ADD, "add\tsp, #%0-6W"},
-    {0xB080, 0xFF80, OP_THUMB_SUB, "sub\tsp, #%0-6W"},
-    /* format 5 */
-    {0x4700, 0xFF80, OP_THUMB_BX, "bx\t%S"},
-    {0x4400, 0xFF00, OP_THUMB_ADD, "add\t%D, %S"},
-    {0x4500, 0xFF00, OP_THUMB_CMP, "cmp\t%D, %S"},
-    {0x4600, 0xFF00, OP_THUMB_MOV, "mov\t%D, %S"},
-    /* format 14 */
-    {0xB400, 0xFE00, OP_THUMB_PUSH, "push\t%N"},
-    {0xBC00, 0xFE00, OP_THUMB_POP, "pop\t%O"},
-    /* format 2 */
-    {0x1800, 0xFE00, OP_THUMB_ADD, "add\t%0-2r, %3-5r, %6-8r"},
-    {0x1A00, 0xFE00, OP_THUMB_SUB, "sub\t%0-2r, %3-5r, %6-8r"},
-    {0x1C00, 0xFE00, OP_THUMB_ADD, "add\t%0-2r, %3-5r, #%6-8d"},
-    {0x1E00, 0xFE00, OP_THUMB_SUB, "sub\t%0-2r, %3-5r, #%6-8d"},
-    /* format 8 */
-    {0x5200, 0xFE00, OP_THUMB_STRH, "strh\t%0-2r, [%3-5r, %6-8r]"},
-    {0x5A00, 0xFE00, OP_THUMB_LDRH, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
-    {0x5600, 0xFE00, OP_THUMB_LDRSB, "ldrsb\t%0-2r, [%3-5r, %6-8r]"},
-    {0x5E00, 0xFE00, OP_THUMB_LDRSH, "ldrsh\t%0-2r, [%3-5r, %6-8r]"},
-    /* format 7 */
-    {0x5000, 0xFE00, OP_THUMB_STR, "str\t%0-2r, [%3-5r, %6-8r]"},
-    {0x5400, 0xFE00, OP_THUMB_STRB, "strb\t%0-2r, [%3-5r, %6-8r]"},
-    {0x5800, 0xFE00, OP_THUMB_LDR, "ldr\t%0-2r, [%3-5r, %6-8r]"},
-    {0x5C00, 0xFE00, OP_THUMB_LDRB, "ldrb\t%0-2r, [%3-5r, %6-8r]"},
-    /* format 1 */
-    {0x0000, 0xF800, OP_THUMB_LSL, "lsl\t%0-2r, %3-5r, #%6-10d"},
-    {0x0800, 0xF800, OP_THUMB_LSR, "lsr\t%0-2r, %3-5r, #%6-10d"},
-    {0x1000, 0xF800, OP_THUMB_ASR, "asr\t%0-2r, %3-5r, #%6-10d"},
-    /* format 3 */
-    {0x2000, 0xF800, OP_THUMB_MOV, "mov\t%8-10r, #%0-7d"},
-    {0x2800, 0xF800, OP_THUMB_CMP, "cmp\t%8-10r, #%0-7d"},
-    {0x3000, 0xF800, OP_THUMB_ADD, "add\t%8-10r, #%0-7d"},
-    {0x3800, 0xF800, OP_THUMB_SUB, "sub\t%8-10r, #%0-7d"},
-    /* format 6 */
-    /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
-    {0x4800, 0xF800, OP_THUMB_LDR, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},
-    /* format 9 */
-    {0x6000, 0xF800, OP_THUMB_STR, "str\t%0-2r, [%3-5r, #%6-10W]"},
-    {0x6800, 0xF800, OP_THUMB_LDR, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
-    {0x7000, 0xF800, OP_THUMB_STRB, "strb\t%0-2r, [%3-5r, #%6-10d]"},
-    {0x7800, 0xF800, OP_THUMB_LDRB, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
-    /* format 10 */
-    {0x8000, 0xF800, OP_THUMB_STRH, "strh\t%0-2r, [%3-5r, #%6-10H]"},
-    {0x8800, 0xF800, OP_THUMB_LDRH, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
-    /* format 11 */
-    {0x9000, 0xF800, OP_THUMB_STR, "str\t%8-10r, [sp, #%0-7W]"},
-    {0x9800, 0xF800, OP_THUMB_LDR, "ldr\t%8-10r, [sp, #%0-7W]"},
-    /* format 12 */
-    {0xA000, 0xF800, OP_THUMB_ADD, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
-    {0xA800, 0xF800, OP_THUMB_ADD, "add\t%8-10r, sp, #%0-7W"},
-    /* format 15 */
-    {0xC000, 0xF800, OP_THUMB_STMIA, "stmia\t%8-10r!,%M"},
-    {0xC800, 0xF800, OP_THUMB_LDMIA, "ldmia\t%8-10r!,%M"},
-    /* format 18 */
-    {0xE000, 0xF800, OP_THUMB_B, "b\t%0-10B"},
-    /* format 19 */
-    /* special processing required in disassembler */
-    {0xF000, 0xF800, OP_THUMB_BL, ""},
-    {0xF800, 0xF800, OP_THUMB_BL, "second half of BL instruction %0-15x"},
-    {0xE800, 0xF800, OP_THUMB_BLX, "second half of BLX instruction %0-15x"},
-    /* format 16 */
-    {0xD000, 0xFF00, OP_THUMB_B, "beq\t%0-7B"},
-    {0xD100, 0xFF00, OP_THUMB_B, "bne\t%0-7B"},
-    {0xD200, 0xFF00, OP_THUMB_B, "bcs\t%0-7B"},
-    {0xD300, 0xFF00, OP_THUMB_B, "bcc\t%0-7B"},
-    {0xD400, 0xFF00, OP_THUMB_B, "bmi\t%0-7B"},
-    {0xD500, 0xFF00, OP_THUMB_B, "bpl\t%0-7B"},
-    {0xD600, 0xFF00, OP_THUMB_B, "bvs\t%0-7B"},
-    {0xD700, 0xFF00, OP_THUMB_B, "bvc\t%0-7B"},
-    {0xD800, 0xFF00, OP_THUMB_B, "bhi\t%0-7B"},
-    {0xD900, 0xFF00, OP_THUMB_B, "bls\t%0-7B"},
-    {0xDA00, 0xFF00, OP_THUMB_B, "bge\t%0-7B"},
-    {0xDB00, 0xFF00, OP_THUMB_B, "blt\t%0-7B"},
-    {0xDC00, 0xFF00, OP_THUMB_B, "bgt\t%0-7B"},
-    {0xDD00, 0xFF00, OP_THUMB_B, "ble\t%0-7B"},
-    /* format 17 */
-    {0xDE00, 0xFF00, OP_THUMB_UNDEFINED, "undefined"},
-    {0xDF00, 0xFF00, OP_THUMB_SWI, "swi\t%0-7d"},
-    /* format 9 */
-    {0x6000, 0xF800, OP_THUMB_STR, "str\t%0-2r, [%3-5r, #%6-10W]"},
-    {0x6800, 0xF800, OP_THUMB_LDR, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
-    {0x7000, 0xF800, OP_THUMB_STRB, "strb\t%0-2r, [%3-5r, #%6-10d]"},
-    {0x7800, 0xF800, OP_THUMB_LDRB, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
-    /* the rest */
-    {0x0000, 0x0000, OP_THUMB_UNDEFINED, "undefined instruction %0-15x"},
-    {0x0000, 0x0000, OP_END, 0}
-};
-
-#define BDISP23(x,y) ((((((x) & 0x07ff) << 11) | ((y) & 0x07ff)) \
-                     ^ 0x200000) - 0x200000) /* 23bit */
-
-static const char * arm_conditional[] =
-{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
-
-typedef struct
-{
-  const char * name;
-  const char * description;
-  const char * reg_names[16];
-}
-arm_regname;
-
-static arm_regname regnames[] =
-{
-  { "raw" , "Select raw register names",
-    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
-  { "gcc",  "Select register names used by GCC",
-    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
-  { "std",  "Select register names used in ARM's ISA documentation",
-    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
-  { "apcs", "Select register names used in the APCS",
-    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
-  { "atpcs", "Select register names used in the ATPCS",
-    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
-  { "special-atpcs", "Select special register names used in the ATPCS",
-    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
-};
-
-/* Default to STD register name set.  */
-static unsigned int regname_selected = 2;
-
-#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
-#define arm_regnames      regnames[regname_selected].reg_names
-
-Opcode decode_insn_thumb(uint32_t given)
-{
-    struct thumb_opcode * insn;
-
-    for (insn = thumb_opcodes; insn->assembler; insn++) {
-        if ((given & insn->mask) == insn->value)
-            return insn->opcode;
-    }
-    return OP_THUMB_UNDEFINED;
-}
-
-// Generates the disassembly string for the thumb instruction "insn1".
-// If "insn1" is a BL or BLX instruction that is the first of two Thumb
-// instructions, then insn2 is the second of two instructions.  Otherwise,
-// insn2 is ignored.
-char *disasm_insn_thumb(uint32_t pc, uint32_t insn1, uint32_t insn2, char *result)
-{
-    struct thumb_opcode * insn;
-    static char buf[80];
-    char *ptr;
-    uint32_t addr;
-    int len;
-
-    if (result == NULL)
-        result = buf;
-    ptr = result;
-
-    for (insn = thumb_opcodes; insn->assembler; insn++) {
-        if ((insn1 & insn->mask) != insn->value)
-            continue;
-
-        const char * c = insn->assembler;
-
-        /* Special processing for Thumb 2-instruction BL sequence:  */
-        if (!*c) { /* Check for empty (not NULL) assembler string.  */
-            uint32_t offset;
-
-            offset = BDISP23 (insn1, insn2);
-            offset = offset * 2 + pc + 4;
-            
-            if ((insn2 & 0x1000) == 0) {
-                len = sprintf(ptr, "blx\t");
-                offset &= 0xfffffffc;
-            } else {
-                len = sprintf(ptr, "bl\t");
-            }
-            ptr += len;
-            
-            sprintf(ptr, "0x%x", offset);
-            return result;
-        }
-        
-        insn1 &= 0xffff;
-        
-        for (; *c; c++) {
-            if (*c != '%') {
-                len = sprintf(ptr, "%c", *c);
-                ptr += len;
-                continue;
-            }
-
-            int domaskpc = 0;
-            int domasklr = 0;
-            
-            switch (*++c) {
-                case '%':
-                    len = sprintf(ptr, "%%");
-                    ptr += len;
-                    break;
-                    
-                case 'S': {
-                    uint32_t reg;
-                    
-                    reg = (insn1 >> 3) & 0x7;
-                    if (insn1 & (1 << 6))
-                        reg += 8;
-                    
-                    len = sprintf(ptr, "%s", arm_regnames[reg]);
-                    ptr += len;
-                    break;
-                }
-                    
-                case 'D': {
-                    uint32_t reg;
-                    
-                    reg = insn1 & 0x7;
-                    if (insn1 & (1 << 7))
-                        reg += 8;
-                    
-                    len = sprintf(ptr, "%s", arm_regnames[reg]);
-                    ptr += len;
-                    break;
-                }
-                    
-                case 'T':
-                    len = sprintf(ptr, "%s",
-                          arm_conditional [(insn1 >> 8) & 0xf]);
-                    ptr += len;
-                    break;
-                    
-                case 'N':
-                    if (insn1 & (1 << 8))
-                        domasklr = 1;
-                    /* Fall through.  */
-                case 'O':
-                    if (*c == 'O' && (insn1 & (1 << 8)))
-                        domaskpc = 1;
-                    /* Fall through.  */
-                case 'M': {
-                    int started = 0;
-                    int reg;
-                    
-                    len = sprintf(ptr, "{");
-                    ptr += len;
-                    
-                    /* It would be nice if we could spot
-                       ranges, and generate the rS-rE format: */
-                    for (reg = 0; (reg < 8); reg++)
-                        if ((insn1 & (1 << reg)) != 0) {
-                            if (started) {
-                                len = sprintf(ptr, ", ");
-                                ptr += len;
-                            }
-                            started = 1;
-                            len = sprintf(ptr, "%s", arm_regnames[reg]);
-                            ptr += len;
-                        }
-                    
-                    if (domasklr) {
-                        if (started) {
-                            len = sprintf(ptr, ", ");
-                            ptr += len;
-                        }
-                        started = 1;
-                        len = sprintf(ptr, arm_regnames[14] /* "lr" */);
-                        ptr += len;
-                    }
-                    
-                    if (domaskpc) {
-                        if (started) {
-                            len = sprintf(ptr, ", ");
-                            ptr += len;
-                        }
-                        len = sprintf(ptr, arm_regnames[15] /* "pc" */);
-                        ptr += len;
-                    }
-                    
-                    len = sprintf(ptr, "}");
-                    ptr += len;
-                    break;
-                }
-                    
-                case '0': case '1': case '2': case '3': case '4': 
-                case '5': case '6': case '7': case '8': case '9': {
-                    int bitstart = *c++ - '0';
-                    int bitend = 0;
-                    
-                    while (*c >= '0' && *c <= '9')
-                        bitstart = (bitstart * 10) + *c++ - '0';
-                    
-                    switch (*c) {
-                        case '-': {
-                            uint32_t reg;
-                            
-                            c++;
-                            while (*c >= '0' && *c <= '9')
-                                bitend = (bitend * 10) + *c++ - '0';
-                            if (!bitend)
-                                abort ();
-                            reg = insn1 >> bitstart;
-                            reg &= (2 << (bitend - bitstart)) - 1;
-                            switch (*c) {
-                                case 'r':
-                                    len = sprintf(ptr, "%s", arm_regnames[reg]);
-                                    break;
-                                    
-                                case 'd':
-                                    len = sprintf(ptr, "%d", reg);
-                                    break;
-                                    
-                                case 'H':
-                                    len = sprintf(ptr, "%d", reg << 1);
-                                    break;
-                                    
-                                case 'W':
-                                    len = sprintf(ptr, "%d", reg << 2);
-                                    break;
-                                    
-                                case 'a':
-                                    /* PC-relative address -- the bottom two
-                                       bits of the address are dropped
-                                       before the calculation.  */
-                                    addr = ((pc + 4) & ~3) + (reg << 2);
-                                    len = sprintf(ptr, "0x%x", addr);
-                                    break;
-                                    
-                                case 'x':
-                                    len = sprintf(ptr, "0x%04x", reg);
-                                    break;
-                                    
-                                case 'I':
-                                    reg = ((reg ^ (1 << bitend)) - (1 << bitend));
-                                    len = sprintf(ptr, "%d", reg);
-                                    break;
-                                    
-                                case 'B':
-                                    reg = ((reg ^ (1 << bitend)) - (1 << bitend));
-                                    addr = reg * 2 + pc + 4;
-                                    len = sprintf(ptr, "0x%x", addr);
-                                    break;
-                                    
-                                default:
-                                    abort ();
-                            }
-                            ptr += len;
-                            break;
-                        }
-                            
-                        case '\'':
-                            c++;
-                            if ((insn1 & (1 << bitstart)) != 0) {
-                                len = sprintf(ptr, "%c", *c);
-                                ptr += len;
-                            }
-                            break;
-                            
-                        case '?':
-                            ++c;
-                            if ((insn1 & (1 << bitstart)) != 0)
-                                len = sprintf(ptr, "%c", *c++);
-                            else
-                                len = sprintf(ptr, "%c", *++c);
-                            ptr += len;
-                            break;
-                            
-                        default:
-                            abort ();
-                    }
-                    break;
-                }
-                    
-                default:
-                    abort ();
-            }
-        }
-        return result;
-    }
-    
-    /* No match.  */
-    abort ();
-}
diff --git a/emulator/qtools/trace_reader.cpp b/emulator/qtools/trace_reader.cpp
deleted file mode 100644
index 47b5d93..0000000
--- a/emulator/qtools/trace_reader.cpp
+++ /dev/null
@@ -1,1201 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <inttypes.h>
-#include <assert.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <elf.h>
-#include "trace_reader.h"
-#include "decoder.h"
-
-// A struct for creating temporary linked-lists of DexSym structs
-struct DexSymList {
-    DexSymList  *next;
-    DexSym      sym;
-};
-
-// Declare static functions used in this file
-static char *ExtractDexPathFromMmap(const char *mmap_path);
-static void CopyDexSymbolsToArray(DexFileList *dexfile,
-                                  DexSymList *head, int num_symbols);
-
-// This function creates the pathname to the a specific trace file.  The
-// string space is allocated in this routine and must be freed by the
-// caller.
-static char *CreateTracePath(const char *filename, const char *ext)
-{
-    char *fname;
-    const char *base_start, *base_end;
-    int ii, len, base_len, dir_len, path_len, qtrace_len;
-
-    // Handle error cases
-    if (filename == NULL || *filename == 0 || strcmp(filename, "/") == 0)
-        return NULL;
-
-    // Ignore a trailing slash, if any
-    len = strlen(filename);
-    if (filename[len - 1] == '/')
-        len -= 1;
-
-    // Find the basename.  We don't use basename(3) because there are
-    // different behaviors for GNU and Posix in the case where the
-    // last character is a slash.
-    base_start = base_end = &filename[len];
-    for (ii = 0; ii < len; ++ii) {
-        base_start -= 1;
-        if (*base_start == '/') {
-            base_start += 1;
-            break;
-        }
-    }
-    base_len = base_end - base_start;
-    dir_len = len - base_len;
-    qtrace_len = strlen("/qtrace");
-
-    // Create space for the pathname: "/dir/basename/qtrace.ext"
-    // The "ext" string already contains the dot, so just add a byte
-    // for the terminating zero.
-    path_len = dir_len + base_len + qtrace_len + strlen(ext) + 1;
-    fname = new char[path_len];
-    if (dir_len > 0)
-        strncpy(fname, filename, dir_len);
-    fname[dir_len] = 0;
-    strncat(fname, base_start, base_len);
-    strcat(fname, "/qtrace");
-    strcat(fname, ext);
-    return fname;
-}
-
-inline BBReader::Future *BBReader::AllocFuture()
-{
-    Future *future = free_;
-    free_ = free_->next;
-    return future;
-}
-
-inline void BBReader::FreeFuture(Future *future)
-{
-    future->next = free_;
-    free_ = future;
-}
-
-inline void BBReader::InsertFuture(Future *future)
-{
-    uint64_t future_time = future->bb.next_time;
-    Future *prev = NULL;
-    Future *ptr;
-    for (ptr = head_; ptr; prev = ptr, ptr = ptr->next) {
-        if (future_time <= ptr->bb.next_time)
-            break;
-    }
-    if (prev == NULL) {
-        // link it at the front
-        future->next = head_;
-        head_ = future;
-    } else {
-        // link it after "prev"
-        future->next = prev->next;
-        prev->next = future;
-    }
-}
-
-// Decodes the next basic block record from the file.  Returns 1
-// at end-of-file, otherwise returns 0.
-inline int BBReader::DecodeNextRec()
-{
-    int64_t bb_diff = decoder_->Decode(true);
-    uint64_t time_diff = decoder_->Decode(false);
-    nextrec_.bb_rec.repeat = decoder_->Decode(false);
-    if (time_diff == 0)
-        return 1;
-    if (nextrec_.bb_rec.repeat)
-        nextrec_.bb_rec.time_diff = decoder_->Decode(false);
-    nextrec_.bb_rec.bb_num += bb_diff;
-    nextrec_.bb_rec.start_time += time_diff;
-    return 0;
-}
-
-BBReader::BBReader(TraceReaderBase *trace)
-{
-    trace_ = trace;
-    decoder_ = new Decoder;
-}
-
-BBReader::~BBReader()
-{
-    delete decoder_;
-}
-
-void BBReader::Open(const char *filename)
-{
-    // Initialize the class variables
-    memset(&nextrec_, 0, sizeof(TimeRec));
-    memset(futures_, 0, sizeof(Future) * kMaxNumBasicBlocks);
-    head_ = NULL;
-
-    // Link all of the futures_[] array elements on the free list.
-    for (int ii = 0; ii < kMaxNumBasicBlocks - 1; ++ii) {
-        futures_[ii].next = &futures_[ii + 1];
-    }
-    futures_[kMaxNumBasicBlocks - 1].next = 0;
-    free_ = &futures_[0];
-
-    // Open the trace.bb file
-    char *fname = CreateTracePath(filename, ".bb");
-    decoder_->Open(fname);
-    is_eof_ = DecodeNextRec();
-    delete[] fname;
-}
-
-void BBReader::Close()
-{
-    decoder_->Close();
-}
-
-// Returns true at end of file.
-bool BBReader::ReadBB(BBEvent *event)
-{
-    if (is_eof_ && head_ == NULL) {
-        return true;
-    }
-
-#if 0
-    if (nextrec_) {
-        printf("nextrec: buffer[%d], bb_num: %lld start: %d diff %d repeat %d next %u\n",
-               nextrec_ - &buffer_[0],
-               nextrec_->bb_rec.bb_num, nextrec_->bb_rec.start_time,
-               nextrec_->bb_rec.time_diff, nextrec_->bb_rec.repeat,
-               nextrec_->next_time);
-    }
-    if (head_) {
-        printf("head: 0x%x, bb_num: %lld start: %d diff %d repeat %d next %u\n",
-               head_,
-               head_->bb->bb_rec.bb_num, head_->bb->bb_rec.start_time,
-               head_->bb->bb_rec.time_diff, head_->bb->bb_rec.repeat,
-               head_->bb->next_time);
-    }
-#endif
-    if (!is_eof_) {
-        if (head_) {
-            TimeRec *bb = &head_->bb;
-            if (bb->next_time < nextrec_.bb_rec.start_time) {
-                // The head is earlier.
-                event->time = bb->next_time;
-                event->bb_num = bb->bb_rec.bb_num;
-                event->bb_addr = trace_->GetBBAddr(event->bb_num);
-                event->insns = trace_->GetInsns(event->bb_num);
-                event->num_insns = trace_->FindNumInsns(event->bb_num, event->time);
-                event->pid = trace_->FindCurrentPid(event->time);
-                event->is_thumb = trace_->GetIsThumb(event->bb_num);
-
-                // Remove the head element from the list
-                Future *future = head_;
-                head_ = head_->next;
-                if (bb->bb_rec.repeat > 0) {
-                    // there are more repetitions of this bb
-                    bb->bb_rec.repeat -= 1;
-                    bb->next_time += bb->bb_rec.time_diff;
-
-                    // Insert this future into the sorted list
-                    InsertFuture(future);
-                } else {
-                    // Add this future to the free list
-                    FreeFuture(future);
-                }
-                return false;
-            }
-        }
-        // The nextrec is earlier (or there was no head)
-        event->time = nextrec_.bb_rec.start_time;
-        event->bb_num = nextrec_.bb_rec.bb_num;
-        event->bb_addr = trace_->GetBBAddr(event->bb_num);
-        event->insns = trace_->GetInsns(event->bb_num);
-        event->num_insns = trace_->FindNumInsns(event->bb_num, event->time);
-        event->pid = trace_->FindCurrentPid(event->time);
-        event->is_thumb = trace_->GetIsThumb(event->bb_num);
-        if (nextrec_.bb_rec.repeat > 0) {
-            Future *future = AllocFuture();
-            future->bb.bb_rec = nextrec_.bb_rec;
-            future->bb.bb_rec.repeat -= 1;
-            future->bb.next_time = nextrec_.bb_rec.start_time + nextrec_.bb_rec.time_diff;
-            InsertFuture(future);
-        }
-
-        is_eof_ = DecodeNextRec();
-        return false;
-    }
-
-    //printf("using head_ 0x%x\n", head_);
-    assert(head_);
-    TimeRec *bb = &head_->bb;
-    event->time = bb->next_time;
-    event->bb_num = bb->bb_rec.bb_num;
-    event->bb_addr = trace_->GetBBAddr(event->bb_num);
-    event->insns = trace_->GetInsns(event->bb_num);
-    event->num_insns = trace_->FindNumInsns(event->bb_num, event->time);
-    event->pid = trace_->FindCurrentPid(event->time);
-    event->is_thumb = trace_->GetIsThumb(event->bb_num);
-
-    // Remove the head element from the list
-    Future *future = head_;
-    head_ = head_->next;
-    if (bb->bb_rec.repeat > 0) {
-        // there are more repetitions of this bb
-        bb->bb_rec.repeat -= 1;
-        bb->next_time += bb->bb_rec.time_diff;
-
-        // Insert this future into the sorted list
-        InsertFuture(future);
-    } else {
-        // Add this future to the free list
-        FreeFuture(future);
-    }
-    return false;
-}
-
-InsnReader::InsnReader()
-{
-    decoder_ = new Decoder;
-}
-
-InsnReader::~InsnReader()
-{
-    delete decoder_;
-}
-
-void InsnReader::Open(const char *filename)
-{
-    prev_time_ = 0;
-    time_diff_ = 0;
-    repeat_ = -1;
-
-    // Open the trace.insn file
-    char *fname = CreateTracePath(filename, ".insn");
-    decoder_->Open(fname);
-    delete[] fname;
-}
-
-void InsnReader::Close()
-{
-    decoder_->Close();
-}
-
-uint64_t InsnReader::ReadInsnTime(uint64_t min_time)
-{
-    do {
-        if (repeat_ == -1) {
-            time_diff_ = decoder_->Decode(false);
-            repeat_ = decoder_->Decode(false);
-        }
-        prev_time_ += time_diff_;
-        repeat_ -= 1;
-    } while (prev_time_ < min_time);
-    return prev_time_;
-}
-
-AddrReader::AddrReader()
-{
-    decoder_ = new Decoder;
-    opened_ = false;
-}
-
-AddrReader::~AddrReader()
-{
-    delete decoder_;
-}
-
-// Returns true if there is an error opening the file
-bool AddrReader::Open(const char *filename, const char *suffix)
-{
-    struct stat stat_buf;
-
-    prev_addr_ = 0;
-    prev_time_ = 0;
-
-    // Open the trace.addr file
-    char *fname = CreateTracePath(filename, suffix);
-    int rval = stat(fname, &stat_buf);
-    if (rval == -1) {
-        // The file does not exist
-        delete[] fname;
-        return true;
-    }
-    decoder_->Open(fname);
-    opened_ = true;
-    delete[] fname;
-    return false;
-}
-
-void AddrReader::Close()
-{
-    decoder_->Close();
-}
-
-// Returns true at end of file.
-bool AddrReader::ReadAddr(uint64_t *time, uint32_t *addr)
-{
-    if (!opened_) {
-        fprintf(stderr, "Cannot read address trace\n");
-        exit(1);
-    }
-    uint32_t addr_diff = decoder_->Decode(true);
-    uint64_t time_diff = decoder_->Decode(false);
-    if (time_diff == 0 && addr_diff == 0) {
-        *addr = 0;
-        *time = 0;
-        return true;
-    }
-    prev_addr_ += addr_diff;
-    prev_time_ += time_diff;
-    *addr = prev_addr_;
-    *time = prev_time_;
-    return false;
-}
-
-ExcReader::ExcReader()
-{
-    decoder_ = new Decoder;
-}
-
-ExcReader::~ExcReader()
-{
-    delete decoder_;
-}
-
-void ExcReader::Open(const char *filename)
-{
-    prev_time_ = 0;
-    prev_recnum_ = 0;
-
-    // Open the trace.exc file
-    char *fname = CreateTracePath(filename, ".exc");
-    decoder_->Open(fname);
-    delete[] fname;
-}
-
-void ExcReader::Close()
-{
-    decoder_->Close();
-}
-
-// Returns true at end of file.
-bool ExcReader::ReadExc(uint64_t *time, uint32_t *current_pc, uint64_t *recnum,
-                        uint32_t *target_pc, uint64_t *bb_num,
-                        uint64_t *bb_start_time, int *num_insns)
-{
-    uint64_t time_diff = decoder_->Decode(false);
-    uint32_t pc = decoder_->Decode(false);
-    if ((time_diff | pc) == 0) {
-        decoder_->Decode(false);
-        decoder_->Decode(false);
-        decoder_->Decode(false);
-        decoder_->Decode(false);
-        decoder_->Decode(false);
-        return true;
-    }
-    uint64_t recnum_diff = decoder_->Decode(false);
-    prev_time_ += time_diff;
-    prev_recnum_ += recnum_diff;
-    *time = prev_time_;
-    *current_pc = pc;
-    *recnum = prev_recnum_;
-    *target_pc = decoder_->Decode(false);
-    *bb_num = decoder_->Decode(false);
-    *bb_start_time = decoder_->Decode(false);
-    *num_insns = decoder_->Decode(false);
-    return false;
-}
-
-PidReader::PidReader()
-{
-    decoder_ = new Decoder;
-}
-
-PidReader::~PidReader()
-{
-    delete decoder_;
-}
-
-void PidReader::Open(const char *filename)
-{
-    prev_time_ = 0;
-
-    // Open the trace.pid file
-    char *fname = CreateTracePath(filename, ".pid");
-    decoder_->Open(fname);
-    delete[] fname;
-}
-
-void PidReader::Close()
-{
-    decoder_->Close();
-}
-
-// Returns true at end of file.
-bool PidReader::ReadPidEvent(PidEvent *event)
-{
-    uint64_t time_diff = decoder_->Decode(false);
-    int rec_type = decoder_->Decode(false);
-    prev_time_ += time_diff;
-    event->time = prev_time_;
-    event->rec_type = rec_type;
-    switch(rec_type) {
-        case kPidEndOfFile:
-            return true;
-        case kPidSwitch:
-        case kPidExit:
-            event->pid = decoder_->Decode(false);
-            break;
-        case kPidFork:
-        case kPidClone:
-            event->tgid = decoder_->Decode(false);
-            event->pid = decoder_->Decode(false);
-            break;
-        case kPidMmap:
-            {
-                event->vstart = decoder_->Decode(false);
-                event->vend = decoder_->Decode(false);
-                event->offset = decoder_->Decode(false);
-                int len = decoder_->Decode(false);
-                char *path = new char[len + 1];
-                decoder_->Read(path, len);
-                path[len] = 0;
-                event->path = path;
-                event->mmap_path = path;
-                char *dexfile = ExtractDexPathFromMmap(path);
-                if (dexfile != NULL) {
-                    delete[] event->path;
-                    event->path = dexfile;
-                }
-            }
-            break;
-        case kPidMunmap:
-            {
-                event->vstart = decoder_->Decode(false);
-                event->vend = decoder_->Decode(false);
-            }
-            break;
-        case kPidSymbolAdd:
-            {
-                event->vstart = decoder_->Decode(false);
-                int len = decoder_->Decode(false);
-                char *path = new char[len + 1];
-                decoder_->Read(path, len);
-                path[len] = 0;
-                event->path = path;
-            }
-            break;
-        case kPidSymbolRemove:
-            event->vstart = decoder_->Decode(false);
-            break;
-        case kPidExec:
-            {
-                int argc = decoder_->Decode(false);
-                event->argc = argc;
-                char **argv = new char*[argc];
-                event->argv = argv;
-                for (int ii = 0; ii < argc; ++ii) {
-                    int alen = decoder_->Decode(false);
-                    argv[ii] = new char[alen + 1];
-                    decoder_->Read(argv[ii], alen);
-                    argv[ii][alen] = 0;
-                }
-            }
-            break;
-        case kPidName:
-        case kPidKthreadName:
-            {
-                if (rec_type == kPidKthreadName) {
-                    event->tgid = decoder_->Decode(false);
-                }
-                event->pid = decoder_->Decode(false);
-                int len = decoder_->Decode(false);
-                char *path = new char[len + 1];
-                decoder_->Read(path, len);
-                path[len] = 0;
-                event->path = path;
-            }
-            break;
-    }
-    return false;
-}
-
-// Frees the memory that might have been allocated for the given event.
-void PidReader::Dispose(PidEvent *event)
-{
-    switch(event->rec_type) {
-        case kPidMmap:
-        case kPidSymbolAdd:
-        case kPidName:
-        case kPidKthreadName:
-            delete[] event->path;
-            event->path = NULL;
-            event->mmap_path = NULL;
-            break;
-
-        case kPidExec:
-            for (int ii = 0; ii < event->argc; ++ii) {
-                delete[] event->argv[ii];
-            }
-            delete[] event->argv;
-            event->argv = NULL;
-            event->argc = 0;
-            break;
-    }
-}
-
-
-MethodReader::MethodReader()
-{
-    decoder_ = new Decoder;
-    opened_ = false;
-}
-
-MethodReader::~MethodReader()
-{
-    delete decoder_;
-}
-
-bool MethodReader::Open(const char *filename)
-{
-    struct stat stat_buf;
-
-    prev_time_ = 0;
-    prev_addr_ = 0;
-    prev_pid_ = 0;
-
-    // Open the trace.method file
-    char *fname = CreateTracePath(filename, ".method");
-    int rval = stat(fname, &stat_buf);
-    if (rval == -1) {
-        // The file does not exist
-        delete[] fname;
-        return true;
-    }
-    decoder_->Open(fname);
-    delete[] fname;
-    opened_ = true;
-    return false;
-}
-
-void MethodReader::Close()
-{
-    decoder_->Close();
-}
-
-// Returns true at end of file.
-bool MethodReader::ReadMethod(MethodRec *method_record)
-{
-    if (!opened_)
-        return true;
-    uint64_t time_diff = decoder_->Decode(false);
-    int32_t addr_diff = decoder_->Decode(true);
-    if (time_diff == 0) {
-        method_record->time = 0;
-        method_record->addr = 0;
-        method_record->flags = 0;
-        return true;
-    }
-    int32_t pid_diff = decoder_->Decode(true);
-    prev_time_ += time_diff;
-    prev_addr_ += addr_diff;
-    prev_pid_ += pid_diff;
-    method_record->time = prev_time_;
-    method_record->addr = prev_addr_;
-    method_record->pid = prev_pid_;
-    method_record->flags = decoder_->Decode(false);
-    return false;
-}
-
-TraceReaderBase::TraceReaderBase()
-{
-    static_filename_ = NULL;
-    static_fstream_ = NULL;
-    header_ = new TraceHeader;
-    bb_reader_ = new BBReader(this);
-    insn_reader_ = new InsnReader;
-    load_addr_reader_ = new AddrReader;
-    store_addr_reader_ = new AddrReader;
-    exc_reader_ = new ExcReader;
-    pid_reader_ = new PidReader;
-    method_reader_ = new MethodReader;
-    internal_exc_reader_ = new ExcReader;
-    internal_pid_reader_ = new PidReader;
-    internal_method_reader_ = new MethodReader;
-    blocks_ = NULL;
-    bb_recnum_ = 0;
-    exc_recnum_ = 0;
-    exc_end_ = false;
-    exc_bb_num_ = 0;
-    exc_time_ = 0;
-    exc_num_insns_ = 0;
-    current_pid_ = 0;
-    next_pid_ = 0;
-    next_pid_switch_time_ = 0;
-    post_processing_ = false;
-    dex_hash_ = NULL;
-    load_eof_ = false;
-    load_time_ = 0;
-    load_addr_ = 0;
-    store_eof_ = false;
-    store_time_ = 0;
-    store_addr_ = 0;
-}
-
-TraceReaderBase::~TraceReaderBase()
-{
-    Close();
-    delete bb_reader_;
-    delete insn_reader_;
-    delete load_addr_reader_;
-    delete store_addr_reader_;
-    delete exc_reader_;
-    delete pid_reader_;
-    delete method_reader_;
-    delete internal_exc_reader_;
-    delete internal_pid_reader_;
-    delete internal_method_reader_;
-    if (blocks_) {
-        int num_static_bb = header_->num_static_bb;
-        for (int ii = 0; ii < num_static_bb; ++ii) {
-            delete[] blocks_[ii].insns;
-        }
-        delete[] blocks_;
-    }
-    delete header_;
-    if (dex_hash_ != NULL) {
-        HashTable<DexFileList*>::entry_type *ptr;
-        for (ptr = dex_hash_->GetFirst(); ptr; ptr = dex_hash_->GetNext()) {
-            DexFileList *dexfile = ptr->value;
-            delete[] dexfile->path;
-            int nsymbols = dexfile->nsymbols;
-            DexSym *symbols = dexfile->symbols;
-            for (int ii = 0; ii < nsymbols; ii++) {
-                delete[] symbols[ii].name;
-            }
-            delete[] dexfile->symbols;
-            delete dexfile;
-        }
-    }
-    delete dex_hash_;
-    delete[] static_filename_;
-}
-
-void TraceReaderBase::ReadTraceHeader(FILE *fstream, const char *filename,
-                                      const char *tracename, TraceHeader *header)
-{
-    int rval = fread(header, sizeof(TraceHeader), 1, fstream);
-    if (rval != 1) {
-        perror(filename);
-        exit(1);
-    }
-
-    if (!post_processing_ && strcmp(header->ident, TRACE_IDENT) != 0) {
-        fprintf(stderr, "%s: missing trace header; run 'post_trace %s' first\n",
-                filename, tracename);
-        exit(1);
-    }
-
-    if (header->version != TRACE_VERSION) {
-        fprintf(stderr,
-                "%s: trace header version (%d) does not match compiled tools version (%d)\n",
-                tracename, header->version, TRACE_VERSION);
-        exit(1);
-    }
-
-    convert32(header->version);
-    convert32(header->start_sec);
-    convert32(header->start_usec);
-    convert32(header->pdate);
-    convert32(header->ptime);
-    convert64(header->num_static_bb);
-    convert64(header->num_static_insn);
-    convert64(header->num_dynamic_bb);
-    convert64(header->num_dynamic_insn);
-    convert64(header->elapsed_usecs);
-}
-
-
-void TraceReaderBase::Open(const char *filename)
-{
-    char *fname;
-    FILE *fstream;
-
-    // Open the qtrace.bb file
-    bb_reader_->Open(filename);
-
-    // Open the qtrace.insn file
-    insn_reader_->Open(filename);
-
-    // Open the qtrace.load file and read the first line
-    load_eof_ = load_addr_reader_->Open(filename, ".load");
-    if (!load_eof_)
-        load_eof_ = load_addr_reader_->ReadAddr(&load_time_, &load_addr_);
-
-    // Open the qtrace.store file and read the first line
-    store_eof_ = store_addr_reader_->Open(filename, ".store");
-    if (!store_eof_)
-        store_eof_ = store_addr_reader_->ReadAddr(&store_time_, &store_addr_);
-
-    // Open the qtrace.exc file
-    exc_reader_->Open(filename);
-
-    // Open another file stream to the qtrace.exc file for internal reads.
-    // This allows the caller to also read from the qtrace.exc file.
-    internal_exc_reader_->Open(filename);
-
-    // Open the qtrace.pid file
-    pid_reader_->Open(filename);
-    internal_pid_reader_->Open(filename);
-
-    // Open the qtrace.method file
-    method_reader_->Open(filename);
-    internal_method_reader_->Open(filename);
-
-    // Open the qtrace.static file
-    fname = CreateTracePath(filename, ".static");
-    static_filename_ = fname;
-
-    fstream = fopen(fname, "r");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-    static_fstream_ = fstream;
-
-    // Read the header
-    ReadTraceHeader(fstream, fname, filename, header_);
-
-    // Allocate space for all of the static blocks
-    int num_static_bb = header_->num_static_bb;
-    if (num_static_bb) {
-        blocks_ = new StaticBlock[num_static_bb];
-
-        // Read in all the static blocks
-        for (int ii = 0; ii < num_static_bb; ++ii) {
-            ReadStatic(&blocks_[ii].rec);
-            int num_insns = blocks_[ii].rec.num_insns;
-            if (num_insns > 0) {
-                blocks_[ii].insns = new uint32_t[num_insns];
-                ReadStaticInsns(num_insns, blocks_[ii].insns);
-            } else {
-                blocks_[ii].insns = NULL;
-            }
-        }
-        fseek(static_fstream_, sizeof(TraceHeader), SEEK_SET);
-    }
-
-    ParseDexList(filename);
-
-    // If the dex_hash_ is NULL, then assign it a small hash table
-    // so that we can simply do a Find() operation without having
-    // to check for NULL first.
-    if (dex_hash_ == NULL) {
-        dex_hash_ = new HashTable<DexFileList*>(1, NULL);
-    }
-}
-
-// Reads the list of pid events looking for an mmap of a dex file.
-PidEvent * TraceReaderBase::FindMmapDexFileEvent()
-{
-    static PidEvent event;
-
-    while (!pid_reader_->ReadPidEvent(&event)) {
-        if (event.rec_type == kPidMmap && event.path != event.mmap_path) {
-            return &event;
-        }
-        pid_reader_->Dispose(&event);
-    }
-    return NULL;
-}
-
-static void CopyDexSymbolsToArray(DexFileList *dexfile,
-                                  DexSymList *head, int num_symbols)
-{
-    if (dexfile == NULL)
-        return;
-
-    DexSym *symbols = NULL;
-    if (num_symbols > 0) {
-        symbols = new DexSym[num_symbols];
-    }
-    dexfile->nsymbols = num_symbols;
-    dexfile->symbols = symbols;
-    
-    // Copy the linked-list to the array.
-    DexSymList *next_sym = NULL;
-    int next_index = 0;
-    for (DexSymList *sym = head; sym; sym = next_sym) {
-        next_sym = sym->next;
-        symbols[next_index].addr = sym->sym.addr;
-        symbols[next_index].len = sym->sym.len;
-        symbols[next_index].name = sym->sym.name;
-        next_index += 1;
-        delete sym;
-    }
-}
-
-void TraceReaderBase::ParseDexList(const char *filename)
-{
-    struct stat stat_buf;
-    static const int kBufSize = 4096;
-    char buf[kBufSize];
-    char current_file[kBufSize];
-
-    // Find an example dex file in the list of mmaps
-    PidEvent *event = FindMmapDexFileEvent();
-
-    // Reset the pid_reader to the beginning of the file.
-    pid_reader_->Close();
-    pid_reader_->Open(filename);
-
-    // If there were no mmapped dex files, then there is no need to parse
-    // the dexlist.
-    if (event == NULL)
-        return;
-    char *mmap_dexfile = event->path;
-
-    // Check if the dexlist file exists.  It should have the name
-    // "qtrace.dexlist"
-    char *fname = CreateTracePath(filename, ".dexlist");
-    int rval = stat(fname, &stat_buf);
-    if (rval == -1) {
-        // The file does not exist
-        delete[] fname;
-        return;
-    }
-
-    // Open the qtrace.dexlist file
-    FILE *fstream = fopen(fname, "r");
-    if (fstream == NULL) {
-        perror(fname);
-        exit(1);
-    }
-
-    // First pass: read all the filenames, looking for a match for the
-    // example mmap dex filename.  Also count the files so that we
-    // know how big to make the hash table.
-    char *match = NULL;
-    int num_files = 0;
-    while (fgets(buf, kBufSize, fstream)) {
-        if (buf[0] != '#')
-            continue;
-        num_files += 1;
-        match = strstr(buf + 1, mmap_dexfile);
-
-        // Check that the dexlist file ends with the string mmap_dexfile.
-        // We add one to the length of the mmap_dexfile because buf[]
-        // ends with a newline.  The strlen(mmap_dexfile) computation
-        // could be moved above the loop but it should only ever be
-        // executed once.
-        if (match != NULL && strlen(match) == strlen(mmap_dexfile) + 1)
-            break;
-    }
-
-    // Count the rest of the files
-    while (fgets(buf, kBufSize, fstream)) {
-        if (buf[0] == '#')
-            num_files += 1;
-    }
-
-    if (match == NULL) {
-        fprintf(stderr,
-                "Cannot find the mmapped dex file '%s' in the dexlist\n",
-                mmap_dexfile);
-        exit(1);
-    }
-    delete[] mmap_dexfile;
-
-    // The prefix length includes the leading '#'.
-    int prefix_len = match - buf;
-
-    // Allocate a hash table
-    dex_hash_ = new HashTable<DexFileList*>(4 * num_files, NULL);
-
-    // Reset the file stream to the beginning
-    rewind(fstream);
-
-    // Second pass: read the filenames, stripping off the common prefix.
-    // And read all the (address, method) mappings.  When we read a new
-    // filename, create a new DexFileList and add it to the hash table.
-    // Add new symbol mappings to a linked list until we have the whole
-    // list and then create an array for them so that we can use binary
-    // search on the address to find the symbol name quickly.
-
-    // Use a linked list for storing the symbols
-    DexSymList *head = NULL;
-    DexSymList *prev = NULL;
-    int num_symbols = 0;
-
-    DexFileList *dexfile = NULL;
-    int linenum = 0;
-    while (fgets(buf, kBufSize, fstream)) {
-        linenum += 1;
-        if (buf[0] == '#') {
-            // Everything after the '#' is a filename.
-            // Ignore the common prefix.
-
-            // First, save all the symbols from the previous file (if any).
-            CopyDexSymbolsToArray(dexfile, head, num_symbols);
-
-            dexfile = new DexFileList;
-            // Subtract one because buf[] contains a trailing newline
-            int pathlen = strlen(buf) - prefix_len - 1;
-            char *path = new char[pathlen + 1];
-            strncpy(path, buf + prefix_len, pathlen);
-            path[pathlen] = 0;
-            dexfile->path = path;
-            dexfile->nsymbols = 0;
-            dexfile->symbols = NULL;
-            dex_hash_->Update(path, dexfile);
-            num_symbols = 0;
-            head = NULL;
-            prev = NULL;
-            continue;
-        }
-
-        uint32_t addr;
-        int len, line;
-        char clazz[kBufSize], method[kBufSize], sig[kBufSize], file[kBufSize];
-        if (sscanf(buf, "0x%x %d %s %s %s %s %d",
-                   &addr, &len, clazz, method, sig, file, &line) != 7) {
-            fprintf(stderr, "Cannot parse line %d of file %s:\n%s",
-                    linenum, fname, buf);
-            exit(1);
-        }
-
-        // Concatenate the class name, method name, and signature
-        // plus one for the period separating the class and method.
-        int nchars = strlen(clazz) + strlen(method) + strlen(sig) + 1;
-        char *name = new char[nchars + 1];
-        strcpy(name, clazz);
-        strcat(name, ".");
-        strcat(name, method);
-        strcat(name, sig);
-
-        DexSymList *symbol = new DexSymList;
-        symbol->sym.addr = addr;
-        symbol->sym.len = len;
-        symbol->sym.name = name;
-        symbol->next = NULL;
-
-        // Keep the list in the same order as the file
-        if (head == NULL)
-            head = symbol;
-        if (prev != NULL)
-            prev->next = symbol;
-        prev = symbol;
-        num_symbols += 1;
-    }
-    fclose(fstream);
-
-    // Copy the symbols from the last file.
-    CopyDexSymbolsToArray(dexfile, head, num_symbols);
-    delete[] fname;
-}
-
-// Extracts the pathname to a jar file (or .apk file) from the mmap pathname.
-// An example mmap pathname looks something like this:
-//   /data/dalvik-cache/system@app@TestHarness.apk@classes.dex
-// We want to convert that to this:
-//   /system/app/TestHarness.apk
-// If the pathname is not of the expected form, then NULL is returned.
-// The space for the extracted path is allocated in this routine and should
-// be freed by the caller after it is no longer needed.
-static char *ExtractDexPathFromMmap(const char *mmap_path)
-{
-    const char *end = rindex(mmap_path, '@');
-    if (end == NULL)
-        return NULL;
-    const char *start = rindex(mmap_path, '/');
-    if (start == NULL)
-        return NULL;
-    int len = end - start;
-    char *path = new char[len + 1];
-    strncpy(path, start, len);
-    path[len] = 0;
-
-    // Replace all the occurrences of '@' with '/'
-    for (int ii = 0; ii < len; ii++) {
-        if (path[ii] == '@')
-            path[ii] = '/';
-    }
-    return path;
-}
-
-void TraceReaderBase::Close()
-{
-    bb_reader_->Close();
-    insn_reader_->Close();
-    load_addr_reader_->Close();
-    store_addr_reader_->Close();
-    exc_reader_->Close();
-    pid_reader_->Close();
-    method_reader_->Close();
-    internal_exc_reader_->Close();
-    internal_pid_reader_->Close();
-    internal_method_reader_->Close();
-    fclose(static_fstream_);
-    static_fstream_ = NULL;
-}
-
-void TraceReaderBase::WriteHeader(TraceHeader *header)
-{
-    TraceHeader swappedHeader;
-
-    freopen(static_filename_, "r+", static_fstream_);
-    fseek(static_fstream_, 0, SEEK_SET);
-
-    memcpy(&swappedHeader, header, sizeof(TraceHeader));
-
-    convert32(swappedHeader.version);
-    convert32(swappedHeader.start_sec);
-    convert32(swappedHeader.start_usec);
-    convert32(swappedHeader.pdate);
-    convert32(swappedHeader.ptime);
-    convert64(swappedHeader.num_static_bb);
-    convert64(swappedHeader.num_static_insn);
-    convert64(swappedHeader.num_dynamic_bb);
-    convert64(swappedHeader.num_dynamic_insn);
-    convert64(swappedHeader.elapsed_usecs);
-
-    fwrite(&swappedHeader, sizeof(TraceHeader), 1, static_fstream_);
-}
-
-// Reads the next StaticRec from the trace file (not including the list
-// of instructions).  On end-of-file, this function returns true.
-int TraceReaderBase::ReadStatic(StaticRec *rec)
-{
-    int rval = fread(rec, sizeof(StaticRec), 1, static_fstream_);
-    if (rval != 1) {
-        if (feof(static_fstream_)) {
-            return true;
-        }
-        perror(static_filename_);
-        exit(1);
-    }
-    convert64(rec->bb_num);
-    convert32(rec->bb_addr);
-    convert32(rec->num_insns);
-    return false;
-}
-
-// Reads "num" instructions into the array "insns" which must be large
-// enough to hold the "num" instructions.
-// Returns the actual number of instructions read.  This will usually
-// be "num" but may be less if end-of-file occurred.
-int TraceReaderBase::ReadStaticInsns(int num, uint32_t *insns)
-{
-    if (num == 0)
-        return 0;
-    int rval = fread(insns, sizeof(uint32_t), num, static_fstream_);
-
-    // Convert from little-endian, if necessary
-    for (int ii = 0; ii < num; ++ii)
-        convert32(insns[ii]);
-
-    if (rval != num) {
-        if (feof(static_fstream_)) {
-            return rval;
-        }
-        perror(static_filename_);
-        exit(1);
-    }
-    return rval;
-}
-
-void TraceReaderBase::TruncateLastBlock(uint32_t num_insns)
-{
-    uint32_t insns[kMaxInsnPerBB];
-    StaticRec static_rec;
-    long loc = 0, prev_loc = 0;
-
-    freopen(static_filename_, "r+", static_fstream_);
-    fseek(static_fstream_, sizeof(TraceHeader), SEEK_SET);
-
-    // Find the last record
-    while (1) {
-        prev_loc = loc;
-        loc = ftell(static_fstream_);
-
-        // We don't need to byte-swap static_rec here because we are just
-        // reading the records until we get to the last one.
-        int rval = fread(&static_rec, sizeof(StaticRec), 1, static_fstream_);
-        if (rval != 1)
-            break;
-        ReadStaticInsns(static_rec.num_insns, insns);
-    }
-    if (prev_loc != 0) {
-        fseek(static_fstream_, prev_loc, SEEK_SET);
-        static_rec.num_insns = num_insns;
-
-        // Now we need to byte-swap, but just the field that we changed.
-        convert32(static_rec.num_insns);
-        fwrite(&static_rec, sizeof(StaticRec), 1, static_fstream_);
-        int fd = fileno(static_fstream_);
-        long len = ftell(static_fstream_);
-        len += num_insns * sizeof(uint32_t);
-        ftruncate(fd, len);
-    }
-}
-
-int TraceReaderBase::FindNumInsns(uint64_t bb_num, uint64_t bb_start_time)
-{
-    int num_insns;
-
-    // Read the exception trace file.  "bb_recnum_" is the number of
-    // basic block records that have been read so far, and "exc_recnum_"
-    // is the record number from the exception trace.
-    while (!exc_end_ && exc_recnum_ < bb_recnum_) {
-        uint32_t current_pc, target_pc;
-        uint64_t time;
-
-        exc_end_ = internal_exc_reader_->ReadExc(&time, &current_pc, &exc_recnum_,
-                                                 &target_pc, &exc_bb_num_,
-                                                 &exc_time_, &exc_num_insns_);
-    }
-
-    // If an exception occurred in this basic block, then use the
-    // number of instructions specified in the exception record.
-    if (!exc_end_ && exc_recnum_ == bb_recnum_) {
-        num_insns = exc_num_insns_;
-    } else {
-        // Otherwise, use the number of instructions specified in the
-        // static basic block.
-        num_insns = blocks_[bb_num].rec.num_insns;
-    }
-    return num_insns;
-}
-
-// Finds the current pid for the given time.  This routine reads the pid
-// trace file and assumes that the "time" parameter is monotonically
-// increasing.
-int TraceReaderBase::FindCurrentPid(uint64_t time)
-{
-    PidEvent event;
-
-    if (time < next_pid_switch_time_)
-        return current_pid_;
-
-    current_pid_ = next_pid_;
-    while (1) {
-        if (internal_pid_reader_->ReadPidEvent(&event)) {
-            next_pid_switch_time_ = ~0ull;
-            break;
-        }
-        if (event.rec_type != kPidSwitch)
-            continue;
-        if (event.time > time) {
-            next_pid_ = event.pid;
-            next_pid_switch_time_ = event.time;
-            break;
-        }
-        current_pid_ = event.pid;
-    }
-    return current_pid_;
-}
diff --git a/emulator/qtools/trace_reader.h b/emulator/qtools/trace_reader.h
deleted file mode 100644
index b91cb1b..0000000
--- a/emulator/qtools/trace_reader.h
+++ /dev/null
@@ -1,1559 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef TRACE_READER_H
-#define TRACE_READER_H
-
-#include <string.h>
-#include <inttypes.h>
-#include <elf.h>
-#include <assert.h>
-#include <cxxabi.h>
-#include "read_elf.h"
-#include "trace_reader_base.h"
-#include "hash_table.h"
-
-struct TraceReaderEmptyStruct {
-};
-
-template <class T = TraceReaderEmptyStruct>
-class TraceReader : public TraceReaderBase {
-  public:
-
-    struct region_entry;
-    typedef struct symbol_entry : public T {
-        typedef region_entry region_type;
-
-        // Define flag values
-        static const uint32_t kIsPlt = 0x01;
-        static const uint32_t kIsVectorStart = 0x02;
-        static const uint32_t kIsVectorTable = (kIsPlt | kIsVectorStart);
-        static const uint32_t kIsInterpreter = 0x04;
-        static const uint32_t kIsMethod = 0x08;
-
-        uint32_t        addr;
-
-        // This may hold the name of the interpreted method instead of
-        // the name of the native function if the native function is a
-        // virtual machine interpreter.
-        const char      *name;
-
-        // The symbol for the virtual machine interpreter, or NULL
-        symbol_entry    *vm_sym;
-        region_type     *region;
-        uint32_t        flags;
-    } symbol_type;
-
-    typedef struct region_entry {
-        // Define flag values
-        static const uint32_t kIsKernelRegion           = 0x01;
-        static const uint32_t kSharedSymbols            = 0x02;
-        static const uint32_t kIsLibraryRegion          = 0x04;
-        static const uint32_t kIsUserMappedRegion       = 0x08;
-
-        region_entry() : refs(0), path(NULL), vstart(0), vend(0), base_addr(0),
-                         file_offset(0), flags(0), nsymbols(0), symbols(NULL) {}
-
-        symbol_type    *LookupFunctionByName(char *name) {
-            // Just do a linear search
-            for (int ii = 0; ii < nsymbols; ++ii) {
-                if (strcmp(symbols[ii].name, name) == 0)
-                    return &symbols[ii];
-            }
-            return NULL;
-        }
-
-        region_entry   *MakePrivateCopy(region_entry *dest) {
-            dest->refs = 0;
-            dest->path = Strdup(path);
-            dest->vstart = vstart;
-            dest->vend = vend;
-            dest->base_addr = base_addr;
-            dest->file_offset = file_offset;
-            dest->flags = flags;
-            dest->nsymbols = nsymbols;
-            dest->symbols = symbols;
-            return dest;
-        }
-
-        int             refs;        // reference count
-        char            *path;
-        uint32_t        vstart;
-        uint32_t        vend;
-        uint32_t        base_addr;
-        uint32_t        file_offset;
-        uint32_t        flags;
-        int             nsymbols;
-        symbol_type     *symbols;
-    } region_type;
-
-    typedef typename HashTable<region_type*>::entry_type hash_entry_type;
-
-    class ProcessState {
-      public:
-
-        // The "regions" array below is a pointer to array of pointers to
-        // regions.  The size of the pointer array is kInitialNumRegions,
-        // but grows if needed.  There is a separate region for each mmap
-        // call which includes shared libraries as well as .dex and .jar
-        // files.  In addition, there is a region for the main executable
-        // for this process, as well as a few regions for the kernel.
-        //
-        // If a child process is a clone of a parent process, the
-        // regions array is unused.  Instead, the "addr_manager" pointer is
-        // used to find the process that is the address space manager for
-        // both the parent and child processes.
-        static const int kInitialNumRegions = 10;
-
-        static const int kMaxMethodStackSize = 1000;
-
-        // Define values for the ProcessState flag bits
-        static const int kCalledExec            = 0x01;
-        static const int kCalledExit            = 0x02;
-        static const int kIsClone               = 0x04;
-        static const int kHasKernelRegion       = 0x08;
-        static const int kHasFirstMmap          = 0x10;
-
-        struct methodFrame {
-            uint32_t    addr;
-            bool        isNative;
-        };
-
-        ProcessState() {
-            cpu_time = 0;
-            tgid = 0;
-            pid = 0;
-            parent_pid = 0;
-            exit_val = 0;
-            flags = 0;
-            argc = 0;
-            argv = NULL;
-            name = NULL;
-            nregions = 0;
-            max_regions = 0;
-            // Don't allocate space yet until we know if we are a clone.
-            regions = NULL;
-            parent = NULL;
-            addr_manager = this;
-            next = NULL;
-            current_method_sym = NULL;
-            method_stack_top = 0;
-        }
-
-        ~ProcessState() {
-            delete[] name;
-            if ((flags & kIsClone) != 0) {
-                return;
-            }
-
-            // Free the regions.  We must be careful not to free the symbols
-            // within each region because the symbols are sometimes shared
-            // between multiple regions.  The TraceReader class has a hash
-            // table containing all the unique regions and it will free the
-            // region symbols in its destructor.  We need to free only the
-            // regions and the array of region pointers.
-            //
-            // Each region is also reference-counted.  The count is zero
-            // if no other processes are sharing this region.
-            for (int ii = 0; ii < nregions; ii++) {
-                if (regions[ii]->refs > 0) {
-                    regions[ii]->refs -= 1;
-                    continue;
-                }
-
-                delete regions[ii];
-            }
-
-            delete[] regions;
-
-            for (int ii = 0; ii < argc; ++ii)
-                delete[] argv[ii];
-            delete[] argv;
-        }
-
-        // Dumps the stack contents to standard output.  For debugging.
-        void            DumpStack(FILE *stream);
-
-        uint64_t        cpu_time;
-        uint64_t        start_time;
-        uint64_t        end_time;
-        int             tgid;
-        int             pid;
-        int             parent_pid;
-        int             exit_val;
-        uint32_t        flags;
-        int             argc;
-        char            **argv;
-        const char      *name;
-        int             nregions;        // num regions in use
-        int             max_regions;     // max regions allocated
-        region_type     **regions;
-        ProcessState    *parent;
-        ProcessState    *addr_manager;   // the address space manager process
-        ProcessState    *next;
-        int             method_stack_top;
-        methodFrame     method_stack[kMaxMethodStackSize];
-        symbol_type     *current_method_sym;
-    };
-
-    TraceReader();
-    ~TraceReader();
-
-    void                ReadKernelSymbols(const char *kernel_file);
-    void                CopyKernelRegion(ProcessState *pstate);
-    void                ClearRegions(ProcessState *pstate);
-    void                CopyRegions(ProcessState *parent, ProcessState *child);
-    void                DumpRegions(FILE *stream, ProcessState *pstate);
-    symbol_type         *LookupFunction(int pid, uint32_t addr, uint64_t time);
-    symbol_type         *GetSymbols(int *num_syms);
-    ProcessState        *GetCurrentProcess()            { return current_; }
-    ProcessState        *GetProcesses(int *num_procs);
-    ProcessState        *GetNextProcess();
-    const char          *GetProcessName(int pid);
-    void                SetRoot(const char *root)       { root_ = root; }
-    void                SetDemangle(bool demangle)      { demangle_ = demangle; }
-    bool                ReadMethodSymbol(MethodRec *method_record,
-                                         symbol_type **psym,
-                                         ProcessState **pproc);
-
-  protected:
-    virtual int FindCurrentPid(uint64_t time);
-
-  private:
-
-    static const int kNumPids = 32768;
-    static const uint32_t kIncludeLocalSymbols = 0x1;
-
-    void                AddPredefinedRegion(region_type *region, const char *path,
-                                            uint32_t vstart, uint32_t vend,
-                                            uint32_t base);
-    void                InitRegionSymbols(region_type *region, int nsymbols);
-    void                AddRegionSymbol(region_type *region, int idx,
-                                        uint32_t addr, const char *name,
-                                        uint32_t flags);
-    void                AddPredefinedRegions(ProcessState *pstate);
-    void                demangle_names(int nfuncs, symbol_type *functions);
-    bool                ReadElfSymbols(region_type *region, uint32_t flags);
-    void                AddRegion(ProcessState *pstate, region_type *region);
-    region_type         *FindRegion(uint32_t addr, int nregions,
-                                    region_type **regions);
-    int                 FindRegionIndex(uint32_t addr, int nregions,
-                                         region_type **regions);
-    void                FindAndRemoveRegion(ProcessState *pstate,
-                                            uint32_t vstart, uint32_t vend);
-    symbol_type         *FindFunction(uint32_t addr, int nsyms,
-                                      symbol_type *symbols, bool exact_match);
-    symbol_type         *FindCurrentMethod(int pid, uint64_t time);
-    void                PopulateSymbolsFromDexFile(const DexFileList *dexfile,
-                                                   region_type *region);
-    void                HandlePidEvent(PidEvent *event);
-    void                HandleMethodRecord(ProcessState *pstate,
-                                           MethodRec *method_rec);
-
-    int                 cached_pid_;
-    symbol_type         *cached_func_;
-    symbol_type         unknown_;
-    int                 next_pid_;
-
-    PidEvent            next_pid_event_;
-    ProcessState        *processes_[kNumPids];
-    ProcessState        *current_;
-    MethodRec           next_method_;
-    uint64_t            function_start_time_;
-    const char          *root_;
-    HashTable<region_type*> *hash_;
-    bool                demangle_;
-};
-
-template<class T>
-TraceReader<T>::TraceReader()
-{
-    static PidEvent event_no_action;
-
-    cached_pid_ = -1;
-    cached_func_ = NULL;
-
-    memset(&unknown_, 0, sizeof(symbol_type));
-    unknown_.name = "(unknown)";
-    next_pid_ = 0;
-
-    memset(&event_no_action, 0, sizeof(PidEvent));
-    event_no_action.rec_type = kPidNoAction;
-    next_pid_event_ = event_no_action;
-    for (int ii = 1; ii < kNumPids; ++ii)
-        processes_[ii] = NULL;
-    current_ = new ProcessState;
-    processes_[0] = current_;
-    next_method_.time = 0;
-    next_method_.addr = 0;
-    next_method_.flags = 0;
-    function_start_time_ = 0;
-    root_ = "";
-    hash_ = new HashTable<region_type*>(512);
-    AddPredefinedRegions(current_);
-    demangle_ = true;
-}
-
-template<class T>
-TraceReader<T>::~TraceReader()
-{
-    hash_entry_type *ptr;
-    for (ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
-        region_type *region = ptr->value;
-        // If the symbols are not shared with another region, then delete them.
-        if ((region->flags & region_type::kSharedSymbols) == 0) {
-            int nsymbols = region->nsymbols;
-            for (int ii = 0; ii < nsymbols; ii++) {
-                delete[] region->symbols[ii].name;
-            }
-            delete[] region->symbols;
-        }
-        delete[] region->path;
-
-        // Do not delete the region itself here.  Each region
-        // is reference-counted and deleted by the ProcessState
-        // object that owns it.
-    }
-    delete hash_;
-
-    // Delete the ProcessState objects after the region symbols in
-    // the hash table above so that we still have valid region pointers
-    // when deleting the region symbols.
-    for (int ii = 0; ii < kNumPids; ++ii) {
-        delete processes_[ii];
-    }
-}
-
-// This function is used by the qsort() routine to sort symbols
-// into increasing address order.
-template<class T>
-int cmp_symbol_addr(const void *a, const void *b) {
-    typedef typename TraceReader<T>::symbol_type stype;
-
-    const stype *syma = static_cast<stype const *>(a);
-    const stype *symb = static_cast<stype const *>(b);
-    uint32_t addr1 = syma->addr;
-    uint32_t addr2 = symb->addr;
-    if (addr1 < addr2)
-        return -1;
-    if (addr1 > addr2)
-        return 1;
-
-    // The addresses are the same, sort the symbols into
-    // increasing alphabetical order.  But put symbols that
-    // that start with "_" last.
-    if (syma->name[0] == '_' || symb->name[0] == '_') {
-        // Count the number of leading underscores and sort the
-        // symbol with the most underscores last.
-        int aCount = 0;
-        while (syma->name[aCount] == '_')
-            aCount += 1;
-        int bCount = 0;
-        while (symb->name[bCount] == '_')
-            bCount += 1;
-        if (aCount < bCount) {
-            return -1;
-        }
-        if (aCount > bCount) {
-            return 1;
-        }
-        // If the symbols have the same number of underscores, then
-        // fall through and sort by the whole name.
-    }
-    return strcmp(syma->name, symb->name);
-}
-
-// This function is used by the qsort() routine to sort region entries
-// into increasing address order.
-template<class T>
-int cmp_region_addr(const void *a, const void *b) {
-    typedef typename TraceReader<T>::region_type rtype;
-
-    const rtype *ma = *static_cast<rtype* const *>(a);
-    const rtype *mb = *static_cast<rtype* const *>(b);
-    uint32_t addr1 = ma->vstart;
-    uint32_t addr2 = mb->vstart;
-    if (addr1 < addr2)
-        return -1;
-    if (addr1 == addr2)
-        return 0;
-    return 1;
-}
-
-// This routine returns a new array containing all the symbols.
-template<class T>
-typename TraceReader<T>::symbol_type*
-TraceReader<T>::GetSymbols(int *num_syms)
-{
-    // Count the symbols
-    int nsyms = 0;
-    for (hash_entry_type *ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
-        region_type *region = ptr->value;
-        nsyms += region->nsymbols;
-    }
-    *num_syms = nsyms;
-
-    // Allocate space
-    symbol_type *syms = new symbol_type[nsyms];
-    symbol_type *next_sym = syms;
-
-    // Copy the symbols
-    for (hash_entry_type *ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
-        region_type *region = ptr->value;
-        memcpy(next_sym, region->symbols, region->nsymbols * sizeof(symbol_type));
-        next_sym += region->nsymbols;
-    }
-
-    return syms;
-}
-
-// This routine returns all the valid processes.
-template<class T>
-typename TraceReader<T>::ProcessState*
-TraceReader<T>::GetProcesses(int *num_procs)
-{
-    // Count the valid processes
-    int nprocs = 0;
-    for (int ii = 0; ii < kNumPids; ++ii) {
-        if (processes_[ii])
-            nprocs += 1;
-    }
-
-    // Allocate a new array to hold the valid processes.
-    ProcessState *procs = new ProcessState[nprocs];
-
-    // Copy the processes to the new array.
-    ProcessState *pstate = procs;
-    for (int ii = 0; ii < kNumPids; ++ii) {
-        if (processes_[ii])
-            memcpy(pstate++, processes_[ii], sizeof(ProcessState));
-    }
-
-    *num_procs = nprocs;
-    return procs;
-}
-
-// This routine returns the next valid process, or NULL if there are no
-// more valid processes.
-template<class T>
-typename TraceReader<T>::ProcessState*
-TraceReader<T>::GetNextProcess()
-{
-    while (next_pid_ < kNumPids) {
-        if (processes_[next_pid_])
-            return processes_[next_pid_++];
-        next_pid_ += 1;
-    }
-    next_pid_ = 0;
-    return NULL;
-}
-
-template<class T>
-const char* TraceReader<T>::GetProcessName(int pid)
-{
-    if (pid < 0 || pid >= kNumPids || processes_[pid] == NULL)
-        return "(unknown)";
-    return processes_[pid]->name;
-}
-
-template<class T>
-void TraceReader<T>::AddPredefinedRegion(region_type *region, const char *path,
-                                         uint32_t vstart, uint32_t vend,
-                                         uint32_t base)
-{
-    // Copy the path to make it easy to delete later.
-    int len = strlen(path);
-    region->path = new char[len + 1];
-    strcpy(region->path, path);
-    region->vstart = vstart;
-    region->vend = vend;
-    region->base_addr = base;
-    region->flags = region_type::kIsKernelRegion;
-}
-
-template<class T>
-void TraceReader<T>::InitRegionSymbols(region_type *region, int nsymbols)
-{
-    region->nsymbols = nsymbols;
-    region->symbols = new symbol_type[nsymbols];
-    memset(region->symbols, 0, nsymbols * sizeof(symbol_type));
-}
-
-template<class T>
-void TraceReader<T>::AddRegionSymbol(region_type *region, int idx,
-                                     uint32_t addr, const char *name,
-                                     uint32_t flags)
-{
-    region->symbols[idx].addr = addr;
-    region->symbols[idx].name = Strdup(name);
-    region->symbols[idx].vm_sym = NULL;
-    region->symbols[idx].region = region;
-    region->symbols[idx].flags = flags;
-}
-
-template<class T>
-void TraceReader<T>::AddPredefinedRegions(ProcessState *pstate)
-{
-    region_type *region = new region_type;
-    AddPredefinedRegion(region, "(bootloader)", 0, 0x14, 0);
-    InitRegionSymbols(region, 2);
-    AddRegionSymbol(region, 0, 0, "(bootloader_start)", 0);
-    AddRegionSymbol(region, 1, 0x14, "(bootloader_end)", 0);
-    AddRegion(pstate, region);
-    hash_->Update(region->path, region);
-
-    region = new region_type;
-    AddPredefinedRegion(region, "(exception vectors)", 0xffff0000, 0xffff0500,
-                        0xffff0000);
-    InitRegionSymbols(region, 2);
-    AddRegionSymbol(region, 0, 0x0, "(vector_start)",
-                    symbol_type::kIsVectorStart);
-    AddRegionSymbol(region, 1, 0x500, "(vector_end)", 0);
-    AddRegion(pstate, region);
-    hash_->Update(region->path, region);
-
-    region = new region_type;
-    AddPredefinedRegion(region, "(atomic ops)", 0xffff0f80, 0xffff1000,
-                        0xffff0f80);
-    // Mark this region as also being mapped in user-space.
-    // This isn't used anywhere in this code but client code can test for
-    // this flag and decide whether to treat this as kernel or user code.
-    region->flags |= region_type::kIsUserMappedRegion;
-
-    InitRegionSymbols(region, 4);
-    AddRegionSymbol(region, 0, 0x0, "(kuser_atomic_inc)", 0);
-    AddRegionSymbol(region, 1, 0x20, "(kuser_atomic_dec)", 0);
-    AddRegionSymbol(region, 2, 0x40, "(kuser_cmpxchg)", 0);
-    AddRegionSymbol(region, 3, 0x80, "(kuser_end)", 0);
-    AddRegion(pstate, region);
-    hash_->Update(region->path, region);
-}
-
-template<class T>
-void TraceReader<T>::ReadKernelSymbols(const char *kernel_file)
-{
-    region_type *region = new region_type;
-    // Copy the path to make it easy to delete later.
-    int len = strlen(kernel_file);
-    region->path = new char[len + 1];
-    strcpy(region->path, kernel_file);
-    region->flags = region_type::kIsKernelRegion;
-    ReadElfSymbols(region, kIncludeLocalSymbols);
-    region->vend = 0xffff0000;
-    AddRegion(processes_[0], region);
-    processes_[0]->flags |= ProcessState::kHasKernelRegion;
-    hash_->Update(region->path, region);
-}
-
-template<class T>
-void TraceReader<T>::demangle_names(int nfuncs, symbol_type *functions)
-{
-    char *demangled;
-    int status;
-
-    for (int ii = 0; ii < nfuncs; ++ii) {
-        demangled = NULL;
-        int len = strlen(functions[ii].name);
-
-        // If we don't check for "len > 1" then the demangler will incorrectly
-        // expand 1-letter function names.  For example, "b" becomes "bool",
-        // "c" becomes "char" and "d" becomes "double".  Also check that the
-        // first character is an underscore.  Otherwise, on some strings
-        // the demangler will try to read past the end of the string (because
-        // the string is not really a C++ mangled name) and valgrind will
-        // complain.
-        if (demangle_ && len > 1 && functions[ii].name[0] == '_') {
-            demangled = abi::__cxa_demangle(functions[ii].name, 0, NULL,
-                                            &status);
-        }
-
-        if (demangled != NULL) {
-            delete[] functions[ii].name;
-            functions[ii].name = Strdup(demangled);
-            free(demangled);
-        }
-    }
-}
-
-// Adds the symbols from the given ELF file to the given process.
-// Returns false if the file was not an ELF file or if there was an
-// error trying to read the sections of the ELF file.
-template<class T>
-bool TraceReader<T>::ReadElfSymbols(region_type *region, uint32_t flags)
-{
-    static char full_path[4096];
-    Elf32_Shdr  *symtab, *symstr;
-    Elf32_Ehdr  *hdr;
-    Elf32_Shdr  *shdr;
-
-    full_path[0] = 0;
-    if (root_ && strcmp(root_, "/")) {
-        strcpy(full_path, root_);
-    }
-    strcat(full_path, region->path);
-    FILE *fobj = fopen(full_path, "r");
-    if(fobj == NULL) {
-    EmptyRegion:
-        // we need to create an (unknown) symbol with address 0, otherwise some
-        // other parts of the trace reader will simply crash when dealing with
-        // an empty region
-        region->vstart = 0;
-        region->nsymbols = 1;
-        region->symbols  = new symbol_type[1];
-        memset(region->symbols, 0, sizeof(symbol_type));
-
-        region->symbols[0].addr   = 0;
-        region->symbols[0].name   = Strdup("(unknown)");
-        region->symbols[0].vm_sym = NULL;
-        region->symbols[0].region = region;
-        region->symbols[0].flags  = 0;
-
-        if (fobj != NULL)
-            fclose(fobj);
-        return false;
-    }
-
-    hdr = ReadElfHeader(fobj);
-    if (hdr == NULL) {
-        fprintf(stderr, "Cannot read ELF header from '%s'\n", full_path);
-        goto EmptyRegion;
-    }
-
-    shdr = ReadSectionHeaders(hdr, fobj);
-    if(shdr == NULL) {
-        fprintf(stderr, "Can't read section headers from executable\n");
-        goto EmptyRegion;
-    }
-    char *section_names = ReadStringTable(hdr, shdr, fobj);
-
-    // Get the symbol table section
-    symtab = FindSymbolTableSection(hdr, shdr, section_names);
-    if (symtab == NULL || symtab->sh_size == 0) {
-        fprintf(stderr, "Can't read symbol table from '%s'\n", full_path);
-        goto EmptyRegion;
-    }
-
-    // Get the symbol string table section
-    symstr = FindSymbolStringTableSection(hdr, shdr, section_names);
-    if (symstr == NULL || symstr->sh_size == 0) {
-        fprintf(stderr, "Can't read symbol string table from '%s'\n", full_path);
-        goto EmptyRegion;
-    }
-
-    // Load the symbol string table data
-    char *symbol_names = new char[symstr->sh_size];
-    ReadSection(symstr, symbol_names, fobj);
-
-    int num_entries = symtab->sh_size / symtab->sh_entsize;
-    Elf32_Sym *elf_symbols = new Elf32_Sym[num_entries];
-    ReadSection(symtab, elf_symbols, fobj);
-    AdjustElfSymbols(hdr, elf_symbols, num_entries);
-#if 0
-    printf("size: %d, ent_size: %d, num_entries: %d\n",
-           symtab->sh_size, symtab->sh_entsize, num_entries);
-#endif
-    int nfuncs = 0;
-
-    // Allocate space for all of the symbols for now.  We will
-    // reallocate space for just the function symbols after we
-    // know how many there are.  Also, make sure there is room
-    // for some extra symbols, including the text section names.
-    int num_alloc = num_entries + hdr->e_shnum + 1;
-    symbol_type *func_symbols = new symbol_type[num_alloc];
-    memset(func_symbols, 0, num_alloc * sizeof(symbol_type));
-
-    // If this is the shared library for a virtual machine, then
-    // set the IsInterpreter flag for all symbols in that shared library.
-    // This will allow us to replace the symbol names with the name of
-    // the currently executing method on the virtual machine.
-    int symbol_flags = 0;
-    char *cp = strrchr(region->path, '/');
-    if (cp != NULL) {
-        // Move past the '/'
-        cp += 1;
-    } else {
-        // There was no '/', so use the whole path
-        cp = region->path;
-    }
-    if (strcmp(cp, "libdvm.so") == 0) {
-        symbol_flags = symbol_type::kIsInterpreter;
-    }
-
-    bool zero_found = false;
-    for (int ii = 1; ii < num_entries; ++ii) {
-        int idx = elf_symbols[ii].st_name;
-
-        // If the symbol does not have a name, or if the name starts with a
-        // dollar sign ($), then skip it.
-        if (idx == 0 || symbol_names[idx] == 0 || symbol_names[idx] == '$')
-            continue;
-
-        // If the section index is not executable, then skip it.
-        uint32_t section = elf_symbols[ii].st_shndx;
-        if (section == 0 || section >= hdr->e_shnum)
-            continue;
-        if ((shdr[section].sh_flags & SHF_EXECINSTR) == 0)
-            continue;
-
-        uint8_t sym_type = ELF32_ST_TYPE(elf_symbols[ii].st_info);
-        uint8_t sym_bind = ELF32_ST_BIND(elf_symbols[ii].st_info);
-
-        // Allow the caller to decide if we want local non-function
-        // symbols to be included.  We currently include these symbols
-        // only for the kernel, where it is useful because the kernel
-        // has lots of assembly language labels that have meaningful names.
-        if ((flags & kIncludeLocalSymbols) == 0 && sym_bind == STB_LOCAL
-            && sym_type != STT_FUNC) {
-            continue;
-        }
-#if 0
-        printf("%08x %x %x %s\n",
-               elf_symbols[ii].st_value,
-               sym_bind,
-               sym_type,
-               &symbol_names[idx]);
-#endif
-        if (sym_type != STT_FUNC && sym_type != STT_NOTYPE)
-            continue;
-
-        if (elf_symbols[ii].st_value == 0)
-            zero_found = true;
-
-        // The address of thumb functions seem to have the low bit set,
-        // even though the instructions are really at an even address.
-        uint32_t addr = elf_symbols[ii].st_value & ~0x1;
-        func_symbols[nfuncs].addr = addr;
-        func_symbols[nfuncs].name = Strdup(&symbol_names[idx]);
-        func_symbols[nfuncs].flags = symbol_flags;
-
-        nfuncs += 1;
-    }
-
-    // Add a [0, "(unknown)"] symbol pair if there is not already a
-    // symbol with the address zero.  We don't need to reallocate space
-    // because we already have more than we need.
-    if (!zero_found) {
-        func_symbols[nfuncs].addr = 0;
-        func_symbols[nfuncs].name = Strdup("(0 unknown)");
-        nfuncs += 1;
-    }
-
-    // Add another entry at the end
-    func_symbols[nfuncs].addr = 0xffffffff;
-    func_symbols[nfuncs].name = Strdup("(end)");
-    nfuncs += 1;
-
-    // Add in the names of the text sections, but only if there
-    // are no symbols with that address already.
-    for (int section = 0; section < hdr->e_shnum; ++section) {
-        if ((shdr[section].sh_flags & SHF_EXECINSTR) == 0)
-            continue;
-
-        uint32_t addr = shdr[section].sh_addr;
-        // Search for a symbol with a matching address.  The symbols aren't
-        // sorted yet so we just search the whole list.
-        int ii;
-        for (ii = 0; ii < nfuncs; ++ii) {
-            if (addr == func_symbols[ii].addr)
-                break;
-        }
-        if (ii == nfuncs) {
-            // Symbol at address "addr" does not exist, so add the text
-            // section name.  This will usually add the ".plt" section
-            // (procedure linkage table).
-            int idx = shdr[section].sh_name;
-            func_symbols[nfuncs].addr = addr;
-            func_symbols[nfuncs].name = Strdup(&section_names[idx]);
-            if (strcmp(func_symbols[nfuncs].name, ".plt") == 0) {
-                func_symbols[nfuncs].flags |= symbol_type::kIsPlt;
-                // Change the name of the symbol to include the
-                // name of the library.  Otherwise we will have lots
-                // of ".plt" symbols.
-                int len = strlen(region->path);
-                len += strlen(":.plt");
-                char *name = new char[len + 1];
-                strcpy(name, region->path);
-                strcat(name, ":.plt");
-                delete[] func_symbols[nfuncs].name;
-                func_symbols[nfuncs].name = name;
-
-                // Check if this is part of the virtual machine interpreter
-                char *cp = strrchr(region->path, '/');
-                if (cp != NULL) {
-                    // Move past the '/'
-                    cp += 1;
-                } else {
-                    // There was no '/', so use the whole path
-                    cp = region->path;
-                }
-                if (strcmp(cp, "libdvm.so") == 0) {
-                    func_symbols[nfuncs].flags |= symbol_type::kIsInterpreter;
-                }
-            }
-            nfuncs += 1;
-        }
-    }
-
-    // Allocate just the space we need now that we know exactly
-    // how many symbols we have.
-    symbol_type *functions = new symbol_type[nfuncs];
-
-    // Copy the symbols to the functions array
-    memcpy(functions, func_symbols, nfuncs * sizeof(symbol_type));
-    delete[] func_symbols;
-
-    // Assign the region pointers
-    for (int ii = 0; ii < nfuncs; ++ii) {
-        functions[ii].region = region;
-    }
-
-    // Sort the symbols into increasing address order
-    qsort(functions, nfuncs, sizeof(symbol_type), cmp_symbol_addr<T>);
-
-    // If there are multiple symbols with the same address, then remove
-    // the duplicates.  First, count the number of duplicates.
-    uint32_t prev_addr = ~0;
-    int num_duplicates = 0;
-    for (int ii = 0; ii < nfuncs; ++ii) {
-        if (prev_addr == functions[ii].addr)
-            num_duplicates += 1;
-        prev_addr = functions[ii].addr;
-    }
- 
-    if (num_duplicates > 0) {
-        int num_uniq = nfuncs - num_duplicates;
-
-        // Allocate space for the unique functions
-        symbol_type *uniq_functions = new symbol_type[num_uniq];
-
-        // Copy the unique functions
-        prev_addr = ~0;
-        int next_uniq = 0;
-        for (int ii = 0; ii < nfuncs; ++ii) {
-            if (prev_addr == functions[ii].addr) {
-                delete[] functions[ii].name;
-                continue;
-            }
-            memcpy(&uniq_functions[next_uniq++], &functions[ii],
-                   sizeof(symbol_type));
-            prev_addr = functions[ii].addr;
-        }
-        assert(next_uniq == num_uniq);
-
-        delete[] functions;
-        functions = uniq_functions;
-        nfuncs = num_uniq;
-    }
-
-    // Finally, demangle all of the symbol names
-    demangle_names(nfuncs, functions);
-
-    uint32_t min_addr = 0;
-    if (!zero_found)
-        min_addr = functions[1].addr;
-    if (region->vstart == 0)
-        region->vstart = min_addr;
-    region->nsymbols = nfuncs;
-    region->symbols = functions;
-
-#if 0
-    printf("%s num symbols: %d min_addr: 0x%x\n", region->path, nfuncs, min_addr);
-    for (int ii = 0; ii < nfuncs; ++ii) {
-        printf("0x%08x %s\n", functions[ii].addr, functions[ii].name);
-    }
-#endif
-    delete[] elf_symbols;
-    delete[] symbol_names;
-    delete[] section_names;
-    delete[] shdr;
-    delete hdr;
-    fclose(fobj);
-    
-    return true;
-}
-
-template<class T>
-void TraceReader<T>::CopyKernelRegion(ProcessState *pstate)
-{
-    ProcessState *manager = pstate->addr_manager;
-    if (manager->flags & ProcessState::kHasKernelRegion)
-        return;
-
-    int nregions = processes_[0]->nregions;
-    region_type **regions = processes_[0]->regions;
-    for (int ii = 0; ii < nregions; ii++) {
-        if (regions[ii]->flags & region_type::kIsKernelRegion) {
-            AddRegion(manager, regions[ii]);
-            regions[ii]->refs += 1;
-        }
-    }
-    manager->flags |= ProcessState::kHasKernelRegion;
-}
-
-template<class T>
-void TraceReader<T>::ClearRegions(ProcessState *pstate)
-{
-    assert(pstate->pid != 0);
-    int nregions = pstate->nregions;
-    region_type **regions = pstate->regions;
-
-    // Decrement the reference count on all the regions
-    for (int ii = 0; ii < nregions; ii++) {
-        if (regions[ii]->refs > 0) {
-            regions[ii]->refs -= 1;
-            continue;
-        }
-
-        delete regions[ii];
-    }
-    delete[] pstate->regions;
-    pstate->regions = NULL;
-    pstate->nregions = 0;
-    pstate->max_regions = 0;
-    pstate->addr_manager = pstate;
-    pstate->flags &= ~ProcessState::kIsClone;
-    pstate->flags &= ~ProcessState::kHasKernelRegion;
-    CopyKernelRegion(pstate);
-}
-
-template<class T>
-void TraceReader<T>::AddRegion(ProcessState *pstate, region_type *region)
-{
-    ProcessState *manager = pstate->addr_manager;
-    if (manager->regions == NULL) {
-        manager->max_regions = ProcessState::kInitialNumRegions;
-        manager->regions = new region_type*[manager->max_regions];
-        manager->nregions = 0;
-    }
-
-    // Check if we need to grow the array
-    int nregions = manager->nregions;
-    int max_regions = manager->max_regions;
-    if (nregions >= max_regions) {
-        max_regions <<= 1;
-        manager->max_regions = max_regions;
-        region_type **regions = new region_type*[max_regions];
-        for (int ii = 0; ii < nregions; ii++) {
-            regions[ii] = manager->regions[ii];
-        }
-        delete[] manager->regions;
-        manager->regions = regions;
-    }
-
-    // Add the new region to the end of the array and resort
-    manager->regions[nregions] = region;
-    nregions += 1;
-    manager->nregions = nregions;
-
-    // Resort the regions into increasing start address
-    qsort(manager->regions, nregions, sizeof(region_type*), cmp_region_addr<T>);
-}
-
-template<class T>
-void TraceReader<T>::FindAndRemoveRegion(ProcessState *pstate, uint32_t vstart,
-                                         uint32_t vend)
-{
-    ProcessState *manager = pstate->addr_manager;
-    int nregions = manager->nregions;
-    int index = FindRegionIndex(vstart, nregions, manager->regions);
-    region_type *region = manager->regions[index];
-
-    // If the region does not contain [vstart,vend], then return.
-    if (vstart < region->vstart || vend > region->vend)
-        return;
-
-    // If the existing region exactly matches the address range [vstart,vend]
-    // then remove the whole region.
-    if (vstart == region->vstart && vend == region->vend) {
-        // The regions are reference-counted.
-        if (region->refs == 0) {
-            // Free the region
-            hash_->Remove(region->path);
-            delete region;
-        } else {
-            region->refs -= 1;
-        }
-
-        if (nregions > 1) {
-            // Assign the region at the end of the array to this empty slot
-            manager->regions[index] = manager->regions[nregions - 1];
-
-            // Resort the regions into increasing start address
-            qsort(manager->regions, nregions - 1, sizeof(region_type*),
-                  cmp_region_addr<T>);
-        }
-        manager->nregions = nregions - 1;
-        return;
-    }
-
-    // If the existing region contains the given range and ends at the
-    // end of the given range (a common case for some reason), then
-    // truncate the existing region so that it ends at vstart (because
-    // we are deleting the range [vstart,vend]).
-    if (vstart > region->vstart && vend == region->vend) {
-        region_type *truncated;
-
-        if (region->refs == 0) {
-            // This region is not shared, so truncate it directly
-            truncated = region;
-        } else {
-            // This region is shared, so make a copy that we can truncate
-            region->refs -= 1;
-            truncated = region->MakePrivateCopy(new region_type);
-        }
-        truncated->vend = vstart;
-        manager->regions[index] = truncated;
-    }
-}
-
-template<class T>
-void TraceReader<T>::CopyRegions(ProcessState *parent, ProcessState *child)
-{
-    // Copy the parent's address space
-    ProcessState *manager = parent->addr_manager;
-    int nregions = manager->nregions;
-    child->nregions = nregions;
-    child->max_regions = manager->max_regions;
-    region_type **regions = new region_type*[manager->max_regions];
-    child->regions = regions;
-    memcpy(regions, manager->regions, nregions * sizeof(region_type*));
-
-    // Increment the reference count on all the regions
-    for (int ii = 0; ii < nregions; ii++) {
-        regions[ii]->refs += 1;
-    }
-}
-
-template<class T>
-void TraceReader<T>::DumpRegions(FILE *stream, ProcessState *pstate) {
-    ProcessState *manager = pstate->addr_manager;
-    for (int ii = 0; ii < manager->nregions; ++ii) {
-        fprintf(stream, "  %08x - %08x offset: %5x  nsyms: %4d refs: %d %s\n",
-                manager->regions[ii]->vstart,
-                manager->regions[ii]->vend,
-                manager->regions[ii]->file_offset,
-                manager->regions[ii]->nsymbols,
-                manager->regions[ii]->refs,
-                manager->regions[ii]->path);
-    }
-}
-
-template<class T>
-typename TraceReader<T>::region_type *
-TraceReader<T>::FindRegion(uint32_t addr, int nregions, region_type **regions)
-{
-    int high = nregions;
-    int low = -1;
-    while (low + 1 < high) {
-        int middle = (high + low) / 2;
-        uint32_t middle_addr = regions[middle]->vstart;
-        if (middle_addr == addr)
-            return regions[middle];
-        if (middle_addr > addr)
-            high = middle;
-        else
-            low = middle;
-    }
-
-    // If we get here then we did not find an exact address match.  So use
-    // the closest region address that is less than the given address.
-    if (low < 0)
-        low = 0;
-    return regions[low];
-}
-
-template<class T>
-int TraceReader<T>::FindRegionIndex(uint32_t addr, int nregions,
-                                    region_type **regions)
-{
-    int high = nregions;
-    int low = -1;
-    while (low + 1 < high) {
-        int middle = (high + low) / 2;
-        uint32_t middle_addr = regions[middle]->vstart;
-        if (middle_addr == addr)
-            return middle;
-        if (middle_addr > addr)
-            high = middle;
-        else
-            low = middle;
-    }
-
-    // If we get here then we did not find an exact address match.  So use
-    // the closest region address that is less than the given address.
-    if (low < 0)
-        low = 0;
-    return low;
-}
-
-template<class T>
-typename TraceReader<T>::symbol_type *
-TraceReader<T>::FindFunction(uint32_t addr, int nsyms, symbol_type *symbols,
-                             bool exact_match)
-{
-    int high = nsyms;
-    int low = -1;
-    while (low + 1 < high) {
-        int middle = (high + low) / 2;
-        uint32_t middle_addr = symbols[middle].addr;
-        if (middle_addr == addr)
-            return &symbols[middle];
-        if (middle_addr > addr)
-            high = middle;
-        else
-            low = middle;
-    }
-
-    // If we get here then we did not find an exact address match.  So use
-    // the closest function address that is less than the given address.
-    // We added a symbol with address zero so if there is no known
-    // function containing the given address, then we will return the
-    // "(unknown)" symbol.
-    if (low >= 0 && !exact_match)
-        return &symbols[low];
-    return NULL;
-}
-
-template<class T>
-typename TraceReader<T>::symbol_type *
-TraceReader<T>::LookupFunction(int pid, uint32_t addr, uint64_t time)
-{
-    // Check if the previous match is still a good match.
-    if (cached_pid_ == pid) {
-        uint32_t vstart = cached_func_->region->vstart;
-        uint32_t vend = cached_func_->region->vend;
-        if (addr >= vstart && addr < vend) {
-            uint32_t sym_addr = addr - cached_func_->region->base_addr;
-            if (sym_addr >= cached_func_->addr
-                && sym_addr < (cached_func_ + 1)->addr) {
-
-                // Check if there is a Java method on the method trace.
-                symbol_type *sym = FindCurrentMethod(pid, time);
-                if (sym != NULL) {
-                    sym->vm_sym = cached_func_;
-                    return sym;
-                }
-                return cached_func_;
-            }
-        }
-    }
-
-    ProcessState *pstate = processes_[pid];
-    if (pstate == NULL) {
-        // There is no process state for the specified pid.
-        // This should never happen.
-        cached_pid_ = -1;
-        cached_func_ = NULL;
-        return NULL;
-    }
-    ProcessState *manager = pstate->addr_manager;
-    cached_pid_ = pid;
-    region_type *region = FindRegion(addr, manager->nregions, manager->regions);
-    uint32_t sym_addr = addr - region->base_addr;
-
-    cached_func_ = FindFunction(sym_addr, region->nsymbols, region->symbols,
-                                false /* no exact match */);
-    if (cached_func_ != NULL) {
-        cached_func_->region = region;
-
-        // Check if there is a Java method on the method trace.
-        symbol_type *sym = FindCurrentMethod(pid, time);
-        if (sym != NULL) {
-            sym->vm_sym = cached_func_;
-            return sym;
-        }
-    }
-
-    return cached_func_;
-}
-
-template <class T>
-void TraceReader<T>::HandlePidEvent(PidEvent *event)
-{
-    switch (event->rec_type) {
-    case kPidFork:
-    case kPidClone:
-        // event->pid is the process id of the child
-        if (event->pid >= kNumPids) {
-            fprintf(stderr, "Error: pid (%d) too large\n", event->pid);
-            exit(1);
-        }
-        // Create a new ProcessState struct for the child
-        // and link it in at the front of the list for that
-        // pid.
-        {
-            ProcessState *child = new ProcessState;
-            processes_[event->pid] = child;
-            child->pid = event->pid;
-            child->tgid = event->tgid;
-
-            // Link the new child at the front of the list (only needed if
-            // pids wrap around, which will probably never happen when
-            // tracing because it would take so long).
-            child->next = processes_[event->pid];
-            child->parent_pid = current_->pid;
-            child->parent = current_;
-            child->start_time = event->time;
-            child->name = Strdup(current_->name);
-            if (event->rec_type == kPidFork) {
-                CopyRegions(current_, child);
-            } else {
-                // Share the parent's address space
-                child->flags |= ProcessState::kIsClone;
-
-                // The address space manager for the clone is the same
-                // as the address space manager for the parent.  This works
-                // even if the child later clones itself.
-                child->addr_manager = current_->addr_manager;
-            }
-        }
-        break;
-    case kPidSwitch:
-        // event->pid is the process id of the process we are
-        // switching to.
-        {
-            uint64_t elapsed = event->time - function_start_time_;
-            function_start_time_ = event->time;
-            current_->cpu_time += elapsed;
-        }
-        if (current_->flags & ProcessState::kCalledExit)
-            current_->end_time = event->time;
-
-        if (event->pid >= kNumPids) {
-            fprintf(stderr, "Error: pid (%d) too large\n", event->pid);
-            exit(1);
-        }
-
-        // If the process we are switching to does not exist, then
-        // create one.  This can happen because the tracing code does
-        // not start tracing from the very beginning of the kernel.
-        current_ = processes_[event->pid];
-        if (current_ == NULL) {
-            current_ = new ProcessState;
-            processes_[event->pid] = current_;
-            current_->pid = event->pid;
-            current_->start_time = event->time;
-            CopyKernelRegion(current_);
-        }
-#if 0
-        {
-            printf("switching to p%d\n", current_->pid);
-            ProcessState *manager = current_->addr_manager;
-            for (int ii = 0; ii < manager->nregions; ++ii) {
-                printf("  %08x - %08x offset: %d nsyms: %4d %s\n",
-                       manager->regions[ii]->vstart,
-                       manager->regions[ii]->vend,
-                       manager->regions[ii]->file_offset,
-                       manager->regions[ii]->nsymbols,
-                       manager->regions[ii]->path);
-            }
-        }
-#endif
-        break;
-    case kPidExit:
-        current_->exit_val = event->pid;
-        current_->flags |= ProcessState::kCalledExit;
-        break;
-    case kPidMunmap:
-        FindAndRemoveRegion(current_, event->vstart, event->vend);
-        break;
-    case kPidMmap:
-        {
-            region_type *region;
-            region_type *existing_region = hash_->Find(event->path);
-            if (existing_region == NULL
-                || existing_region->vstart != event->vstart
-                || existing_region->vend != event->vend
-                || existing_region->file_offset != event->offset) {
-                // Create a new region and add it to the current process'
-                // address space.
-                region = new region_type;
-
-                // The event->path is allocated by ReadPidEvent() and owned
-                // by us.
-                region->path = event->path;
-                region->vstart = event->vstart;
-                region->vend = event->vend;
-                region->file_offset = event->offset;
-                if (existing_region == NULL) {
-                    DexFileList *dexfile = dex_hash_->Find(event->path);
-                    if (dexfile != NULL) {
-                        PopulateSymbolsFromDexFile(dexfile, region);
-                    } else {
-                        ReadElfSymbols(region, 0);
-                    }
-                    hash_->Update(region->path, region);
-                } else {
-                    region->nsymbols = existing_region->nsymbols;
-                    region->symbols = existing_region->symbols;
-                    region->flags |= region_type::kSharedSymbols;
-                }
-
-                // The base_addr is subtracted from an address before the
-                // symbol name lookup and is either zero or event->vstart.
-                // HACK: Determine if base_addr is non-zero by looking at the
-                // second symbol address (skip the first symbol because that is
-                // the special symbol "(unknown)" with an address of zero).
-                if (region->nsymbols > 2 && region->symbols[1].addr < event->vstart)
-                    region->base_addr = event->vstart;
-
-                // Treat all mmapped regions after the first as "libraries".
-                // Profiling tools can test for this property.
-                if (current_->flags & ProcessState::kHasFirstMmap)
-                    region->flags |= region_type::kIsLibraryRegion;
-                else
-                    current_->flags |= ProcessState::kHasFirstMmap;
-#if 0
-                printf("%s vstart: 0x%x vend: 0x%x offset: 0x%x\n",
-                       region->path, region->vstart, region->vend, region->file_offset);
-#endif
-            } else {
-                region = existing_region;
-                region->refs += 1;
-                delete[] event->path;
-            }
-            AddRegion(current_, region);
-        }
-        break;
-    case kPidExec:
-        if (current_->argc > 0) {
-            for (int ii = 0; ii < current_->argc; ii++) {
-                delete[] current_->argv[ii];
-            }
-            delete[] current_->argv;
-        }
-        delete[] current_->name;
-
-        current_->argc = event->argc;
-        current_->argv = event->argv;
-        current_->name = Strdup(current_->argv[0]);
-        current_->flags |= ProcessState::kCalledExec;
-        ClearRegions(current_);
-        break;
-    case kPidName:
-    case kPidKthreadName:
-        {
-            ProcessState *pstate = processes_[event->pid];
-            if (pstate == NULL) {
-                pstate = new ProcessState;
-                if (event->rec_type == kPidKthreadName) {
-                    pstate->tgid = event->tgid;
-                }
-                pstate->pid = event->pid;
-                pstate->start_time = event->time;
-                processes_[event->pid] = pstate;
-                CopyKernelRegion(pstate);
-            } else {
-                delete[] pstate->name;
-            }
-            pstate->name = event->path;
-        }
-        break;
-    case kPidNoAction:
-        break;
-    case kPidSymbolAdd:
-        delete[] event->path;
-        break;
-    case kPidSymbolRemove:
-        break;
-    }
-}
-
-// Finds the current pid for the given time.  This routine reads the pid
-// trace file and assumes that the "time" parameter is monotonically
-// increasing.
-template <class T>
-int TraceReader<T>::FindCurrentPid(uint64_t time)
-{
-    if (time < next_pid_event_.time)
-        return current_->pid;
-
-    while (1) {
-        HandlePidEvent(&next_pid_event_);
-
-        if (internal_pid_reader_->ReadPidEvent(&next_pid_event_)) {
-            next_pid_event_.time = ~0ull;
-            break;
-        }
-        if (next_pid_event_.time > time)
-            break;
-    }
-    return current_->pid;
-}
-
-template <class T>
-void TraceReader<T>::ProcessState::DumpStack(FILE *stream)
-{
-    const char *native;
-    for (int ii = 0; ii < method_stack_top; ii++) {
-        native = method_stack[ii].isNative ? "n" : " ";
-        fprintf(stream, "%2d: %s 0x%08x\n", ii, native, method_stack[ii].addr);
-    }
-}
-
-template <class T>
-void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
-                                        MethodRec *method_rec)
-{
-    uint32_t addr;
-    int top = pstate->method_stack_top;
-    int flags = method_rec->flags;
-    bool isNative;
-    if (flags == kMethodEnter || flags == kNativeEnter) {
-        // Push this method on the stack
-        if (top >= pstate->kMaxMethodStackSize) {
-            fprintf(stderr, "Stack overflow at time %llu\n", method_rec->time);
-            exit(1);
-        }
-        pstate->method_stack[top].addr = method_rec->addr;
-        isNative = (flags == kNativeEnter);
-        pstate->method_stack[top].isNative = isNative;
-        pstate->method_stack_top = top + 1;
-        addr = method_rec->addr;
-    } else {
-        if (top <= 0) {
-            // If the stack underflows, then set the current method to NULL.
-            pstate->current_method_sym = NULL;
-            return;
-        }
-        top -= 1;
-        addr = pstate->method_stack[top].addr;
-
-        // If this is a non-native method then the address we are popping should
-        // match the top-of-stack address.  Native pops don't always match the
-        // address of the native push for some reason.
-        if (addr != method_rec->addr && !pstate->method_stack[top].isNative) {
-            fprintf(stderr,
-                    "Stack method (0x%x) at index %d does not match trace record (0x%x) at time %llu\n",
-                    addr, top, method_rec->addr, method_rec->time);
-            pstate->DumpStack(stderr);
-            exit(1);
-        }
-
-        // If we are popping a native method, then the top-of-stack should also
-        // be a native method.
-        bool poppingNative = (flags == kNativeExit) || (flags == kNativeException);
-        if (poppingNative != pstate->method_stack[top].isNative) {
-            fprintf(stderr,
-                    "Popping native vs. non-native mismatch at index %d time %llu\n",
-                    top, method_rec->time);
-            pstate->DumpStack(stderr);
-            exit(1);
-        }
-
-        pstate->method_stack_top = top;
-        if (top == 0) {
-            // When we empty the stack, set the current method to NULL
-            pstate->current_method_sym = NULL;
-            return;
-        }
-        addr = pstate->method_stack[top - 1].addr;
-        isNative = pstate->method_stack[top - 1].isNative;
-    }
-
-    // If the top-of-stack is a native method, then set the current method
-    // to NULL.
-    if (isNative) {
-        pstate->current_method_sym = NULL;
-        return;
-    }
-
-    ProcessState *manager = pstate->addr_manager;
-    region_type *region = FindRegion(addr, manager->nregions, manager->regions);
-    uint32_t sym_addr = addr - region->base_addr;
-    symbol_type *sym = FindFunction(sym_addr, region->nsymbols,
-                                    region->symbols, true /* exact match */);
-
-    pstate->current_method_sym = sym;
-    if (sym != NULL) {
-        sym->region = region;
-    }
-}
-
-// Returns the current top-of-stack Java method, if any, for the given pid
-// at the given time. The "time" parameter must be monotonically increasing
-// across successive calls to this method.
-// If the Java method stack is empty or if a native JNI method is on the
-// top of the stack, then this method returns NULL.
-template <class T>
-typename TraceReader<T>::symbol_type*
-TraceReader<T>::FindCurrentMethod(int pid, uint64_t time)
-{
-    ProcessState *procState = processes_[pid];
-
-    if (time < next_method_.time) {
-        return procState->current_method_sym;
-    }
-
-    while (1) {
-        if (next_method_.time != 0) {
-            // We may have to process methods from a different pid so use
-            // a local variable here so that we don't overwrite procState.
-            ProcessState *pState = processes_[next_method_.pid];
-            HandleMethodRecord(pState, &next_method_);
-        }
-
-        if (internal_method_reader_->ReadMethod(&next_method_)) {
-            next_method_.time = ~0ull;
-            break;
-        }
-        if (next_method_.time > time)
-            break;
-    }
-    return procState->current_method_sym;
-}
-
-template <class T>
-void TraceReader<T>::PopulateSymbolsFromDexFile(const DexFileList *dexfile,
-                                                region_type *region)
-                                                
-{
-    int nsymbols = dexfile->nsymbols;
-    DexSym *dexsyms = dexfile->symbols;
-    region->nsymbols = nsymbols + 1;
-    symbol_type *symbols = new symbol_type[nsymbols + 1];
-    memset(symbols, 0, (nsymbols + 1) * sizeof(symbol_type));
-    region->symbols = symbols;
-    for (int ii = 0; ii < nsymbols; ii++) {
-        symbols[ii].addr = dexsyms[ii].addr;
-        symbols[ii].name = Strdup(dexsyms[ii].name);
-        symbols[ii].vm_sym = NULL;
-        symbols[ii].region = region;
-        symbols[ii].flags = symbol_type::kIsMethod;
-    }
-
-    // Add an entry at the end with an address of 0xffffffff.  This
-    // is required for LookupFunction() to work.
-    symbol_type *symbol = &symbols[nsymbols];
-    symbol->addr = 0xffffffff;
-    symbol->name = Strdup("(end)");
-    symbol->vm_sym = NULL;
-    symbol->region = region;
-    symbol->flags = symbol_type::kIsMethod;
-}
-
-template <class T>
-bool TraceReader<T>::ReadMethodSymbol(MethodRec *method_record,
-                                      symbol_type **psym,
-                                      ProcessState **pproc)
-{
-    if (internal_method_reader_->ReadMethod(&next_method_)) {
-        return true;
-    }
-
-    // Copy the whole MethodRec struct
-    *method_record = next_method_;
-
-    uint64_t time = next_method_.time;
-    
-    // Read the pid trace file up to this point to make sure the
-    // process state is valid.
-    FindCurrentPid(time);
-
-    ProcessState *pstate = processes_[next_method_.pid];
-    *pproc = pstate;
-    HandleMethodRecord(pstate, &next_method_);
-    *psym = pstate->current_method_sym;
-    return false;
-}
-
-#endif /* TRACE_READER_H */
diff --git a/emulator/qtools/trace_reader_base.h b/emulator/qtools/trace_reader_base.h
deleted file mode 100644
index 416c3d1..0000000
--- a/emulator/qtools/trace_reader_base.h
+++ /dev/null
@@ -1,332 +0,0 @@
-// Copyright 2006 The Android Open Source Project
-
-#ifndef TRACE_READER_BASE_H
-#define TRACE_READER_BASE_H
-
-#include <inttypes.h>
-#include "trace_common.h"
-#include "hash_table.h"
-
-class BBReader;
-class InsnReader;
-class AddrReader;
-class ExcReader;
-class PidReader;
-class MethodReader;
-
-struct StaticRec {
-    uint64_t    bb_num;
-    uint32_t    bb_addr;
-    uint32_t    num_insns;
-};
-
-struct StaticBlock {
-    StaticRec   rec;
-    uint32_t    *insns;
-};
-
-struct BBEvent {
-    uint64_t    time;
-    uint64_t    bb_num;
-    uint32_t    bb_addr;
-    uint32_t    *insns;
-    int         num_insns;
-    int         pid;
-    int         is_thumb;
-};
-
-struct PidEvent {
-    uint64_t    time;
-    int         rec_type;       // record type: fork, context switch, exit ...
-    int         tgid;           // thread group id
-    int         pid;            // for fork: child pid; for switch: next pid;
-                                //   for exit: exit value
-    uint32_t    vstart;         // virtual start address (only used with mmap)
-    uint32_t    vend;           // virtual end address (only used with mmap)
-    uint32_t    offset;         // virtual file offset (only used with mmap)
-
-    // Dynamically allocated path to executable (or lib). In the case of
-    // an mmapped dex file, the path is modified to be more useful for
-    // comparing against the output of dexlist.  For example, instead of this:
-    //   /data/dalvik-cache/system@app@TestHarness.apk@classes.dex
-    // We convert to this:
-    //   /system/app/TestHarness.apk
-    char        *path;
-    char        *mmap_path;     // unmodified mmap path
-    int         argc;           // number of args
-    char        **argv;         // dynamically allocated array of args
-};
-
-struct MethodRec {
-    uint64_t    time;
-    uint32_t    addr;
-    int         pid;
-    int         flags;
-};
-
-struct DexSym {
-    uint32_t    addr;
-    int         len;
-    char        *name;
-};
-
-struct DexFileList {
-    char        *path;
-    int         nsymbols;
-    DexSym      *symbols;
-};
-
-class TraceReaderBase {
-  public:
-    TraceReaderBase();
-    virtual ~TraceReaderBase();
-
-    friend class BBReader;
-
-    void                Open(const char *filename);
-    void                Close();
-    void                WriteHeader(TraceHeader *header);
-    inline bool         ReadBB(BBEvent *event);
-    int                 ReadStatic(StaticRec *rec);
-    int                 ReadStaticInsns(int num, uint32_t *insns);
-    TraceHeader         *GetHeader()                { return header_; }
-    inline uint64_t     ReadInsnTime(uint64_t min_time);
-    void                TruncateLastBlock(uint32_t num_insns);
-    inline bool         ReadAddr(uint64_t *time, uint32_t *addr, int *flags);
-    inline bool         ReadExc(uint64_t *time, uint32_t *current_pc,
-                                uint64_t *recnum, uint32_t *target_pc,
-                                uint64_t *bb_num, uint64_t *bb_start_time,
-                                int *num_insns);
-    inline bool         ReadPidEvent(PidEvent *event);
-    inline bool         ReadMethod(MethodRec *method_record);
-    StaticBlock         *GetStaticBlock(uint64_t bb_num) { return &blocks_[bb_num]; }
-    uint32_t            *GetInsns(uint64_t bb_num) { return blocks_[bb_num].insns; }
-    uint32_t            GetBBAddr(uint64_t bb_num) {
-        return blocks_[bb_num].rec.bb_addr & ~1;
-    }
-    int                 GetIsThumb(uint64_t bb_num) {
-        return blocks_[bb_num].rec.bb_addr & 1;
-    }
-    void                SetPostProcessing(bool val) { post_processing_ = val; }
-
-  protected:
-    virtual int         FindCurrentPid(uint64_t time);
-    int                 current_pid_;
-    int                 next_pid_;
-    uint64_t            next_pid_switch_time_;
-    PidReader           *internal_pid_reader_;
-    MethodReader        *internal_method_reader_;
-    HashTable<DexFileList*> *dex_hash_;
-
-  private:
-    int          FindNumInsns(uint64_t bb_num, uint64_t bb_start_time);
-    void         ReadTraceHeader(FILE *fstream, const char *filename,
-                                const char *tracename, TraceHeader *header);
-    PidEvent     *FindMmapDexFileEvent();
-    void         ParseDexList(const char *filename);
-
-    char         *static_filename_;
-    FILE         *static_fstream_;
-    TraceHeader  *header_;
-    BBReader     *bb_reader_;
-    InsnReader   *insn_reader_;
-    AddrReader   *load_addr_reader_;
-    AddrReader   *store_addr_reader_;
-    ExcReader    *exc_reader_;
-    PidReader    *pid_reader_;
-    MethodReader *method_reader_;
-    ExcReader    *internal_exc_reader_;
-    StaticBlock  *blocks_;
-    bool         exc_end_;
-    uint64_t     bb_recnum_;
-    uint64_t     exc_recnum_;
-    uint64_t     exc_bb_num_;
-    uint64_t     exc_time_;
-    int          exc_num_insns_;
-    bool         post_processing_;
-
-    bool         load_eof_;
-    uint64_t     load_time_;
-    uint32_t     load_addr_;
-    bool         store_eof_;
-    uint64_t     store_time_;
-    uint32_t     store_addr_;
-};
-
-class Decoder;
-
-class BBReader {
-  public:
-    explicit BBReader(TraceReaderBase *trace);
-    ~BBReader();
-    void     Open(const char *filename);
-    void     Close();
-    bool     ReadBB(BBEvent *event);
-
-  private:
-    struct TimeRec {
-        BBRec       bb_rec;
-        uint64_t    next_time;
-    };
-
-    struct Future {
-        Future      *next;
-        TimeRec     bb;
-    };
-
-    inline Future   *AllocFuture();
-    inline void     FreeFuture(Future *future);
-    inline void     InsertFuture(Future *future);
-    inline int      DecodeNextRec();
-
-    TimeRec         nextrec_;
-    Future          futures_[kMaxNumBasicBlocks];
-    Future          *head_;
-    Future          *free_;
-    Decoder         *decoder_;
-    bool            is_eof_;
-    TraceReaderBase *trace_;
-};
-
-class InsnReader {
-  public:
-    InsnReader();
-    ~InsnReader();
-
-    void        Open(const char *filename);
-    void        Close();
-    uint64_t    ReadInsnTime(uint64_t min_time);
-
-  private:
-    Decoder     *decoder_;
-    uint64_t    prev_time_;
-    uint64_t    time_diff_;
-    int         repeat_;
-};
-
-class AddrReader {
-  public:
-    AddrReader();
-    ~AddrReader();
-
-    bool        Open(const char *filename, const char *suffix);
-    void        Close();
-    bool        ReadAddr(uint64_t *time, uint32_t *addr);
-
-  private:
-    Decoder     *decoder_;
-    uint32_t    prev_addr_;
-    uint64_t    prev_time_;
-    bool        opened_;        // true after file is opened
-};
-
-class ExcReader {
-  public:
-    ExcReader();
-    ~ExcReader();
-
-    void        Open(const char *filename);
-    void        Close();
-    bool        ReadExc(uint64_t *time, uint32_t *current_pc,
-                        uint64_t *recnum, uint32_t *target_pc,
-                        uint64_t *bb_num, uint64_t *bb_start_time,
-                        int *num_insns);
-
-  private:
-    Decoder     *decoder_;
-    uint64_t    prev_time_;
-    uint64_t    prev_recnum_;
-};
-
-class PidReader {
-  public:
-    PidReader();
-    ~PidReader();
-
-    void        Open(const char *filename);
-    void        Close();
-    bool        ReadPidEvent(struct PidEvent *event);
-    void        Dispose(struct PidEvent *event);
-
-  private:
-    Decoder     *decoder_;
-    uint64_t    prev_time_;
-};
-
-class MethodReader {
-  public:
-    MethodReader();
-    ~MethodReader();
-
-    bool        Open(const char *filename);
-    void        Close();
-    bool        ReadMethod(MethodRec *method_record);
-
-  private:
-    Decoder     *decoder_;
-    uint64_t    prev_time_;
-    uint32_t    prev_addr_;
-    int32_t     prev_pid_;
-    bool        opened_;        // true after file is opened
-};
-
-// Reads the next dynamic basic block from the trace.
-// Returns true on end-of-file.
-inline bool TraceReaderBase::ReadBB(BBEvent *event)
-{
-    bb_recnum_ += 1;
-    return bb_reader_->ReadBB(event);
-}
-
-inline uint64_t TraceReaderBase::ReadInsnTime(uint64_t min_time)
-{
-    return insn_reader_->ReadInsnTime(min_time);
-}
-
-inline bool TraceReaderBase::ReadAddr(uint64_t *time, uint32_t *addr, int *flags)
-{
-    if (load_eof_ && store_eof_)
-        return true;
-
-    if (store_eof_ || (!load_eof_ && load_time_ <= store_time_)) {
-        *time = load_time_;
-        *addr = load_addr_;
-        *flags = 0;
-        load_eof_ = load_addr_reader_->ReadAddr(&load_time_, &load_addr_);
-    } else {
-        *time = store_time_;
-        *addr = store_addr_;
-        *flags = 1;
-        store_eof_ = store_addr_reader_->ReadAddr(&store_time_, &store_addr_);
-    }
-    return false;
-}
-
-inline bool TraceReaderBase::ReadExc(uint64_t *time, uint32_t *current_pc,
-                                     uint64_t *recnum, uint32_t *target_pc,
-                                     uint64_t *bb_num, uint64_t *bb_start_time,
-                                     int *num_insns)
-{
-    return exc_reader_->ReadExc(time, current_pc, recnum, target_pc, bb_num,
-                                bb_start_time, num_insns);
-}
-
-inline bool TraceReaderBase::ReadPidEvent(PidEvent *event)
-{
-    return pid_reader_->ReadPidEvent(event);
-}
-
-inline bool TraceReaderBase::ReadMethod(MethodRec *method_record)
-{
-    return method_reader_->ReadMethod(method_record);
-}
-
-// Duplicates a string, allocating space using new[].
-inline char * Strdup(const char *src) {
-    int len = strlen(src);
-    char *copy = new char[len + 1];
-    strcpy(copy, src);
-    return copy;
-}
-
-#endif /* TRACE_READER_BASE_H */
diff --git a/emulator/sensors/Android.mk b/emulator/sensors/Android.mk
deleted file mode 100644
index 74e02ad..0000000
--- a/emulator/sensors/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(TARGET_PRODUCT),sim)
-# HAL module implemenation, not prelinked and stored in
-# hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_SRC_FILES := sensors_qemu.c
-LOCAL_MODULE := sensors.goldfish
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_SHARED_LIBRARY)
-endif
diff --git a/emulator/sensors/sensors_qemu.c b/emulator/sensors/sensors_qemu.c
deleted file mode 100644
index 0cc636a..0000000
--- a/emulator/sensors/sensors_qemu.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* this implements a sensors hardware library for the Android emulator.
- * the following code should be built as a shared library that will be
- * placed into /system/lib/hw/sensors.goldfish.so
- *
- * it will be loaded by the code in hardware/libhardware/hardware.c
- * which is itself called from com_android_server_SensorService.cpp
- */
-
-
-/* we connect with the emulator through the "sensors" qemud service
- */
-#define  SENSORS_SERVICE_NAME "sensors"
-
-#define LOG_TAG "QemuSensors"
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <cutils/log.h>
-#include <cutils/native_handle.h>
-#include <cutils/sockets.h>
-#include <hardware/sensors.h>
-
-#if 0
-#define  D(...)  LOGD(__VA_ARGS__)
-#else
-#define  D(...)  ((void)0)
-#endif
-
-#define  E(...)  LOGE(__VA_ARGS__)
-
-#include <hardware/qemud.h>
-
-/** SENSOR IDS AND NAMES
- **/
-
-#define MAX_NUM_SENSORS 4
-
-#define SUPPORTED_SENSORS  ((1<<MAX_NUM_SENSORS)-1)
-
-#define  ID_BASE           SENSORS_HANDLE_BASE
-#define  ID_ACCELERATION   (ID_BASE+0)
-#define  ID_MAGNETIC_FIELD (ID_BASE+1)
-#define  ID_ORIENTATION    (ID_BASE+2)
-#define  ID_TEMPERATURE    (ID_BASE+3)
-
-#define  SENSORS_ACCELERATION   (1 << ID_ACCELERATION)
-#define  SENSORS_MAGNETIC_FIELD  (1 << ID_MAGNETIC_FIELD)
-#define  SENSORS_ORIENTATION     (1 << ID_ORIENTATION)
-#define  SENSORS_TEMPERATURE     (1 << ID_TEMPERATURE)
-
-#define  ID_CHECK(x)  ((unsigned)((x)-ID_BASE) < 4)
-
-#define  SENSORS_LIST  \
-    SENSOR_(ACCELERATION,"acceleration") \
-    SENSOR_(MAGNETIC_FIELD,"magnetic-field") \
-    SENSOR_(ORIENTATION,"orientation") \
-    SENSOR_(TEMPERATURE,"temperature") \
-
-static const struct {
-    const char*  name;
-    int          id; } _sensorIds[MAX_NUM_SENSORS] =
-{
-#define SENSOR_(x,y)  { y, ID_##x },
-    SENSORS_LIST
-#undef  SENSOR_
-};
-
-static const char*
-_sensorIdToName( int  id )
-{
-    int  nn;
-    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
-        if (id == _sensorIds[nn].id)
-            return _sensorIds[nn].name;
-    return "<UNKNOWN>";
-}
-
-static int
-_sensorIdFromName( const char*  name )
-{
-    int  nn;
-
-    if (name == NULL)
-        return -1;
-
-    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
-        if (!strcmp(name, _sensorIds[nn].name))
-            return _sensorIds[nn].id;
-
-    return -1;
-}
-
-/** SENSORS CONTROL DEVICE
- **
- ** This one is used to send commands to the sensors drivers.
- ** We implement this by sending directly commands to the emulator
- ** through the QEMUD channel.
- **/
-
-typedef struct SensorControl {
-    struct sensors_control_device_t  device;
-    int                              fd;
-    uint32_t                         active_sensors;
-} SensorControl;
-
-/* this must return a file descriptor that will be used to read
- * the sensors data (it is passed to data__data_open() below
- */
-static native_handle_t*
-control__open_data_source(struct sensors_control_device_t *dev)
-{
-    SensorControl*  ctl = (void*)dev;
-    native_handle_t* handle;
-
-    if (ctl->fd < 0) {
-        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
-    }
-    D("%s: fd=%d", __FUNCTION__, ctl->fd);
-    handle = native_handle_create(1, 0);
-    handle->data[0] = ctl->fd;
-    return handle;
-}
-
-static int
-control__activate(struct sensors_control_device_t *dev,
-                  int handle,
-                  int enabled)
-{
-    SensorControl*  ctl = (void*)dev;
-    uint32_t        mask, sensors, active, new_sensors, changed;
-    char            command[128];
-    int             ret;
-
-    D("%s: handle=%s (%d) enabled=%d", __FUNCTION__,
-        _sensorIdToName(handle), handle, enabled);
-
-    if (!ID_CHECK(handle)) {
-        E("%s: bad handle ID", __FUNCTION__);
-        return -1;
-    }
-
-    mask    = (1<<handle);
-    sensors = enabled ? mask : 0;
-
-    active      = ctl->active_sensors;
-    new_sensors = (active & ~mask) | (sensors & mask);
-    changed     = active ^ new_sensors;
-
-    if (!changed)
-        return 0;
-
-    snprintf(command, sizeof command, "set:%s:%d",
-                _sensorIdToName(handle), enabled != 0);
-
-    if (ctl->fd < 0) {
-        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
-    }
-
-    ret = qemud_channel_send(ctl->fd, command, -1);
-    if (ret < 0)
-        return -1;
-
-    ctl->active_sensors = new_sensors;
-
-    return 0;
-}
-
-static int
-control__set_delay(struct sensors_control_device_t *dev, int32_t ms)
-{
-    SensorControl*  ctl = (void*)dev;
-    char            command[128];
-
-    D("%s: dev=%p delay-ms=%d", __FUNCTION__, dev, ms);
-
-    snprintf(command, sizeof command, "set-delay:%d", ms);
-
-    return qemud_channel_send(ctl->fd, command, -1);
-}
-
-/* this function is used to force-stop the blocking read() in
- * data__poll. In order to keep the implementation as simple
- * as possible here, we send a command to the emulator which
- * shall send back an appropriate data block to the system.
- */
-static int
-control__wake(struct sensors_control_device_t *dev)
-{
-    SensorControl*  ctl = (void*)dev;
-    D("%s: dev=%p", __FUNCTION__, dev);
-    return qemud_channel_send(ctl->fd, "wake", -1);
-}
-
-
-static int
-control__close(struct hw_device_t *dev) 
-{
-    SensorControl*  ctl = (void*)dev;
-    close(ctl->fd);
-    free(ctl);
-    return 0;
-}
-
-/** SENSORS DATA DEVICE
- **
- ** This one is used to read sensor data from the hardware.
- ** We implement this by simply reading the data from the
- ** emulator through the QEMUD channel.
- **/
-
-
-typedef struct SensorData {
-    struct sensors_data_device_t  device;
-    sensors_data_t                sensors[MAX_NUM_SENSORS];
-    int                           events_fd;
-    uint32_t                      pendingSensors;
-    int64_t                       timeStart;
-    int64_t                       timeOffset;
-} SensorData;
-
-/* return the current time in nanoseconds */
-static int64_t
-data__now_ns(void)
-{
-    struct timespec  ts;
-
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-
-    return (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
-}
-
-static int
-data__data_open(struct sensors_data_device_t *dev, native_handle_t* handle)
-{
-    SensorData*  data = (void*)dev;
-    int i;
-    D("%s: dev=%p fd=%d", __FUNCTION__, dev, fd);
-    memset(&data->sensors, 0, sizeof(data->sensors));
-
-    for (i=0 ; i<MAX_NUM_SENSORS ; i++) {
-        data->sensors[i].vector.status = SENSOR_STATUS_ACCURACY_HIGH;
-    }
-    data->pendingSensors = 0;
-    data->timeStart      = 0;
-    data->timeOffset     = 0;
-
-    data->events_fd = dup(handle->data[0]);
-    native_handle_close(handle);
-    native_handle_delete(handle);
-    return 0;
-}
-
-static int
-data__data_close(struct sensors_data_device_t *dev)
-{
-    SensorData*  data = (void*)dev;
-    D("%s: dev=%p", __FUNCTION__, dev);
-    if (data->events_fd > 0) {
-        close(data->events_fd);
-        data->events_fd = -1;
-    }
-    return 0;
-}
-
-static int
-pick_sensor(SensorData*      data,
-            sensors_data_t*  values)
-{
-    uint32_t mask = SUPPORTED_SENSORS;
-    while (mask) {
-        uint32_t i = 31 - __builtin_clz(mask);
-        mask &= ~(1<<i);
-        if (data->pendingSensors & (1<<i)) {
-            data->pendingSensors &= ~(1<<i);
-            *values = data->sensors[i];
-            values->sensor = (1<<i);
-            LOGD_IF(0, "%s: %d [%f, %f, %f]", __FUNCTION__,
-                    (1<<i),
-                    values->vector.x,
-                    values->vector.y,
-                    values->vector.z);
-            return i;
-        }
-    }
-    LOGE("No sensor to return!!! pendingSensors=%08x", data->pendingSensors);
-    // we may end-up in a busy loop, slow things down, just in case.
-    usleep(100000);
-    return -1;
-}
-
-static int
-data__poll(struct sensors_data_device_t *dev, sensors_data_t* values)
-{
-    SensorData*  data = (void*)dev;
-    int fd = data->events_fd;
-
-    D("%s: data=%p", __FUNCTION__, dev);
-
-    // there are pending sensors, returns them now...
-    if (data->pendingSensors) {
-        return pick_sensor(data, values);
-    }
-
-    // wait until we get a complete event for an enabled sensor
-    uint32_t new_sensors = 0;
-
-    while (1) {
-        /* read the next event */
-        char     buff[256];
-        int      len = qemud_channel_recv(data->events_fd, buff, sizeof buff-1);
-        float    params[3];
-        int64_t  event_time;
-
-        if (len < 0)
-            continue;
-
-        buff[len] = 0;
-
-        /* "wake" is sent from the emulator to exit this loop. This shall
-         * really be because another thread called "control__wake" in this
-         * process.
-         */
-        if (!strcmp((const char*)data, "wake")) {
-            return 0x7FFFFFFF;
-        }
-
-        /* "acceleration:<x>:<y>:<z>" corresponds to an acceleration event */
-        if (sscanf(buff, "acceleration:%g:%g:%g", params+0, params+1, params+2) == 3) {
-            new_sensors |= SENSORS_ACCELERATION;
-            data->sensors[ID_ACCELERATION].acceleration.x = params[0];
-            data->sensors[ID_ACCELERATION].acceleration.y = params[1];
-            data->sensors[ID_ACCELERATION].acceleration.z = params[2];
-            continue;
-        }
-
-        /* "orientation:<azimuth>:<pitch>:<roll>" is sent when orientation changes */
-        if (sscanf(buff, "orientation:%g:%g:%g", params+0, params+1, params+2) == 3) {
-            new_sensors |= SENSORS_ORIENTATION;
-            data->sensors[ID_ORIENTATION].orientation.azimuth = params[0];
-            data->sensors[ID_ORIENTATION].orientation.pitch   = params[1];
-            data->sensors[ID_ORIENTATION].orientation.roll    = params[2];
-            continue;
-        }
-
-        /* "magnetic:<x>:<y>:<z>" is sent for the params of the magnetic field */
-        if (sscanf(buff, "magnetic:%g:%g:%g", params+0, params+1, params+2) == 3) {
-            new_sensors |= SENSORS_MAGNETIC_FIELD;
-            data->sensors[ID_MAGNETIC_FIELD].magnetic.x = params[0];
-            data->sensors[ID_MAGNETIC_FIELD].magnetic.y = params[1];
-            data->sensors[ID_MAGNETIC_FIELD].magnetic.z = params[2];
-            continue;
-        }
-
-        /* "temperature:<celsius>" */
-        if (sscanf(buff, "temperature:%g", params+0) == 2) {
-            new_sensors |= SENSORS_TEMPERATURE;
-            data->sensors[ID_TEMPERATURE].temperature = params[0];
-            continue;
-        }
-
-        /* "sync:<time>" is sent after a series of sensor events.
-         * where 'time' is expressed in micro-seconds and corresponds
-         * to the VM time when the real poll occured.
-         */
-        if (sscanf(buff, "sync:%lld", &event_time) == 1) {
-            if (new_sensors) {
-                data->pendingSensors = new_sensors;
-                int64_t t = event_time * 1000LL;  /* convert to nano-seconds */
-
-                /* use the time at the first sync: as the base for later
-                 * time values */
-                if (data->timeStart == 0) {
-                    data->timeStart  = data__now_ns();
-                    data->timeOffset = data->timeStart - t;
-                }
-                t += data->timeOffset;
-
-                while (new_sensors) {
-                    uint32_t i = 31 - __builtin_clz(new_sensors);
-                    new_sensors &= ~(1<<i);
-                    data->sensors[i].time = t;
-                }
-                return pick_sensor(data, values);
-            } else {
-                D("huh ? sync without any sensor data ?");
-            }
-            continue;
-        }
-        D("huh ? unsupported command");
-    }
-}
-
-static int
-data__close(struct hw_device_t *dev) 
-{
-    SensorData* data = (SensorData*)dev;
-    if (data) {
-        if (data->events_fd > 0) {
-            //LOGD("(device close) about to close fd=%d", data->events_fd);
-            close(data->events_fd);
-        }
-        free(data);
-    }
-    return 0;
-}
-
-
-/** MODULE REGISTRATION SUPPORT
- **
- ** This is required so that hardware/libhardware/hardware.c
- ** will dlopen() this library appropriately.
- **/
-
-/*
- * the following is the list of all supported sensors.
- * this table is used to build sSensorList declared below
- * according to which hardware sensors are reported as
- * available from the emulator (see get_sensors_list below)
- *
- * note: numerical values for maxRange/resolution/power were
- *       taken from the reference AK8976A implementation
- */
-static const struct sensor_t sSensorListInit[] = {
-        { .name       = "Goldfish 3-axis Accelerometer",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_ACCELERATION,
-          .type       = SENSOR_TYPE_ACCELEROMETER,
-          .maxRange   = 2.8f,
-          .resolution = 1.0f/4032.0f,
-          .power      = 3.0f,
-          .reserved   = {}
-        },
-
-        { .name       = "Goldfish 3-axis Magnetic field sensor",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_MAGNETIC_FIELD,
-          .type       = SENSOR_TYPE_MAGNETIC_FIELD,
-          .maxRange   = 2000.0f,
-          .resolution = 1.0f,
-          .power      = 6.7f,
-          .reserved   = {}
-        },
-
-        { .name       = "Goldfish Orientation sensor",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_ORIENTATION,
-          .type       = SENSOR_TYPE_ORIENTATION,
-          .maxRange   = 360.0f,
-          .resolution = 1.0f,
-          .power      = 9.7f,
-          .reserved   = {}
-        },
-
-        { .name       = "Goldfish Temperature sensor",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_TEMPERATURE,
-          .type       = SENSOR_TYPE_TEMPERATURE,
-          .maxRange   = 80.0f,
-          .resolution = 1.0f,
-          .power      = 0.0f,
-          .reserved   = {}
-        },
-};
-
-static struct sensor_t  sSensorList[MAX_NUM_SENSORS];
-
-static uint32_t sensors__get_sensors_list(struct sensors_module_t* module,
-        struct sensor_t const** list) 
-{
-    int  fd = qemud_channel_open(SENSORS_SERVICE_NAME);
-    char buffer[12];
-    int  mask, nn, count;
-
-    int  ret;
-    if (fd < 0) {
-        E("%s: no qemud connection", __FUNCTION__);
-        return 0;
-    }
-    ret = qemud_channel_send(fd, "list-sensors", -1);
-    if (ret < 0) {
-        E("%s: could not query sensor list: %s", __FUNCTION__,
-          strerror(errno));
-        close(fd);
-        return 0;
-    }
-    ret = qemud_channel_recv(fd, buffer, sizeof buffer-1);
-    if (ret < 0) {
-        E("%s: could not receive sensor list: %s", __FUNCTION__,
-          strerror(errno));
-        close(fd);
-        return 0;
-    }
-    buffer[ret] = 0;
-    close(fd);
-
-    /* the result is a integer used as a mask for available sensors */
-    mask  = atoi(buffer);
-    count = 0;
-    for (nn = 0; nn < MAX_NUM_SENSORS; nn++) {
-        if (((1 << nn) & mask) == 0)
-            continue;
-
-        sSensorList[count++] = sSensorListInit[nn];
-    }
-    D("%s: returned %d sensors (mask=%d)", __FUNCTION__, count, mask);
-    *list = sSensorList;
-    return count;
-}
-
-
-static int
-open_sensors(const struct hw_module_t* module,
-             const char*               name,
-             struct hw_device_t*      *device)
-{
-    int  status = -EINVAL;
-
-    D("%s: name=%s", __FUNCTION__, name);
-
-    if (!strcmp(name, SENSORS_HARDWARE_CONTROL))
-    {
-        SensorControl *dev = malloc(sizeof(*dev));
-
-        memset(dev, 0, sizeof(*dev));
-
-        dev->device.common.tag       = HARDWARE_DEVICE_TAG;
-        dev->device.common.version   = 0;
-        dev->device.common.module    = (struct hw_module_t*) module;
-        dev->device.common.close     = control__close;
-        dev->device.open_data_source = control__open_data_source;
-        dev->device.activate         = control__activate;
-        dev->device.set_delay        = control__set_delay;
-        dev->device.wake             = control__wake;
-        dev->fd                      = -1;
-
-        *device = &dev->device.common;
-        status  = 0;
-    }
-    else if (!strcmp(name, SENSORS_HARDWARE_DATA)) {
-        SensorData *dev = malloc(sizeof(*dev));
-
-        memset(dev, 0, sizeof(*dev));
-
-        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
-        dev->device.common.version = 0;
-        dev->device.common.module  = (struct hw_module_t*) module;
-        dev->device.common.close   = data__close;
-        dev->device.data_open      = data__data_open;
-        dev->device.data_close     = data__data_close;
-        dev->device.poll           = data__poll;
-        dev->events_fd             = -1;
-
-        *device = &dev->device.common;
-        status  = 0;
-    }
-    return status;
-}
-
-
-static struct hw_module_methods_t sensors_module_methods = {
-    .open = open_sensors
-};
-
-const struct sensors_module_t HAL_MODULE_INFO_SYM = {
-    .common = {
-        .tag = HARDWARE_MODULE_TAG,
-        .version_major = 1,
-        .version_minor = 0,
-        .id = SENSORS_HARDWARE_MODULE_ID,
-        .name = "Goldfish SENSORS Module",
-        .author = "The Android Open Source Project",
-        .methods = &sensors_module_methods,
-    },
-    .get_sensors_list = sensors__get_sensors_list
-};
diff --git a/emulator/skins/HVGA/arrow_down.png b/emulator/skins/HVGA/arrow_down.png
deleted file mode 100644
index b9fde22..0000000
--- a/emulator/skins/HVGA/arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/arrow_left.png b/emulator/skins/HVGA/arrow_left.png
deleted file mode 100644
index 281b192..0000000
--- a/emulator/skins/HVGA/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/arrow_right.png b/emulator/skins/HVGA/arrow_right.png
deleted file mode 100644
index 4cbc65d..0000000
--- a/emulator/skins/HVGA/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/arrow_up.png b/emulator/skins/HVGA/arrow_up.png
deleted file mode 100644
index 29c7121..0000000
--- a/emulator/skins/HVGA/arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/background_land.png b/emulator/skins/HVGA/background_land.png
deleted file mode 100644
index 09c857b..0000000
--- a/emulator/skins/HVGA/background_land.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/background_port.png b/emulator/skins/HVGA/background_port.png
deleted file mode 100644
index a452934..0000000
--- a/emulator/skins/HVGA/background_port.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/button.png b/emulator/skins/HVGA/button.png
deleted file mode 100644
index 8281d20..0000000
--- a/emulator/skins/HVGA/button.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/controls.png b/emulator/skins/HVGA/controls.png
deleted file mode 100644
index 04b85e2..0000000
--- a/emulator/skins/HVGA/controls.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/hardware.ini b/emulator/skins/HVGA/hardware.ini
deleted file mode 100644
index f6a30b0..0000000
--- a/emulator/skins/HVGA/hardware.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-# skin-specific hardware values
-hw.lcd.density=160
\ No newline at end of file
diff --git a/emulator/skins/HVGA/key.png b/emulator/skins/HVGA/key.png
deleted file mode 100644
index 40b03bf..0000000
--- a/emulator/skins/HVGA/key.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/keyboard.png b/emulator/skins/HVGA/keyboard.png
deleted file mode 100644
index ca49dcf..0000000
--- a/emulator/skins/HVGA/keyboard.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/layout b/emulator/skins/HVGA/layout
deleted file mode 100644
index cc82dde..0000000
--- a/emulator/skins/HVGA/layout
+++ /dev/null
@@ -1,443 +0,0 @@
-parts {
-    portrait {
-        background {
-            image   background_port.png
-        }
-    }
-    landscape {
-        background {
-            image   background_land.png
-        }
-    }
-
-    device {
-        display {
-            width   320
-            height  480
-            x       0
-            y       0
-        }
-    }
-
-    controls {
-        background {
-            image   controls.png
-        }
-        buttons {
-            soft-left {
-                    image button.png
-                    x 56
-                    y 142
-            }
-            home {
-                    image button.png
-                    x 0
-                    y 142
-            }
-            back {
-                    image button.png
-                    x 112
-                    y 142
-            }
-            dpad-up {
-                    image arrow_up.png
-                    x 77
-                    y 53
-            }
-            dpad-down {
-                    image arrow_down.png
-                    x 77
-                    y 106
-            }
-            dpad-left {
-                    image arrow_left.png
-                    x 53
-                    y 53
-            }
-            dpad-right {
-                    image arrow_right.png
-                    x 123
-                    y 53
-            }
-            dpad-center {
-                    image select.png
-                    x 77
-                    y 81
-            }
-            phone-dial {
-                    image button.png
-                    x 0
-                    y 71
-            }
-            phone-hangup {
-                    image button.png
-                    x 168
-                    y 71
-            }
-
-            power {
-                    image button.png
-                    x 168
-                    y 0
-            }
-
-            volume-up {
-                    image button.png
-                    x 112
-                    y 0
-            }
-
-            volume-down {
-                    image button.png
-                    x 56
-                    y 0
-            }
-
-            search {
-                    image button.png
-                    x 168
-                    y 142
-            }
-
-        }
-    }
-
-    keyboard {
-        background {
-            image   keyboard.png
-        }
-        buttons {
-            1 {
-                image  key.png
-                x  5
-                y  5
-            }
-            2 {
-                image  key.png
-                x 42
-                y 5
-            }
-            3 {
-                image  key.png
-                x 79
-                y 5
-            }
-            4 {
-                image  key.png
-                x 116
-                y 5
-            }
-            5 {
-                image  key.png
-                x 153
-                y 5
-            }
-            6 {
-                image  key.png
-                x 190
-                y 5
-            }
-            7 {
-                image  key.png
-                x 227
-                y 5
-            }
-            8 {
-                image  key.png
-                x 264
-                y 5
-            }
-            9 {
-                image  key.png
-                x 301
-                y 5
-            }
-            0 {
-                image  key.png
-                x 338
-                y 5
-            }
-
-            q {
-                image  key.png
-                x  5
-                y  41
-            }
-            w {
-                image  key.png
-                x 42
-                y 41
-            }
-            e {
-                image  key.png
-                x 79
-                y 41
-            }
-            r {
-                image  key.png
-                x 116
-                y 41
-            }
-            t {
-                image  key.png
-                x 153
-                y 41
-            }
-            y {
-                image  key.png
-                x 190
-                y 41
-            }
-            u {
-                image  key.png
-                x 227
-                y 41
-            }
-            i {
-                image  key.png
-                x 264
-                y 41
-            }
-            o {
-                image  key.png
-                x 301
-                y 41
-            }
-            p {
-                image  key.png
-                x 338
-                y 41
-            }
-
-            a {
-                image  key.png
-                x  5
-                y 77
-            }
-            s {
-                image  key.png
-                x 42
-                y 77
-            }
-            d {
-                image  key.png
-                x 79
-                y 77
-            }
-            f {
-                image  key.png
-                x 116
-                y 77
-            }
-            g {
-                image  key.png
-                x 153
-                y 77
-            }
-            h {
-                image  key.png
-                x 190
-                y 77
-            }
-            j {
-                image  key.png
-                x 227
-                y 77
-            }
-            k {
-                image  key.png
-                x 264
-                y 77
-            }
-            l {
-                image  key.png
-                x 301
-                y 77
-            }
-            DEL {
-                image  key.png
-                x 338
-                y 77
-            }
-
-            CAP {
-                image  key.png
-                x  5
-                y 113
-            }
-            z {
-                image  key.png
-                x 42
-                y 113
-            }
-            x {
-                image  key.png
-                x 79
-                y 113
-            }
-            c {
-                image  key.png
-                x 116
-                y 113
-            }
-            v {
-                image  key.png
-                x 153
-                y 113
-            }
-            b {
-                image  key.png
-                x 190
-                y 113
-            }
-            n {
-                image  key.png
-                x 227
-                y 113
-            }
-            m {
-                image  key.png
-                x 264
-                y 113
-            }
-            PERIOD {
-                image  key.png
-                x 301
-                y 113
-            }
-            ENTER {
-                image  key.png
-                x 338
-                y 113
-            }
-
-            ALT {
-                image  key.png
-                x  5
-                y 149
-            }
-            SYM {
-                image  key.png
-                x 42
-                y 149
-            }
-            AT {
-                image  key.png
-                x 79
-                y 149
-            }
-            SPACE {
-                image  spacebar.png
-                x 116
-                y 149
-            }
-            SLASH {
-                image  key.png
-                x 264
-                y 149
-            }
-            COMMA {
-                image  key.png
-                x 301
-                y 149
-            }
-            ALT2 {
-                image  key.png
-                x 338
-                y 149
-            }
-
-        }
-    }
-}
-
-layouts {
-    portrait {
-        width     791
-        height    534
-        color     0xe0e0e0
-        event     EV_SW:0:1
-
-        part1 {
-            name    portrait
-            x       0
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       800
-            y       0
-        }
-
-        part3 {
-            name    device
-            x       28
-            y       27
-        }
-        part4 {
-            name    controls
-            x       476
-            y       77
-        }
-        part5 {
-            name    keyboard
-            x       395
-            y       328
-        }
-
-    }
-
-    landscape {
-        width     640
-        height    601
-        color     0xe0e0e0
-        event     EV_SW:0:0
-
-        # the framework _always_ assume that the DPad
-        # has been physically rotated in landscape mode.
-        # however, with this skin, this is not the case
-        #
-        dpad-rotation 3
-
-        part1 {
-            name    portrait
-            x       800
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       0
-            y       0
-        }
-
-        part3 {
-            name      device
-            x         80
-            y         349
-            rotation  3
-        }
-
-        part4 {
-            name     controls
-            x        410
-            y        396
-        }
-
-        part5 {
-            name     keyboard
-            x        18
-            y        396
-        }
-    }
-}
-
-keyboard {
-    charmap qwerty2
-}
-
-network {
-    speed  full
-    delay  none
-}
diff --git a/emulator/skins/HVGA/select.png b/emulator/skins/HVGA/select.png
deleted file mode 100644
index f4a65d3..0000000
--- a/emulator/skins/HVGA/select.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/HVGA/spacebar.png b/emulator/skins/HVGA/spacebar.png
deleted file mode 100644
index aa459bd..0000000
--- a/emulator/skins/HVGA/spacebar.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/arrow_down.png b/emulator/skins/QVGA/arrow_down.png
deleted file mode 100644
index b9fde22..0000000
--- a/emulator/skins/QVGA/arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/arrow_left.png b/emulator/skins/QVGA/arrow_left.png
deleted file mode 100644
index 281b192..0000000
--- a/emulator/skins/QVGA/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/arrow_right.png b/emulator/skins/QVGA/arrow_right.png
deleted file mode 100644
index 4cbc65d..0000000
--- a/emulator/skins/QVGA/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/arrow_up.png b/emulator/skins/QVGA/arrow_up.png
deleted file mode 100644
index 29c7121..0000000
--- a/emulator/skins/QVGA/arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/background_land.png b/emulator/skins/QVGA/background_land.png
deleted file mode 100644
index cb002b5..0000000
--- a/emulator/skins/QVGA/background_land.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/background_port.png b/emulator/skins/QVGA/background_port.png
deleted file mode 100644
index 6728562..0000000
--- a/emulator/skins/QVGA/background_port.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/button.png b/emulator/skins/QVGA/button.png
deleted file mode 100644
index 8281d20..0000000
--- a/emulator/skins/QVGA/button.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/controls.png b/emulator/skins/QVGA/controls.png
deleted file mode 100644
index 04b85e2..0000000
--- a/emulator/skins/QVGA/controls.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/hardware.ini b/emulator/skins/QVGA/hardware.ini
deleted file mode 100644
index 2efe617..0000000
--- a/emulator/skins/QVGA/hardware.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-# skin-specific hardware values
-hw.lcd.density=120
\ No newline at end of file
diff --git a/emulator/skins/QVGA/key.png b/emulator/skins/QVGA/key.png
deleted file mode 100644
index 40b03bf..0000000
--- a/emulator/skins/QVGA/key.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/keyboard.png b/emulator/skins/QVGA/keyboard.png
deleted file mode 100644
index ca49dcf..0000000
--- a/emulator/skins/QVGA/keyboard.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/layout b/emulator/skins/QVGA/layout
deleted file mode 100644
index 96f2133..0000000
--- a/emulator/skins/QVGA/layout
+++ /dev/null
@@ -1,439 +0,0 @@
-parts {
-    portrait {
-        background {
-            image   background_port.png
-        }
-    }
-    landscape {
-        background {
-            image   background_land.png
-        }
-    }
-
-    device {
-        display {
-            width   240
-            height  320
-            x       0
-            y       0
-        }
-    }
-    
-    controls {
-        background {
-            image   controls.png
-        }
-        buttons {
-            soft-left {
-                    image button.png
-                    x 56
-                    y 142
-            }
-            home {
-                    image button.png
-                    x 0
-                    y 142
-            }
-            back {
-                    image button.png
-                    x 112
-                    y 142
-            }
-            dpad-up {
-                    image arrow_up.png
-                    x 77
-                    y 53
-            }
-            dpad-down {
-                    image arrow_down.png
-                    x 77
-                    y 106
-            }
-            dpad-left {
-                    image arrow_left.png
-                    x 53
-                    y 53
-            }
-            dpad-right {
-                    image arrow_right.png
-                    x 123
-                    y 53
-            }
-            dpad-center {
-                    image select.png
-                    x 77
-                    y 81
-            }
-            phone-dial {
-                    image button.png
-                    x 0
-                    y 71
-            }
-            phone-hangup {
-                    image button.png
-                    x 168
-                    y 71
-            }
-
-            power {
-                    image button.png
-                    x 168
-                    y 0
-            }
-
-            volume-up {
-                    image button.png
-                    x 112
-                    y 0
-            }
-
-            volume-down {
-                    image button.png
-                    x 56
-                    y 0
-            }
-
-            search {
-                    image button.png
-                    x 168
-                    y 142
-            }
-
-        }
-    }
-
-    keyboard {
-        background {
-            image   keyboard.png
-        }
-        buttons {
-            1 {
-                image  key.png
-                x  5
-                y  5
-            }
-            2 {
-                image  key.png
-                x 42
-                y 5
-            }
-            3 {
-                image  key.png
-                x 79
-                y 5
-            }
-            4 {
-                image  key.png
-                x 116
-                y 5
-            }
-            5 {
-                image  key.png
-                x 153
-                y 5
-            }
-            6 {
-                image  key.png
-                x 190
-                y 5
-            }
-            7 {
-                image  key.png
-                x 227
-                y 5
-            }
-            8 {
-                image  key.png
-                x 264
-                y 5
-            }
-            9 {
-                image  key.png
-                x 301
-                y 5
-            }
-            0 {
-                image  key.png
-                x 338
-                y 5
-            }
-
-            q {
-                image  key.png
-                x  5
-                y  41
-            }
-            w {
-                image  key.png
-                x 42
-                y 41
-            }
-            e {
-                image  key.png
-                x 79
-                y 41
-            }
-            r {
-                image  key.png
-                x 116
-                y 41
-            }
-            t {
-                image  key.png
-                x 153
-                y 41
-            }
-            y {
-                image  key.png
-                x 190
-                y 41
-            }
-            u {
-                image  key.png
-                x 227
-                y 41
-            }
-            i {
-                image  key.png
-                x 264
-                y 41
-            }
-            o {
-                image  key.png
-                x 301
-                y 41
-            }
-            p {
-                image  key.png
-                x 338
-                y 41
-            }
-
-            a {
-                image  key.png
-                x  5
-                y 77
-            }
-            s {
-                image  key.png
-                x 42
-                y 77
-            }
-            d {
-                image  key.png
-                x 79
-                y 77
-            }
-            f {
-                image  key.png
-                x 116
-                y 77
-            }
-            g {
-                image  key.png
-                x 153
-                y 77
-            }
-            h {
-                image  key.png
-                x 190
-                y 77
-            }
-            j {
-                image  key.png
-                x 227
-                y 77
-            }
-            k {
-                image  key.png
-                x 264
-                y 77
-            }
-            l {
-                image  key.png
-                x 301
-                y 77
-            }
-            DEL {
-                image  key.png
-                x 338
-                y 77
-            }
-
-            CAP {
-                image  key.png
-                x  5
-                y 113
-            }
-            z {
-                image  key.png
-                x 42
-                y 113
-            }
-            x {
-                image  key.png
-                x 79
-                y 113
-            }
-            c {
-                image  key.png
-                x 116
-                y 113
-            }
-            v {
-                image  key.png
-                x 153
-                y 113
-            }
-            b {
-                image  key.png
-                x 190
-                y 113
-            }
-            n {
-                image  key.png
-                x 227
-                y 113
-            }
-            m {
-                image  key.png
-                x 264
-                y 113
-            }
-            PERIOD {
-                image  key.png
-                x 301
-                y 113
-            }
-            ENTER {
-                image  key.png
-                x 338
-                y 113
-            }
-
-            ALT {
-                image  key.png
-                x  5
-                y 149
-            }
-            SYM {
-                image  key.png
-                x 42
-                y 149
-            }
-            AT {
-                image  key.png
-                x 79
-                y 149
-            }
-            SPACE {
-                image  spacebar.png
-                x 116
-                y 149
-            }
-            SLASH {
-                image  key.png
-                x 264
-                y 149
-            }
-            COMMA {
-                image  key.png
-                x 301
-                y 149
-            }
-            ALT2 {
-                image  key.png
-                x 338
-                y 149
-            }
-
-        }
-    }
-}
-
-layouts {
-    portrait {
-        width     711
-        height    435
-        color     0xe0e0e0
-        event     EV_SW:0:1
-        
-        part1 {
-            name    portrait
-            x       0
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       800
-            y       0
-        }
-
-        part3 {
-            name    device
-            x       28
-            y       58
-        }
-        part4 {
-            name     controls
-            x        396
-            y        27
-        }
-        part5 {
-            name     keyboard
-            x        315
-            y        229
-        }
-    }
-
-    landscape {
-        width     640
-        height    522
-        color     0xe0e0e0
-        event     EV_SW:0:0
-
-        dpad-rotation 3
-
-
-        part1 {
-            name    portrait
-            x       800
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       0
-            y       0
-        }
-
-        part3 {
-            name      device
-            x         160
-            y         270
-            rotation  3
-        }
-
-        part4 {
-            name     controls
-            x        410
-            y        317
-        }
-
-        part5 {
-            name     keyboard
-            x        18
-            y        317
-        }
-    }
-}
-
-keyboard {
-    charmap qwerty2
-}
-
-network {
-    speed  full
-    delay  none
-}
diff --git a/emulator/skins/QVGA/select.png b/emulator/skins/QVGA/select.png
deleted file mode 100644
index f4a65d3..0000000
--- a/emulator/skins/QVGA/select.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/QVGA/spacebar.png b/emulator/skins/QVGA/spacebar.png
deleted file mode 100644
index aa459bd..0000000
--- a/emulator/skins/QVGA/spacebar.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/arrow_down.png b/emulator/skins/WQVGA400/arrow_down.png
deleted file mode 100644
index b9fde22..0000000
--- a/emulator/skins/WQVGA400/arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/arrow_left.png b/emulator/skins/WQVGA400/arrow_left.png
deleted file mode 100644
index 281b192..0000000
--- a/emulator/skins/WQVGA400/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/arrow_right.png b/emulator/skins/WQVGA400/arrow_right.png
deleted file mode 100644
index 4cbc65d..0000000
--- a/emulator/skins/WQVGA400/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/arrow_up.png b/emulator/skins/WQVGA400/arrow_up.png
deleted file mode 100644
index 29c7121..0000000
--- a/emulator/skins/WQVGA400/arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/background_land.png b/emulator/skins/WQVGA400/background_land.png
deleted file mode 100644
index c3fbee9..0000000
--- a/emulator/skins/WQVGA400/background_land.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/background_port.png b/emulator/skins/WQVGA400/background_port.png
deleted file mode 100644
index c88edb8..0000000
--- a/emulator/skins/WQVGA400/background_port.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/button.png b/emulator/skins/WQVGA400/button.png
deleted file mode 100644
index 8281d20..0000000
--- a/emulator/skins/WQVGA400/button.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/controls.png b/emulator/skins/WQVGA400/controls.png
deleted file mode 100644
index 04b85e2..0000000
--- a/emulator/skins/WQVGA400/controls.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/hardware.ini b/emulator/skins/WQVGA400/hardware.ini
deleted file mode 100644
index 2efe617..0000000
--- a/emulator/skins/WQVGA400/hardware.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-# skin-specific hardware values
-hw.lcd.density=120
\ No newline at end of file
diff --git a/emulator/skins/WQVGA400/key.png b/emulator/skins/WQVGA400/key.png
deleted file mode 100644
index 40b03bf..0000000
--- a/emulator/skins/WQVGA400/key.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/keyboard.png b/emulator/skins/WQVGA400/keyboard.png
deleted file mode 100644
index ca49dcf..0000000
--- a/emulator/skins/WQVGA400/keyboard.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/layout b/emulator/skins/WQVGA400/layout
deleted file mode 100644
index 4d71adf..0000000
--- a/emulator/skins/WQVGA400/layout
+++ /dev/null
@@ -1,438 +0,0 @@
-parts {
-    portrait {
-        background {
-            image   background_port.png
-        }
-    }
-    landscape {
-        background {
-            image   background_land.png
-        }
-    }
-
-    device {
-        display {
-            width   240
-            height  400
-            x       0
-            y       0
-        }
-    }
-    
-    controls {
-        background {
-            image   controls.png
-        }
-        buttons {
-            soft-left {
-                    image button.png
-                    x 56
-                    y 142
-            }
-            home {
-                    image button.png
-                    x 0
-                    y 142
-            }
-            back {
-                    image button.png
-                    x 112
-                    y 142
-            }
-            dpad-up {
-                    image arrow_up.png
-                    x 77
-                    y 53
-            }
-            dpad-down {
-                    image arrow_down.png
-                    x 77
-                    y 106
-            }
-            dpad-left {
-                    image arrow_left.png
-                    x 53
-                    y 53
-            }
-            dpad-right {
-                    image arrow_right.png
-                    x 123
-                    y 53
-            }
-            dpad-center {
-                    image select.png
-                    x 77
-                    y 81
-            }
-            phone-dial {
-                    image button.png
-                    x 0
-                    y 71
-            }
-            phone-hangup {
-                    image button.png
-                    x 168
-                    y 71
-            }
-
-            power {
-                    image button.png
-                    x 168
-                    y 0
-            }
-
-            volume-up {
-                    image button.png
-                    x 112
-                    y 0
-            }
-
-            volume-down {
-                    image button.png
-                    x 56
-                    y 0
-            }
-
-            search {
-                    image button.png
-                    x 168
-                    y 142
-            }
-
-        }
-    }
-
-    keyboard {
-        background {
-            image   keyboard.png
-        }
-        buttons {
-            1 {
-                image  key.png
-                x  5
-                y  5
-            }
-            2 {
-                image  key.png
-                x 42
-                y 5
-            }
-            3 {
-                image  key.png
-                x 79
-                y 5
-            }
-            4 {
-                image  key.png
-                x 116
-                y 5
-            }
-            5 {
-                image  key.png
-                x 153
-                y 5
-            }
-            6 {
-                image  key.png
-                x 190
-                y 5
-            }
-            7 {
-                image  key.png
-                x 227
-                y 5
-            }
-            8 {
-                image  key.png
-                x 264
-                y 5
-            }
-            9 {
-                image  key.png
-                x 301
-                y 5
-            }
-            0 {
-                image  key.png
-                x 338
-                y 5
-            }
-
-            q {
-                image  key.png
-                x  5
-                y  41
-            }
-            w {
-                image  key.png
-                x 42
-                y 41
-            }
-            e {
-                image  key.png
-                x 79
-                y 41
-            }
-            r {
-                image  key.png
-                x 116
-                y 41
-            }
-            t {
-                image  key.png
-                x 153
-                y 41
-            }
-            y {
-                image  key.png
-                x 190
-                y 41
-            }
-            u {
-                image  key.png
-                x 227
-                y 41
-            }
-            i {
-                image  key.png
-                x 264
-                y 41
-            }
-            o {
-                image  key.png
-                x 301
-                y 41
-            }
-            p {
-                image  key.png
-                x 338
-                y 41
-            }
-
-            a {
-                image  key.png
-                x  5
-                y 77
-            }
-            s {
-                image  key.png
-                x 42
-                y 77
-            }
-            d {
-                image  key.png
-                x 79
-                y 77
-            }
-            f {
-                image  key.png
-                x 116
-                y 77
-            }
-            g {
-                image  key.png
-                x 153
-                y 77
-            }
-            h {
-                image  key.png
-                x 190
-                y 77
-            }
-            j {
-                image  key.png
-                x 227
-                y 77
-            }
-            k {
-                image  key.png
-                x 264
-                y 77
-            }
-            l {
-                image  key.png
-                x 301
-                y 77
-            }
-            DEL {
-                image  key.png
-                x 338
-                y 77
-            }
-
-            CAP {
-                image  key.png
-                x  5
-                y 113
-            }
-            z {
-                image  key.png
-                x 42
-                y 113
-            }
-            x {
-                image  key.png
-                x 79
-                y 113
-            }
-            c {
-                image  key.png
-                x 116
-                y 113
-            }
-            v {
-                image  key.png
-                x 153
-                y 113
-            }
-            b {
-                image  key.png
-                x 190
-                y 113
-            }
-            n {
-                image  key.png
-                x 227
-                y 113
-            }
-            m {
-                image  key.png
-                x 264
-                y 113
-            }
-            PERIOD {
-                image  key.png
-                x 301
-                y 113
-            }
-            ENTER {
-                image  key.png
-                x 338
-                y 113
-            }
-
-            ALT {
-                image  key.png
-                x  5
-                y 149
-            }
-            SYM {
-                image  key.png
-                x 42
-                y 149
-            }
-            AT {
-                image  key.png
-                x 79
-                y 149
-            }
-            SPACE {
-                image  spacebar.png
-                x 116
-                y 149
-            }
-            SLASH {
-                image  key.png
-                x 264
-                y 149
-            }
-            COMMA {
-                image  key.png
-                x 301
-                y 149
-            }
-            ALT2 {
-                image  key.png
-                x 338
-                y 149
-            }
-
-        }
-    }
-}
-
-layouts {
-    portrait {
-        width     711
-        height    454
-        color     0xe0e0e0
-        event     EV_SW:0:1
-        
-        part1 {
-            name    portrait
-            x       0
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       800
-            y       0
-        }
-
-        part3 {
-            name    device
-            x       28
-            y       27
-        }
-        part4 {
-            name     controls
-            x        396
-            y        37
-        }
-        part5 {
-            name     keyboard
-            x        315
-            y        248
-        }
-    }
-
-    landscape {
-        width     640
-        height    522
-        color     0xe0e0e0
-        event     EV_SW:0:0
-
-        dpad-rotation 3
-
-        part1 {
-            name    portrait
-            x       800
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       0
-            y       0
-        }
-
-        part3 {
-            name      device
-            x         120
-            y         270
-            rotation  3
-        }
-
-        part4 {
-            name     controls
-            x        410
-            y        317
-        }
-
-        part5 {
-            name     keyboard
-            x        18
-            y        317
-        }
-    }
-}
-
-keyboard {
-    charmap qwerty2
-}
-
-network {
-    speed  full
-    delay  none
-}
diff --git a/emulator/skins/WQVGA400/select.png b/emulator/skins/WQVGA400/select.png
deleted file mode 100644
index f4a65d3..0000000
--- a/emulator/skins/WQVGA400/select.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA400/spacebar.png b/emulator/skins/WQVGA400/spacebar.png
deleted file mode 100644
index aa459bd..0000000
--- a/emulator/skins/WQVGA400/spacebar.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/arrow_down.png b/emulator/skins/WQVGA432/arrow_down.png
deleted file mode 100644
index b9fde22..0000000
--- a/emulator/skins/WQVGA432/arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/arrow_left.png b/emulator/skins/WQVGA432/arrow_left.png
deleted file mode 100644
index 281b192..0000000
--- a/emulator/skins/WQVGA432/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/arrow_right.png b/emulator/skins/WQVGA432/arrow_right.png
deleted file mode 100644
index 4cbc65d..0000000
--- a/emulator/skins/WQVGA432/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/arrow_up.png b/emulator/skins/WQVGA432/arrow_up.png
deleted file mode 100644
index 29c7121..0000000
--- a/emulator/skins/WQVGA432/arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/background_land.png b/emulator/skins/WQVGA432/background_land.png
deleted file mode 100644
index 1450e25..0000000
--- a/emulator/skins/WQVGA432/background_land.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/background_port.png b/emulator/skins/WQVGA432/background_port.png
deleted file mode 100644
index 891ab45..0000000
--- a/emulator/skins/WQVGA432/background_port.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/button.png b/emulator/skins/WQVGA432/button.png
deleted file mode 100644
index 8281d20..0000000
--- a/emulator/skins/WQVGA432/button.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/controls.png b/emulator/skins/WQVGA432/controls.png
deleted file mode 100644
index 04b85e2..0000000
--- a/emulator/skins/WQVGA432/controls.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/hardware.ini b/emulator/skins/WQVGA432/hardware.ini
deleted file mode 100644
index 2efe617..0000000
--- a/emulator/skins/WQVGA432/hardware.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-# skin-specific hardware values
-hw.lcd.density=120
\ No newline at end of file
diff --git a/emulator/skins/WQVGA432/key.png b/emulator/skins/WQVGA432/key.png
deleted file mode 100644
index 40b03bf..0000000
--- a/emulator/skins/WQVGA432/key.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/keyboard.png b/emulator/skins/WQVGA432/keyboard.png
deleted file mode 100644
index ca49dcf..0000000
--- a/emulator/skins/WQVGA432/keyboard.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/layout b/emulator/skins/WQVGA432/layout
deleted file mode 100644
index 006e955..0000000
--- a/emulator/skins/WQVGA432/layout
+++ /dev/null
@@ -1,438 +0,0 @@
-parts {
-    portrait {
-        background {
-            image   background_port.png
-        }
-    }
-    landscape {
-        background {
-            image   background_land.png
-        }
-    }
-
-    device {
-        display {
-            width   240
-            height  432
-            x       0
-            y       0
-        }
-    }
-    
-    controls {
-        background {
-            image   controls.png
-        }
-        buttons {
-            soft-left {
-                    image button.png
-                    x 56
-                    y 142
-            }
-            home {
-                    image button.png
-                    x 0
-                    y 142
-            }
-            back {
-                    image button.png
-                    x 112
-                    y 142
-            }
-            dpad-up {
-                    image arrow_up.png
-                    x 77
-                    y 53
-            }
-            dpad-down {
-                    image arrow_down.png
-                    x 77
-                    y 106
-            }
-            dpad-left {
-                    image arrow_left.png
-                    x 53
-                    y 53
-            }
-            dpad-right {
-                    image arrow_right.png
-                    x 123
-                    y 53
-            }
-            dpad-center {
-                    image select.png
-                    x 77
-                    y 81
-            }
-            phone-dial {
-                    image button.png
-                    x 0
-                    y 71
-            }
-            phone-hangup {
-                    image button.png
-                    x 168
-                    y 71
-            }
-
-            power {
-                    image button.png
-                    x 168
-                    y 0
-            }
-
-            volume-up {
-                    image button.png
-                    x 112
-                    y 0
-            }
-
-            volume-down {
-                    image button.png
-                    x 56
-                    y 0
-            }
-
-            search {
-                    image button.png
-                    x 168
-                    y 142
-            }
-
-        }
-    }
-
-    keyboard {
-        background {
-            image   keyboard.png
-        }
-        buttons {
-            1 {
-                image  key.png
-                x  5
-                y  5
-            }
-            2 {
-                image  key.png
-                x 42
-                y 5
-            }
-            3 {
-                image  key.png
-                x 79
-                y 5
-            }
-            4 {
-                image  key.png
-                x 116
-                y 5
-            }
-            5 {
-                image  key.png
-                x 153
-                y 5
-            }
-            6 {
-                image  key.png
-                x 190
-                y 5
-            }
-            7 {
-                image  key.png
-                x 227
-                y 5
-            }
-            8 {
-                image  key.png
-                x 264
-                y 5
-            }
-            9 {
-                image  key.png
-                x 301
-                y 5
-            }
-            0 {
-                image  key.png
-                x 338
-                y 5
-            }
-
-            q {
-                image  key.png
-                x  5
-                y  41
-            }
-            w {
-                image  key.png
-                x 42
-                y 41
-            }
-            e {
-                image  key.png
-                x 79
-                y 41
-            }
-            r {
-                image  key.png
-                x 116
-                y 41
-            }
-            t {
-                image  key.png
-                x 153
-                y 41
-            }
-            y {
-                image  key.png
-                x 190
-                y 41
-            }
-            u {
-                image  key.png
-                x 227
-                y 41
-            }
-            i {
-                image  key.png
-                x 264
-                y 41
-            }
-            o {
-                image  key.png
-                x 301
-                y 41
-            }
-            p {
-                image  key.png
-                x 338
-                y 41
-            }
-
-            a {
-                image  key.png
-                x  5
-                y 77
-            }
-            s {
-                image  key.png
-                x 42
-                y 77
-            }
-            d {
-                image  key.png
-                x 79
-                y 77
-            }
-            f {
-                image  key.png
-                x 116
-                y 77
-            }
-            g {
-                image  key.png
-                x 153
-                y 77
-            }
-            h {
-                image  key.png
-                x 190
-                y 77
-            }
-            j {
-                image  key.png
-                x 227
-                y 77
-            }
-            k {
-                image  key.png
-                x 264
-                y 77
-            }
-            l {
-                image  key.png
-                x 301
-                y 77
-            }
-            DEL {
-                image  key.png
-                x 338
-                y 77
-            }
-
-            CAP {
-                image  key.png
-                x  5
-                y 113
-            }
-            z {
-                image  key.png
-                x 42
-                y 113
-            }
-            x {
-                image  key.png
-                x 79
-                y 113
-            }
-            c {
-                image  key.png
-                x 116
-                y 113
-            }
-            v {
-                image  key.png
-                x 153
-                y 113
-            }
-            b {
-                image  key.png
-                x 190
-                y 113
-            }
-            n {
-                image  key.png
-                x 227
-                y 113
-            }
-            m {
-                image  key.png
-                x 264
-                y 113
-            }
-            PERIOD {
-                image  key.png
-                x 301
-                y 113
-            }
-            ENTER {
-                image  key.png
-                x 338
-                y 113
-            }
-
-            ALT {
-                image  key.png
-                x  5
-                y 149
-            }
-            SYM {
-                image  key.png
-                x 42
-                y 149
-            }
-            AT {
-                image  key.png
-                x 79
-                y 149
-            }
-            SPACE {
-                image  spacebar.png
-                x 116
-                y 149
-            }
-            SLASH {
-                image  key.png
-                x 264
-                y 149
-            }
-            COMMA {
-                image  key.png
-                x 301
-                y 149
-            }
-            ALT2 {
-                image  key.png
-                x 338
-                y 149
-            }
-
-        }
-    }
-}
-
-layouts {
-    portrait {
-        width     711
-        height    486
-        color     0xe0e0e0
-        event     EV_SW:0:1
-        
-        part1 {
-            name    portrait
-            x       0
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       800
-            y       0
-        }
-
-        part3 {
-            name    device
-            x       28
-            y       27
-        }
-        part4 {
-            name     controls
-            x        396
-            y        53
-        }
-        part5 {
-            name     keyboard
-            x        315
-            y        280
-        }
-    }
-
-    landscape {
-        width     640
-        height    522
-        color     0xe0e0e0
-        event     EV_SW:0:0
-
-        dpad-rotation 3
-
-        part1 {
-            name    portrait
-            x       800
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       0
-            y       0
-        }
-
-        part3 {
-            name      device
-            x         104
-            y         270
-            rotation  3
-        }
-
-        part4 {
-            name     controls
-            x        410
-            y        317
-        }
-
-        part5 {
-            name     keyboard
-            x        18
-            y        317
-        }
-    }
-}
-
-keyboard {
-    charmap qwerty2
-}
-
-network {
-    speed  full
-    delay  none
-}
diff --git a/emulator/skins/WQVGA432/select.png b/emulator/skins/WQVGA432/select.png
deleted file mode 100644
index f4a65d3..0000000
--- a/emulator/skins/WQVGA432/select.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WQVGA432/spacebar.png b/emulator/skins/WQVGA432/spacebar.png
deleted file mode 100644
index aa459bd..0000000
--- a/emulator/skins/WQVGA432/spacebar.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/arrow_down.png b/emulator/skins/WVGA800/arrow_down.png
deleted file mode 100644
index b9fde22..0000000
--- a/emulator/skins/WVGA800/arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/arrow_left.png b/emulator/skins/WVGA800/arrow_left.png
deleted file mode 100644
index 281b192..0000000
--- a/emulator/skins/WVGA800/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/arrow_right.png b/emulator/skins/WVGA800/arrow_right.png
deleted file mode 100644
index 4cbc65d..0000000
--- a/emulator/skins/WVGA800/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/arrow_up.png b/emulator/skins/WVGA800/arrow_up.png
deleted file mode 100644
index 29c7121..0000000
--- a/emulator/skins/WVGA800/arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/background_land.png b/emulator/skins/WVGA800/background_land.png
deleted file mode 100644
index 4967717..0000000
--- a/emulator/skins/WVGA800/background_land.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/background_port.png b/emulator/skins/WVGA800/background_port.png
deleted file mode 100644
index 13ef2ea..0000000
--- a/emulator/skins/WVGA800/background_port.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/button.png b/emulator/skins/WVGA800/button.png
deleted file mode 100644
index 8281d20..0000000
--- a/emulator/skins/WVGA800/button.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/controls.png b/emulator/skins/WVGA800/controls.png
deleted file mode 100644
index 04b85e2..0000000
--- a/emulator/skins/WVGA800/controls.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/hardware.ini b/emulator/skins/WVGA800/hardware.ini
deleted file mode 100644
index 9aec915..0000000
--- a/emulator/skins/WVGA800/hardware.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-# skin-specific hardware values
-hw.lcd.density=240
-vm.heapSize=24
diff --git a/emulator/skins/WVGA800/key.png b/emulator/skins/WVGA800/key.png
deleted file mode 100644
index 40b03bf..0000000
--- a/emulator/skins/WVGA800/key.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/keyboard.png b/emulator/skins/WVGA800/keyboard.png
deleted file mode 100644
index ca49dcf..0000000
--- a/emulator/skins/WVGA800/keyboard.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/layout b/emulator/skins/WVGA800/layout
deleted file mode 100644
index 63647f3..0000000
--- a/emulator/skins/WVGA800/layout
+++ /dev/null
@@ -1,439 +0,0 @@
-parts {
-    portrait {
-        background {
-            image   background_port.png
-        }
-    }
-    landscape {
-        background {
-            image   background_land.png
-        }
-    }
-
-    device {
-        display {
-            width   480
-            height  800
-            x       0
-            y       0
-        }
-    }
-    
-    controls {
-        background {
-            image   controls.png
-        }
-        buttons {
-            soft-left {
-                    image button.png
-                    x 56
-                    y 142
-            }
-            home {
-                    image button.png
-                    x 0
-                    y 142
-            }
-            back {
-                    image button.png
-                    x 112
-                    y 142
-            }
-            dpad-up {
-                    image arrow_up.png
-                    x 77
-                    y 53
-            }
-            dpad-down {
-                    image arrow_down.png
-                    x 77
-                    y 106
-            }
-            dpad-left {
-                    image arrow_left.png
-                    x 53
-                    y 53
-            }
-            dpad-right {
-                    image arrow_right.png
-                    x 123
-                    y 53
-            }
-            dpad-center {
-                    image select.png
-                    x 77
-                    y 81
-            }
-            phone-dial {
-                    image button.png
-                    x 0
-                    y 71
-            }
-            phone-hangup {
-                    image button.png
-                    x 168
-                    y 71
-            }
-
-            power {
-                    image button.png
-                    x 168
-                    y 0
-            }
-
-            volume-up {
-                    image button.png
-                    x 112
-                    y 0
-            }
-
-            volume-down {
-                    image button.png
-                    x 56
-                    y 0
-            }
-
-            search {
-                    image button.png
-                    x 168
-                    y 142
-            }
-
-        }
-    }
-
-    keyboard {
-        background {
-            image   keyboard.png
-        }
-        buttons {
-            1 {
-                image  key.png
-                x  5
-                y  5
-            }
-            2 {
-                image  key.png
-                x 42
-                y 5
-            }
-            3 {
-                image  key.png
-                x 79
-                y 5
-            }
-            4 {
-                image  key.png
-                x 116
-                y 5
-            }
-            5 {
-                image  key.png
-                x 153
-                y 5
-            }
-            6 {
-                image  key.png
-                x 190
-                y 5
-            }
-            7 {
-                image  key.png
-                x 227
-                y 5
-            }
-            8 {
-                image  key.png
-                x 264
-                y 5
-            }
-            9 {
-                image  key.png
-                x 301
-                y 5
-            }
-            0 {
-                image  key.png
-                x 338
-                y 5
-            }
-
-            q {
-                image  key.png
-                x  5
-                y  41
-            }
-            w {
-                image  key.png
-                x 42
-                y 41
-            }
-            e {
-                image  key.png
-                x 79
-                y 41
-            }
-            r {
-                image  key.png
-                x 116
-                y 41
-            }
-            t {
-                image  key.png
-                x 153
-                y 41
-            }
-            y {
-                image  key.png
-                x 190
-                y 41
-            }
-            u {
-                image  key.png
-                x 227
-                y 41
-            }
-            i {
-                image  key.png
-                x 264
-                y 41
-            }
-            o {
-                image  key.png
-                x 301
-                y 41
-            }
-            p {
-                image  key.png
-                x 338
-                y 41
-            }
-
-            a {
-                image  key.png
-                x  5
-                y 77
-            }
-            s {
-                image  key.png
-                x 42
-                y 77
-            }
-            d {
-                image  key.png
-                x 79
-                y 77
-            }
-            f {
-                image  key.png
-                x 116
-                y 77
-            }
-            g {
-                image  key.png
-                x 153
-                y 77
-            }
-            h {
-                image  key.png
-                x 190
-                y 77
-            }
-            j {
-                image  key.png
-                x 227
-                y 77
-            }
-            k {
-                image  key.png
-                x 264
-                y 77
-            }
-            l {
-                image  key.png
-                x 301
-                y 77
-            }
-            DEL {
-                image  key.png
-                x 338
-                y 77
-            }
-
-            CAP {
-                image  key.png
-                x  5
-                y 113
-            }
-            z {
-                image  key.png
-                x 42
-                y 113
-            }
-            x {
-                image  key.png
-                x 79
-                y 113
-            }
-            c {
-                image  key.png
-                x 116
-                y 113
-            }
-            v {
-                image  key.png
-                x 153
-                y 113
-            }
-            b {
-                image  key.png
-                x 190
-                y 113
-            }
-            n {
-                image  key.png
-                x 227
-                y 113
-            }
-            m {
-                image  key.png
-                x 264
-                y 113
-            }
-            PERIOD {
-                image  key.png
-                x 301
-                y 113
-            }
-            ENTER {
-                image  key.png
-                x 338
-                y 113
-            }
-
-            ALT {
-                image  key.png
-                x  5
-                y 149
-            }
-            SYM {
-                image  key.png
-                x 42
-                y 149
-            }
-            AT {
-                image  key.png
-                x 79
-                y 149
-            }
-            SPACE {
-                image  spacebar.png
-                x 116
-                y 149
-            }
-            SLASH {
-                image  key.png
-                x 264
-                y 149
-            }
-            COMMA {
-                image  key.png
-                x 301
-                y 149
-            }
-            ALT2 {
-                image  key.png
-                x 338
-                y 149
-            }
-
-        }
-    }
-}
-
-layouts {
-    portrait {
-        width     950
-        height    854
-        color     0xe0e0e0
-        event     EV_SW:0:1
-        
-        part1 {
-            name    portrait
-            x       0
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       1000
-            y       0
-        }
-
-        part3 {
-            name    device
-            x       27
-            y       27
-        }
-        part4 {
-            name    controls
-            x       635
-            y       207
-        }
-        part5 {
-            name    keyboard
-            x       554
-            y       459
-        }
-
-    }
-
-    landscape {
-        width     853
-        height    761
-        color     0xe0e0e0
-        event     EV_SW:0:0
-
-        dpad-rotation 3
-
-        part1 {
-            name    portrait
-            x       900
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       0
-            y       0
-        }
-
-        part3 {
-            name      device
-            x         26
-            y         509
-            rotation  3
-        }
-
-        part4 {
-            name     controls
-            x        539
-            y        556
-        }
-
-        part5 {
-            name     keyboard
-            x        98
-            y        556
-        }
-    }
-}
-
-keyboard {
-    charmap qwerty2
-}
-
-network {
-    speed  full
-    delay  none
-}
diff --git a/emulator/skins/WVGA800/select.png b/emulator/skins/WVGA800/select.png
deleted file mode 100644
index f4a65d3..0000000
--- a/emulator/skins/WVGA800/select.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA800/spacebar.png b/emulator/skins/WVGA800/spacebar.png
deleted file mode 100644
index aa459bd..0000000
--- a/emulator/skins/WVGA800/spacebar.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/arrow_down.png b/emulator/skins/WVGA854/arrow_down.png
deleted file mode 100644
index b9fde22..0000000
--- a/emulator/skins/WVGA854/arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/arrow_left.png b/emulator/skins/WVGA854/arrow_left.png
deleted file mode 100644
index 281b192..0000000
--- a/emulator/skins/WVGA854/arrow_left.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/arrow_right.png b/emulator/skins/WVGA854/arrow_right.png
deleted file mode 100644
index 4cbc65d..0000000
--- a/emulator/skins/WVGA854/arrow_right.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/arrow_up.png b/emulator/skins/WVGA854/arrow_up.png
deleted file mode 100644
index 29c7121..0000000
--- a/emulator/skins/WVGA854/arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/background_land.png b/emulator/skins/WVGA854/background_land.png
deleted file mode 100644
index 4f0f90e..0000000
--- a/emulator/skins/WVGA854/background_land.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/background_port.png b/emulator/skins/WVGA854/background_port.png
deleted file mode 100644
index e35bf67..0000000
--- a/emulator/skins/WVGA854/background_port.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/button.png b/emulator/skins/WVGA854/button.png
deleted file mode 100644
index 8281d20..0000000
--- a/emulator/skins/WVGA854/button.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/controls.png b/emulator/skins/WVGA854/controls.png
deleted file mode 100644
index 04b85e2..0000000
--- a/emulator/skins/WVGA854/controls.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/hardware.ini b/emulator/skins/WVGA854/hardware.ini
deleted file mode 100644
index 9aec915..0000000
--- a/emulator/skins/WVGA854/hardware.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-# skin-specific hardware values
-hw.lcd.density=240
-vm.heapSize=24
diff --git a/emulator/skins/WVGA854/key.png b/emulator/skins/WVGA854/key.png
deleted file mode 100644
index 40b03bf..0000000
--- a/emulator/skins/WVGA854/key.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/keyboard.png b/emulator/skins/WVGA854/keyboard.png
deleted file mode 100644
index ca49dcf..0000000
--- a/emulator/skins/WVGA854/keyboard.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/layout b/emulator/skins/WVGA854/layout
deleted file mode 100644
index b086ddc..0000000
--- a/emulator/skins/WVGA854/layout
+++ /dev/null
@@ -1,439 +0,0 @@
-parts {
-    portrait {
-        background {
-            image   background_port.png
-        }
-    }
-    landscape {
-        background {
-            image   background_land.png
-        }
-    }
-
-    device {
-        display {
-            width   480
-            height  854
-            x       0
-            y       0
-        }
-    }
-    
-    controls {
-        background {
-            image   controls.png
-        }
-        buttons {
-            soft-left {
-                    image button.png
-                    x 56
-                    y 142
-            }
-            home {
-                    image button.png
-                    x 0
-                    y 142
-            }
-            back {
-                    image button.png
-                    x 112
-                    y 142
-            }
-            dpad-up {
-                    image arrow_up.png
-                    x 77
-                    y 53
-            }
-            dpad-down {
-                    image arrow_down.png
-                    x 77
-                    y 106
-            }
-            dpad-left {
-                    image arrow_left.png
-                    x 53
-                    y 53
-            }
-            dpad-right {
-                    image arrow_right.png
-                    x 123
-                    y 53
-            }
-            dpad-center {
-                    image select.png
-                    x 77
-                    y 81
-            }
-            phone-dial {
-                    image button.png
-                    x 0
-                    y 71
-            }
-            phone-hangup {
-                    image button.png
-                    x 168
-                    y 71
-            }
-
-            power {
-                    image button.png
-                    x 168
-                    y 0
-            }
-
-            volume-up {
-                    image button.png
-                    x 112
-                    y 0
-            }
-
-            volume-down {
-                    image button.png
-                    x 56
-                    y 0
-            }
-
-            search {
-                    image button.png
-                    x 168
-                    y 142
-            }
-
-        }
-    }
-
-    keyboard {
-        background {
-            image   keyboard.png
-        }
-        buttons {
-            1 {
-                image  key.png
-                x  5
-                y  5
-            }
-            2 {
-                image  key.png
-                x 42
-                y 5
-            }
-            3 {
-                image  key.png
-                x 79
-                y 5
-            }
-            4 {
-                image  key.png
-                x 116
-                y 5
-            }
-            5 {
-                image  key.png
-                x 153
-                y 5
-            }
-            6 {
-                image  key.png
-                x 190
-                y 5
-            }
-            7 {
-                image  key.png
-                x 227
-                y 5
-            }
-            8 {
-                image  key.png
-                x 264
-                y 5
-            }
-            9 {
-                image  key.png
-                x 301
-                y 5
-            }
-            0 {
-                image  key.png
-                x 338
-                y 5
-            }
-
-            q {
-                image  key.png
-                x  5
-                y  41
-            }
-            w {
-                image  key.png
-                x 42
-                y 41
-            }
-            e {
-                image  key.png
-                x 79
-                y 41
-            }
-            r {
-                image  key.png
-                x 116
-                y 41
-            }
-            t {
-                image  key.png
-                x 153
-                y 41
-            }
-            y {
-                image  key.png
-                x 190
-                y 41
-            }
-            u {
-                image  key.png
-                x 227
-                y 41
-            }
-            i {
-                image  key.png
-                x 264
-                y 41
-            }
-            o {
-                image  key.png
-                x 301
-                y 41
-            }
-            p {
-                image  key.png
-                x 338
-                y 41
-            }
-
-            a {
-                image  key.png
-                x  5
-                y 77
-            }
-            s {
-                image  key.png
-                x 42
-                y 77
-            }
-            d {
-                image  key.png
-                x 79
-                y 77
-            }
-            f {
-                image  key.png
-                x 116
-                y 77
-            }
-            g {
-                image  key.png
-                x 153
-                y 77
-            }
-            h {
-                image  key.png
-                x 190
-                y 77
-            }
-            j {
-                image  key.png
-                x 227
-                y 77
-            }
-            k {
-                image  key.png
-                x 264
-                y 77
-            }
-            l {
-                image  key.png
-                x 301
-                y 77
-            }
-            DEL {
-                image  key.png
-                x 338
-                y 77
-            }
-
-            CAP {
-                image  key.png
-                x  5
-                y 113
-            }
-            z {
-                image  key.png
-                x 42
-                y 113
-            }
-            x {
-                image  key.png
-                x 79
-                y 113
-            }
-            c {
-                image  key.png
-                x 116
-                y 113
-            }
-            v {
-                image  key.png
-                x 153
-                y 113
-            }
-            b {
-                image  key.png
-                x 190
-                y 113
-            }
-            n {
-                image  key.png
-                x 227
-                y 113
-            }
-            m {
-                image  key.png
-                x 264
-                y 113
-            }
-            PERIOD {
-                image  key.png
-                x 301
-                y 113
-            }
-            ENTER {
-                image  key.png
-                x 338
-                y 113
-            }
-
-            ALT {
-                image  key.png
-                x  5
-                y 149
-            }
-            SYM {
-                image  key.png
-                x 42
-                y 149
-            }
-            AT {
-                image  key.png
-                x 79
-                y 149
-            }
-            SPACE {
-                image  spacebar.png
-                x 116
-                y 149
-            }
-            SLASH {
-                image  key.png
-                x 264
-                y 149
-            }
-            COMMA {
-                image  key.png
-                x 301
-                y 149
-            }
-            ALT2 {
-                image  key.png
-                x 338
-                y 149
-            }
-
-        }
-    }
-}
-
-layouts {
-    portrait {
-        width     950
-        height    908
-        color     0xe0e0e0
-        event     EV_SW:0:1
-        
-        part1 {
-            name    portrait
-            x       0
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       1000
-            y       0
-        }
-
-        part3 {
-            name    device
-            x       27
-            y       27
-        }
-        part4 {
-            name    controls
-            x       635
-            y       234
-        }
-        part5 {
-            name    keyboard
-            x       554
-            y       486
-        }
-
-    }
-
-    landscape {
-        width     907
-        height    761
-        color     0xe0e0e0
-        event     EV_SW:0:0
-
-        dpad-rotation 3
-
-        part1 {
-            name    portrait
-            x       900
-            y       0
-        }
-
-        part2 {
-            name    landscape
-            x       0
-            y       0
-        }
-
-        part3 {
-            name      device
-            x         26
-            y         509
-            rotation  3
-        }
-
-        part4 {
-            name     controls
-            x        567
-            y        556
-        }
-
-        part5 {
-            name     keyboard
-            x        126
-            y        556
-        }
-    }
-}
-
-keyboard {
-    charmap qwerty2
-}
-
-network {
-    speed  full
-    delay  none
-}
diff --git a/emulator/skins/WVGA854/select.png b/emulator/skins/WVGA854/select.png
deleted file mode 100644
index f4a65d3..0000000
--- a/emulator/skins/WVGA854/select.png
+++ /dev/null
Binary files differ
diff --git a/emulator/skins/WVGA854/spacebar.png b/emulator/skins/WVGA854/spacebar.png
deleted file mode 100644
index aa459bd..0000000
--- a/emulator/skins/WVGA854/spacebar.png
+++ /dev/null
Binary files differ
diff --git a/emulator/tools/Android.mk b/emulator/tools/Android.mk
deleted file mode 100644
index c9d9613..0000000
--- a/emulator/tools/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# this file is used to build emulator-specific program tools
-# that should only run in the emulator.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(TARGET_PRODUCT),sim)
-
-# The 'qemu-props' program is run from /system/etc/init.goldfish.rc
-# to setup various system properties sent by the emulator program.
-#
-include $(CLEAR_VARS)
-LOCAL_MODULE    := qemu-props
-LOCAL_SRC_FILES := qemu-props.c
-LOCAL_SHARED_LIBRARIES := libcutils
-# we don't want this in 'user' builds which don't have
-# emulator-specific binaries.
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_EXECUTABLE)
-
-endif # TARGET_PRODUCT != sim
-
diff --git a/emulator/tools/qemu-props.c b/emulator/tools/qemu-props.c
deleted file mode 100644
index 09105fc..0000000
--- a/emulator/tools/qemu-props.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* this program is used to read a set of system properties and their values
- * from the emulator program and set them in the currently-running emulated
- * system. It does so by connecting to the 'boot-properties' qemud service.
- *
- * This program should be run as root and called from
- * /system/etc/init.goldfish.rc exclusively.
- */
-
-#define LOG_TAG  "qemu-props"
-
-#define DEBUG  1
-
-#if DEBUG
-#  include <cutils/log.h>
-#  define  DD(...)    LOGI(__VA_ARGS__)
-#else
-#  define  DD(...)    ((void)0)
-#endif
-
-#include <cutils/properties.h>
-#include <unistd.h>
-#include <hardware/qemud.h>
-
-/* Name of the qemud service we want to connect to.
- */
-#define  QEMUD_SERVICE  "boot-properties"
-
-#define  MAX_TRIES      5
-
-int  main(void)
-{
-    int  qemud_fd, count = 0;
-
-    /* try to connect to the qemud service */
-    {
-        int  tries = MAX_TRIES;
-
-        while (1) {
-            qemud_fd = qemud_channel_open( "boot-properties" );
-            if (qemud_fd >= 0)
-                break;
-
-            if (--tries <= 0) {
-                DD("Could not connect after too many tries. Aborting");
-                return 1;
-            }
-
-            DD("waiting 1s to wait for qemud.");
-            sleep(1);
-        }
-    }
-
-    DD("connected to '%s' qemud service.", QEMUD_SERVICE);
-
-    /* send the 'list' command to the service */
-    if (qemud_channel_send(qemud_fd, "list", -1) < 0) {
-        DD("could not send command to '%s' service", QEMUD_SERVICE);
-        return 1;
-    }
-
-    /* read each system property as a single line from the service,
-     * until exhaustion.
-     */
-    for (;;)
-    {
-#define  BUFF_SIZE   (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
-
-        char* q;
-        char  temp[BUFF_SIZE];
-        int   len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1);
-
-        if (len < 0 || len > BUFF_SIZE-1)
-            break;
-
-        temp[len] = '\0';  /* zero-terminate string */
-
-        DD("received: %.*s", len, temp);
-
-        /* separate propery name from value */
-        q = strchr(temp, '=');
-        if (q == NULL) {
-            DD("invalid format, ignored.");
-            continue;
-        }
-        *q++ = '\0';
-
-        if (property_set(temp, q) < 0) {
-            DD("could not set property '%s' to '%s'", temp, q);
-        } else {
-            count += 1;
-        }
-    }
-
-    /* finally, close the channel and exit */
-    close(qemud_fd);
-    DD("exiting (%d properties set).", count);
-    return 0;
-}
diff --git a/tools/androidprefs/.classpath b/tools/androidprefs/.classpath
deleted file mode 100644
index fb50116..0000000
--- a/tools/androidprefs/.classpath
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/androidprefs/.gitignore b/tools/androidprefs/.gitignore
deleted file mode 100644
index fe99505..0000000
--- a/tools/androidprefs/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin
-
diff --git a/tools/androidprefs/.project b/tools/androidprefs/.project
deleted file mode 100644
index 6633bba..0000000
--- a/tools/androidprefs/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>AndroidPrefs</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/androidprefs/Android.mk b/tools/androidprefs/Android.mk
deleted file mode 100644
index 363b085..0000000
--- a/tools/androidprefs/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# 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.
-#
-JARUTILS_LOCAL_DIR := $(call my-dir)
-include $(JARUTILS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/androidprefs/src/Android.mk b/tools/androidprefs/src/Android.mk
deleted file mode 100644
index ddc0aa6..0000000
--- a/tools/androidprefs/src/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_MODULE := androidprefs
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/androidprefs/src/com/android/prefs/AndroidLocation.java b/tools/androidprefs/src/com/android/prefs/AndroidLocation.java
deleted file mode 100644
index 446c426..0000000
--- a/tools/androidprefs/src/com/android/prefs/AndroidLocation.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.android.prefs;
-
-import java.io.File;
-
-/**
- * Manages the location of the android files (including emulator files, ddms config, debug keystore)
- */
-public final class AndroidLocation {
-    /**
-     * Virtual Device folder inside the path returned by {@link #getFolder()}
-     */
-    public static final String FOLDER_AVD = "avd";
-
-    /**
-     * Throw when the location of the android folder couldn't be found.
-     */
-    public static final class AndroidLocationException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public AndroidLocationException(String string) {
-            super(string);
-        }
-    }
-
-    private static String sPrefsLocation = null;
-
-    /**
-     * Returns the folder used to store android related files.
-     * @return an OS specific path, terminated by a separator.
-     * @throws AndroidLocationException
-     */
-    public final static String getFolder() throws AndroidLocationException {
-        if (sPrefsLocation == null) {
-            String home = findValidPath("ANDROID_SDK_HOME", "user.home", "HOME");
-
-            // if the above failed, we throw an exception.
-            if (home == null) {
-                throw new AndroidLocationException(
-                        "Unable to get the home directory. Make sure the user.home property is set up");
-            } else {
-                sPrefsLocation = home + File.separator + ".android" + File.separator;
-            }
-        }
-
-        // make sure the folder exists!
-        File f = new File(sPrefsLocation);
-        if (f.exists() == false) {
-            try {
-                f.mkdir();
-            } catch (SecurityException e) {
-                AndroidLocationException e2 = new AndroidLocationException(String.format(
-                        "Unable to create folder '%1$s'. " +
-                        "This is the path of preference folder expected by the Android tools.",
-                        sPrefsLocation));
-                e2.initCause(e);
-                throw e2;
-            }
-        } else if (f.isFile()) {
-            throw new AndroidLocationException(sPrefsLocation +
-                    " is not a directory! " +
-                    "This is the path of preference folder expected by the Android tools.");
-        }
-
-        return sPrefsLocation;
-    }
-
-    /**
-     * Checks a list of system properties and/or system environment variables for validity, and
-     * existing director, and returns the first one.
-     * @param names
-     * @return the content of the first property/variable.
-     */
-    private static String findValidPath(String... names) {
-        for (String name : names) {
-            String path;
-            if (name.indexOf('.') != -1) {
-                path = System.getProperty(name);
-            } else {
-                path = System.getenv(name);
-            }
-
-            if (path != null) {
-                File f = new File(path);
-                if (f.isDirectory()) {
-                    return path;
-                }
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/tools/anttasks/.classpath b/tools/anttasks/.classpath
deleted file mode 100644
index d6ce15a..0000000
--- a/tools/anttasks/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
-	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/ant/ant.jar"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ApkBuilder"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/anttasks/.gitignore b/tools/anttasks/.gitignore
deleted file mode 100644
index fe99505..0000000
--- a/tools/anttasks/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin
-
diff --git a/tools/anttasks/.project b/tools/anttasks/.project
deleted file mode 100644
index aed1b61..0000000
--- a/tools/anttasks/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ant-tasks</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/anttasks/Android.mk b/tools/anttasks/Android.mk
deleted file mode 100644
index 15ee903..0000000
--- a/tools/anttasks/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# 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.
-#
-ANTTASKS_LOCAL_DIR := $(call my-dir)
-include $(ANTTASKS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/anttasks/src/Android.mk b/tools/anttasks/src/Android.mk
deleted file mode 100644
index 94d6d3f..0000000
--- a/tools/anttasks/src/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := \
-        sdklib \
-        apkbuilder \
-        ant
-
-LOCAL_MODULE := anttasks
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java b/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java
deleted file mode 100644
index 47b8f48..0000000
--- a/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ant;
-
-import com.android.sdklib.internal.project.ApkConfigurationHelper;
-import com.android.sdklib.internal.project.ApkSettings;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.taskdefs.ExecTask;
-import org.apache.tools.ant.types.Path;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Task able to run an Exec task on aapt several times.
- * It does not follow the exec task format, instead it has its own parameters, which maps
- * directly to aapt.
- *
- */
-public final class AaptExecLoopTask extends Task {
-
-    private String mExecutable;
-    private String mCommand;
-    private String mManifest;
-    private String mResources;
-    private String mAssets;
-    private String mAndroidJar;
-    private String mOutFolder;
-    private String mBaseName;
-
-    /**
-     * Sets the value of the "executable" attribute.
-     * @param executable the value.
-     */
-    public void setExecutable(String executable) {
-        mExecutable = executable;
-    }
-
-    /**
-     * Sets the value of the "command" attribute.
-     * @param command the value.
-     */
-    public void setCommand(String command) {
-        mCommand = command;
-    }
-
-    /**
-     * Sets the value of the "manifest" attribute.
-     * @param manifest the value.
-     */
-    public void setManifest(Path manifest) {
-        mManifest = manifest.toString();
-    }
-
-    /**
-     * Sets the value of the "resources" attribute.
-     * @param resources the value.
-     */
-    public void setResources(Path resources) {
-        mResources = resources.toString();
-    }
-
-    /**
-     * Sets the value of the "assets" attribute.
-     * @param assets the value.
-     */
-    public void setAssets(Path assets) {
-        mAssets = assets.toString();
-    }
-
-    /**
-     * Sets the value of the "androidjar" attribute.
-     * @param androidJar the value.
-     */
-    public void setAndroidjar(Path androidJar) {
-        mAndroidJar = androidJar.toString();
-    }
-
-    /**
-     * Sets the value of the "outfolder" attribute.
-     * @param outFolder the value.
-     */
-    public void setOutfolder(Path outFolder) {
-        mOutFolder = outFolder.toString();
-    }
-
-    /**
-     * Sets the value of the "basename" attribute.
-     * @param baseName the value.
-     */
-    public void setBasename(String baseName) {
-        mBaseName = baseName;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * Executes the loop. Based on the values inside default.properties, this will
-     * create alternate temporary ap_ files.
-     *
-     * @see org.apache.tools.ant.Task#execute()
-     */
-    @Override
-    public void execute() throws BuildException {
-        Project taskProject = getProject();
-
-        // first do a full resource package
-        createPackage(null /*configName*/, null /*resourceFilter*/);
-
-        // now see if we need to create file with filtered resources.
-        // Get the project base directory.
-        File baseDir = taskProject.getBaseDir();
-        ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
-                PropertyType.DEFAULT);
-
-
-        ApkSettings apkSettings = ApkConfigurationHelper.getSettings(properties);
-        if (apkSettings != null) {
-            Map<String, String> apkFilters = apkSettings.getResourceFilters();
-            if (apkFilters.size() > 0) {
-                for (Entry<String, String> entry : apkFilters.entrySet()) {
-                    createPackage(entry.getKey(), entry.getValue());
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates a resource package.
-     * @param configName the name of the filter config. Can be null in which case a full resource
-     * package will be generated.
-     * @param resourceFilter the resource configuration filter to pass to aapt (if configName is
-     * non null)
-     */
-    private void createPackage(String configName, String resourceFilter) {
-        Project taskProject = getProject();
-
-        if (configName == null || resourceFilter == null) {
-            System.out.println("Creating full resource package...");
-        } else {
-            System.out.println(String.format(
-                    "Creating resource package for config '%1$s' (%2$s)...",
-                    configName, resourceFilter));
-        }
-
-        // create a task for the default apk.
-        ExecTask task = new ExecTask();
-        task.setExecutable(mExecutable);
-        task.setFailonerror(true);
-
-        // aapt command. Only "package" is supported at this time really.
-        task.createArg().setValue(mCommand);
-
-        // filters if needed
-        if (configName != null && resourceFilter != null) {
-            task.createArg().setValue("-c");
-            task.createArg().setValue(resourceFilter);
-        }
-
-        // force flag
-        task.createArg().setValue("-f");
-
-        // manifest location
-        task.createArg().setValue("-M");
-        task.createArg().setValue(mManifest);
-
-        // resources location. This may not exists, and aapt doesn't like it, so we check first.
-        File res = new File(mResources);
-        if (res.isDirectory()) {
-            task.createArg().setValue("-S");
-            task.createArg().setValue(mResources);
-        }
-
-        // assets location. This may not exists, and aapt doesn't like it, so we check first.
-        File assets = new File(mAssets);
-        if (assets.isDirectory()) {
-            task.createArg().setValue("-A");
-            task.createArg().setValue(mAssets);
-        }
-
-        // android.jar
-        task.createArg().setValue("-I");
-        task.createArg().setValue(mAndroidJar);
-
-        // out file. This is based on the outFolder, baseName, and the configName (if applicable)
-        String filename;
-        if (configName != null && resourceFilter != null) {
-            filename = mBaseName + "-" + configName + ".ap_";
-        } else {
-            filename = mBaseName + ".ap_";
-        }
-
-        File file = new File(mOutFolder, filename);
-        task.createArg().setValue("-F");
-        task.createArg().setValue(file.getAbsolutePath());
-
-        // final setup of the task
-        task.setProject(taskProject);
-        task.setOwningTarget(getOwningTarget());
-
-        // execute it.
-        task.execute();
-    }
-}
diff --git a/tools/anttasks/src/com/android/ant/ApkBuilderTask.java b/tools/anttasks/src/com/android/ant/ApkBuilderTask.java
deleted file mode 100644
index a7ee02b..0000000
--- a/tools/anttasks/src/com/android/ant/ApkBuilderTask.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ant;
-
-import com.android.apkbuilder.ApkBuilder.ApkCreationException;
-import com.android.apkbuilder.internal.ApkBuilderImpl;
-import com.android.apkbuilder.internal.ApkBuilderImpl.ApkFile;
-import com.android.sdklib.internal.project.ApkConfigurationHelper;
-import com.android.sdklib.internal.project.ApkSettings;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.ProjectComponent;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Path.PathElement;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class ApkBuilderTask extends Task {
-
-    // ref id to the <path> object containing all the boot classpaths.
-    private final static String REF_APK_PATH = "android.apks.path";
-
-    /**
-     * Class to represent nested elements. Since they all have only one attribute ('path'), the
-     * same class can be used for all the nested elements (zip, file, sourcefolder, jarfolder,
-     * nativefolder).
-     */
-    public final static class Value extends ProjectComponent {
-        String mPath;
-
-        /**
-         * Sets the value of the "path" attribute.
-         * @param path the value.
-         */
-        public void setPath(Path path) {
-            mPath = path.toString();
-        }
-    }
-
-    private String mOutFolder;
-    private String mBaseName;
-    private boolean mVerbose = false;
-    private boolean mSigned = true;
-
-    private final ArrayList<Value> mZipList = new ArrayList<Value>();
-    private final ArrayList<Value> mFileList = new ArrayList<Value>();
-    private final ArrayList<Value> mSourceList = new ArrayList<Value>();
-    private final ArrayList<Value> mJarfolderList = new ArrayList<Value>();
-    private final ArrayList<Value> mJarfileList = new ArrayList<Value>();
-    private final ArrayList<Value> mNativeList = new ArrayList<Value>();
-
-    private final ArrayList<FileInputStream> mZipArchives = new ArrayList<FileInputStream>();
-    private final ArrayList<File> mArchiveFiles = new ArrayList<File>();
-    private final ArrayList<ApkFile> mJavaResources = new ArrayList<ApkFile>();
-    private final ArrayList<FileInputStream> mResourcesJars = new ArrayList<FileInputStream>();
-    private final ArrayList<ApkFile> mNativeLibraries = new ArrayList<ApkFile>();
-
-    /**
-     * Sets the value of the "outfolder" attribute.
-     * @param outFolder the value.
-     */
-    public void setOutfolder(Path outFolder) {
-        mOutFolder = outFolder.toString();
-    }
-
-    /**
-     * Sets the value of the "basename" attribute.
-     * @param baseName the value.
-     */
-    public void setBasename(String baseName) {
-        mBaseName = baseName;
-    }
-
-    /**
-     * Sets the value of the "verbose" attribute.
-     * @param verbose the value.
-     */
-    public void setVerbose(boolean verbose) {
-        mVerbose = verbose;
-    }
-
-    /**
-     * Sets the value of the "signed" attribute.
-     * @param signed the value.
-     */
-    public void setSigned(boolean signed) {
-        mSigned = signed;
-    }
-
-    /**
-     * Returns an object representing a nested <var>zip</var> element.
-     */
-    public Object createZip() {
-        Value zip = new Value();
-        mZipList.add(zip);
-        return zip;
-    }
-
-    /**
-     * Returns an object representing a nested <var>file</var> element.
-     */
-    public Object createFile() {
-        Value file = new Value();
-        mFileList.add(file);
-        return file;
-    }
-
-    /**
-     * Returns an object representing a nested <var>sourcefolder</var> element.
-     */
-    public Object createSourcefolder() {
-        Value file = new Value();
-        mSourceList.add(file);
-        return file;
-    }
-
-    /**
-     * Returns an object representing a nested <var>jarfolder</var> element.
-     */
-    public Object createJarfolder() {
-        Value file = new Value();
-        mJarfolderList.add(file);
-        return file;
-    }
-
-    /**
-     * Returns an object representing a nested <var>jarfile</var> element.
-     */
-    public Object createJarfile() {
-        Value file = new Value();
-        mJarfileList.add(file);
-        return file;
-    }
-
-    /**
-     * Returns an object representing a nested <var>nativefolder</var> element.
-     */
-    public Object createNativefolder() {
-        Value file = new Value();
-        mNativeList.add(file);
-        return file;
-    }
-
-    @Override
-    public void execute() throws BuildException {
-        Project antProject = getProject();
-
-        ApkBuilderImpl apkBuilder = new ApkBuilderImpl();
-        apkBuilder.setVerbose(mVerbose);
-        apkBuilder.setSignedPackage(mSigned);
-
-        try {
-            // setup the list of everything that needs to go in the archive.
-
-            // go through the list of zip files to add. This will not include
-            // the resource package, which is handled separaly for each apk to create.
-            for (Value v : mZipList) {
-                FileInputStream input = new FileInputStream(v.mPath);
-                mZipArchives.add(input);
-            }
-
-            // now go through the list of file to directly add the to the list.
-            for (Value v : mFileList) {
-                mArchiveFiles.add(ApkBuilderImpl.getInputFile(v.mPath));
-            }
-
-            // now go through the list of file to directly add the to the list.
-            for (Value v : mSourceList) {
-                ApkBuilderImpl.processSourceFolderForResource(v.mPath, mJavaResources);
-            }
-
-            // now go through the list of jar folders.
-            for (Value v : mJarfolderList) {
-                ApkBuilderImpl.processJarFolder(v.mPath, mResourcesJars);
-            }
-
-            // now go through the list of jar files.
-            for (Value v : mJarfileList) {
-                ApkBuilderImpl.processJarFile(v.mPath, mResourcesJars);
-            }
-
-            // now the native lib folder.
-            for (Value v : mNativeList) {
-                String parameter = v.mPath;
-                File f = new File(parameter);
-
-                // compute the offset to get the relative path
-                int offset = parameter.length();
-                if (parameter.endsWith(File.separator) == false) {
-                    offset++;
-                }
-
-                ApkBuilderImpl.processNativeFolder(offset, f, mNativeLibraries);
-            }
-
-            // create the Path item that will contain all the generated APKs
-            // for reuse by other targets (signing/zipaligning)
-            Path path = new Path(antProject);
-
-            // The createApk method uses mBaseName for the base name of the packages (resources
-            // and apk files).
-            // The generated apk file name is
-            // debug:   {base}[-{config}]-debug-unaligned.apk
-            // release: {base}[-{config}]-unsigned.apk
-            // Unfortunately for 1.5 projects and before the 'install' ant target expects the name
-            // of the default debug package to be {base}-debug.apk
-            // In order to support those package, we look for the 'out.debug.unaligned.package'
-            // property. If this exist, then we generate {base}[-{config}]-debug-unaligned.apk
-            // otherwise we generate {base}[-{config}]-debug.apk
-            // FIXME: Make apkbuilder export the package name used instead of
-            // having to keep apkbuilder and the rules file in sync
-            String debugPackageSuffix = "-debug-unaligned.apk";
-            if (antProject.getProperty("out.debug.unaligned.package") == null
-                    && antProject.getProperty("out-debug-unaligned-package") == null) {
-                debugPackageSuffix = "-debug.apk";
-            }
-
-            // first do a full resource package
-            createApk(apkBuilder, null /*configName*/, null /*resourceFilter*/, path,
-                    debugPackageSuffix);
-
-            // now see if we need to create file with filtered resources.
-            // Get the project base directory.
-            File baseDir = antProject.getBaseDir();
-            ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
-                    PropertyType.DEFAULT);
-
-            ApkSettings apkSettings = ApkConfigurationHelper.getSettings(properties);
-            if (apkSettings != null) {
-                Map<String, String> apkFilters = apkSettings.getResourceFilters();
-                if (apkFilters.size() > 0) {
-                    for (Entry<String, String> entry : apkFilters.entrySet()) {
-                        createApk(apkBuilder, entry.getKey(), entry.getValue(), path,
-                                debugPackageSuffix);
-                    }
-                }
-            }
-
-            // finally sets the path in the project with a reference
-            antProject.addReference(REF_APK_PATH, path);
-
-        } catch (FileNotFoundException e) {
-            throw new BuildException(e);
-        } catch (IllegalArgumentException e) {
-            throw new BuildException(e);
-        } catch (ApkCreationException e) {
-            throw new BuildException(e);
-        }
-    }
-
-    /**
-     * Creates an application package.
-     * @param apkBuilder
-     * @param configName the name of the filter config. Can be null in which case a full resource
-     * package will be generated.
-     * @param resourceFilter the resource configuration filter to pass to aapt (if configName is
-     * non null)
-     * @param path Ant {@link Path} to which add the generated APKs as {@link PathElement}
-     * @param debugPackageSuffix suffix for the debug packages.
-     * @throws FileNotFoundException
-     * @throws ApkCreationException
-     */
-    private void createApk(ApkBuilderImpl apkBuilder, String configName, String resourceFilter,
-            Path path, String debugPackageSuffix)
-            throws FileNotFoundException, ApkCreationException {
-        // All the files to be included in the archive have already been prep'ed up, except
-        // the resource package.
-        // figure out its name.
-        String filename;
-        if (configName != null && resourceFilter != null) {
-            filename = mBaseName + "-" + configName + ".ap_";
-        } else {
-            filename = mBaseName + ".ap_";
-        }
-
-        // now we add it to the list of zip archive (it's just a zip file).
-
-        // it's used as a zip archive input
-        FileInputStream resoucePackageZipFile = new FileInputStream(new File(mOutFolder, filename));
-        mZipArchives.add(resoucePackageZipFile);
-
-        // prepare the filename to generate. Same thing as the resource file.
-        if (configName != null && resourceFilter != null) {
-            filename = mBaseName + "-" + configName;
-        } else {
-            filename = mBaseName;
-        }
-
-        if (mSigned) {
-            filename = filename + debugPackageSuffix;
-        } else {
-            filename = filename + "-unsigned.apk";
-        }
-
-        if (configName == null || resourceFilter == null) {
-            if (mSigned) {
-                System.out.println(String.format(
-                        "Creating %s and signing it with a debug key...", filename));
-            } else {
-                System.out.println(String.format(
-                        "Creating %s for release...", filename));
-            }
-        } else {
-            if (mSigned) {
-                System.out.println(String.format(
-                        "Creating %1$s (with %2$s) and signing it with a debug key...",
-                        filename, resourceFilter));
-            } else {
-                System.out.println(String.format(
-                        "Creating %1$s (with %2$s) for release...",
-                        filename, resourceFilter));
-            }
-        }
-
-        // out File
-        File f = new File(mOutFolder, filename);
-
-        // add it to the Path object
-        PathElement element = path.createPathElement();
-        element.setLocation(f);
-
-        // and generate the apk
-        apkBuilder.createPackage(f.getAbsoluteFile(), mZipArchives,
-                mArchiveFiles, mJavaResources, mResourcesJars, mNativeLibraries);
-
-        // we are done. We need to remove the resource package from the list of zip archives
-        // in case we have another apk to generate.
-        mZipArchives.remove(resoucePackageZipFile);
-    }
-}
diff --git a/tools/anttasks/src/com/android/ant/SetupTask.java b/tools/anttasks/src/com/android/ant/SetupTask.java
deleted file mode 100644
index f13cccd..0000000
--- a/tools/anttasks/src/com/android/ant/SetupTask.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ant;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.xml.AndroidXPathFactory;
-import com.android.sdklib.xml.AndroidManifest;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.ImportTask;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Path.PathElement;
-import org.xml.sax.InputSource;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.HashSet;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Setup/Import Ant task. This task accomplishes:
- * <ul>
- * <li>Gets the project target hash string from {@link ProjectProperties#PROPERTY_TARGET},
- * and resolves it to get the project's {@link IAndroidTarget}.</li>
- * <li>Sets up properties so that aapt can find the android.jar in the resolved target.</li>
- * <li>Sets up the boot classpath ref so that the <code>javac</code> task knows where to find
- * the libraries. This includes the default android.jar from the resolved target but also optional
- * libraries provided by the target (if any, when the target is an add-on).</li>
- * <li>Imports the build rules located in the resolved target so that the build actually does
- * something. This can be disabled with the attribute <var>import</var> set to <code>false</code>
- * </li></ul>
- *
- * This is used in build.xml/template.
- *
- */
-public final class SetupTask extends ImportTask {
-    private final static String ANDROID_RULES = "android_rules.xml";
-    // additional android rules for test project - depends on android_rules.xml
-    private final static String ANDROID_TEST_RULES = "android_test_rules.xml";
-    // ant property with the path to the android.jar
-    private final static String PROPERTY_ANDROID_JAR = "android.jar";
-    // LEGACY - compatibility with 1.6 and before
-    private final static String PROPERTY_ANDROID_JAR_LEGACY = "android-jar";
-    // ant property with the path to the framework.jar
-    private final static String PROPERTY_ANDROID_AIDL = "android.aidl";
-    // LEGACY - compatibility with 1.6 and before
-    private final static String PROPERTY_ANDROID_AIDL_LEGACY = "android-aidl";
-    // ant property with the path to the aapt tool
-    private final static String PROPERTY_AAPT = "aapt";
-    // ant property with the path to the aidl tool
-    private final static String PROPERTY_AIDL = "aidl";
-    // ant property with the path to the dx tool
-    private final static String PROPERTY_DX = "dx";
-    // ref id to the <path> object containing all the boot classpaths.
-    private final static String REF_CLASSPATH = "android.target.classpath";
-
-    private boolean mDoImport = true;
-
-    @Override
-    public void execute() throws BuildException {
-        Project antProject = getProject();
-
-        // get the SDK location
-        String sdkLocation = antProject.getProperty(ProjectProperties.PROPERTY_SDK);
-
-        // check if it's valid and exists
-        if (sdkLocation == null || sdkLocation.length() == 0) {
-            // LEGACY support: project created with 1.6 or before may be using a different
-            // property to declare the location of the SDK. At this point, we cannot
-            // yet check which target is running so we check both always.
-            sdkLocation = antProject.getProperty(ProjectProperties.PROPERTY_SDK_LEGACY);
-            if (sdkLocation == null || sdkLocation.length() == 0) {
-                throw new BuildException("SDK Location is not set.");
-            }
-        }
-
-        File sdk = new File(sdkLocation);
-        if (sdk.isDirectory() == false) {
-            throw new BuildException(String.format("SDK Location '%s' is not valid.", sdkLocation));
-        }
-
-        // get the target property value
-        String targetHashString = antProject.getProperty(ProjectProperties.PROPERTY_TARGET);
-
-        boolean isTestProject = false;
-
-        if (antProject.getProperty("tested.project.dir") != null) {
-            isTestProject = true;
-        }
-
-        if (targetHashString == null) {
-            throw new BuildException("Android Target is not set.");
-        }
-
-        // load up the sdk targets.
-        final ArrayList<String> messages = new ArrayList<String>();
-        SdkManager manager = SdkManager.createManager(sdkLocation, new ISdkLog() {
-            public void error(Throwable t, String errorFormat, Object... args) {
-                if (errorFormat != null) {
-                    messages.add(String.format("Error: " + errorFormat, args));
-                }
-                if (t != null) {
-                    messages.add("Error: " + t.getMessage());
-                }
-            }
-
-            public void printf(String msgFormat, Object... args) {
-                messages.add(String.format(msgFormat, args));
-            }
-
-            public void warning(String warningFormat, Object... args) {
-                messages.add(String.format("Warning: " + warningFormat, args));
-            }
-        });
-
-        if (manager == null) {
-            // since we failed to parse the SDK, lets display the parsing output.
-            for (String msg : messages) {
-                System.out.println(msg);
-            }
-            throw new BuildException("Failed to parse SDK content.");
-        }
-
-        // resolve it
-        IAndroidTarget androidTarget = manager.getTargetFromHashString(targetHashString);
-
-        if (androidTarget == null) {
-            throw new BuildException(String.format(
-                    "Unable to resolve target '%s'", targetHashString));
-        }
-
-        // display it
-        System.out.println("Project Target: " + androidTarget.getName());
-        if (androidTarget.isPlatform() == false) {
-            System.out.println("Vendor: " + androidTarget.getVendor());
-            System.out.println("Platform Version: " + androidTarget.getVersionName());
-        }
-        System.out.println("API level: " + androidTarget.getVersion().getApiString());
-
-        // always check the manifest minSdkVersion.
-        checkManifest(antProject, androidTarget.getVersion());
-
-        // sets up the properties to find android.jar/framework.aidl/target tools
-        String androidJar = androidTarget.getPath(IAndroidTarget.ANDROID_JAR);
-        antProject.setProperty(PROPERTY_ANDROID_JAR, androidJar);
-
-        String androidAidl = androidTarget.getPath(IAndroidTarget.ANDROID_AIDL);
-        antProject.setProperty(PROPERTY_ANDROID_AIDL, androidAidl);
-
-        antProject.setProperty(PROPERTY_AAPT, androidTarget.getPath(IAndroidTarget.AAPT));
-        antProject.setProperty(PROPERTY_AIDL, androidTarget.getPath(IAndroidTarget.AIDL));
-        antProject.setProperty(PROPERTY_DX, androidTarget.getPath(IAndroidTarget.DX));
-
-        // sets up the boot classpath
-
-        // create the Path object
-        Path bootclasspath = new Path(antProject);
-
-        // create a PathElement for the framework jar
-        PathElement element = bootclasspath.createPathElement();
-        element.setPath(androidJar);
-
-        // create PathElement for each optional library.
-        IOptionalLibrary[] libraries = androidTarget.getOptionalLibraries();
-        if (libraries != null) {
-            HashSet<String> visitedJars = new HashSet<String>();
-            for (IOptionalLibrary library : libraries) {
-                String jarPath = library.getJarPath();
-                if (visitedJars.contains(jarPath) == false) {
-                    visitedJars.add(jarPath);
-
-                    element = bootclasspath.createPathElement();
-                    element.setPath(library.getJarPath());
-                }
-            }
-        }
-
-        // finally sets the path in the project with a reference
-        antProject.addReference(REF_CLASSPATH, bootclasspath);
-
-        // find the file to import, and import it.
-        String templateFolder = androidTarget.getPath(IAndroidTarget.TEMPLATES);
-
-        // LEGACY support. android_rules.xml in older platforms expects properties with
-        // older names. This sets those properties to make sure the rules will work.
-        if (androidTarget.getVersion().getApiLevel() <= 4) { // 1.6 and earlier
-            antProject.setProperty(PROPERTY_ANDROID_JAR_LEGACY, androidJar);
-            antProject.setProperty(PROPERTY_ANDROID_AIDL_LEGACY, androidAidl);
-            antProject.setProperty(ProjectProperties.PROPERTY_SDK_LEGACY, sdkLocation);
-            String appPackage = antProject.getProperty(ProjectProperties.PROPERTY_APP_PACKAGE);
-            if (appPackage != null && appPackage.length() > 0) {
-                antProject.setProperty(ProjectProperties.PROPERTY_APP_PACKAGE_LEGACY, appPackage);
-            }
-        }
-
-        // Now the import section. This is only executed if the task actually has to import a file.
-        if (mDoImport) {
-            // make sure the file exists.
-            File templates = new File(templateFolder);
-
-            if (templates.isDirectory() == false) {
-                throw new BuildException(String.format("Template directory '%s' is missing.",
-                        templateFolder));
-            }
-
-            String importedRulesFileName = isTestProject ? ANDROID_TEST_RULES : ANDROID_RULES;
-
-            // now check the rules file exists.
-            File rules = new File(templateFolder, importedRulesFileName);
-
-            if (rules.isFile() == false) {
-                throw new BuildException(String.format("Build rules file '%s' is missing.",
-                        templateFolder));
-            }
-
-            // set the file location to import
-            setFile(rules.getAbsolutePath());
-
-            // and import
-            super.execute();
-        }
-    }
-
-    /**
-     * Sets the value of the "import" attribute.
-     * @param value the value.
-     */
-    public void setImport(boolean value) {
-        mDoImport = value;
-    }
-
-    /**
-     * Checks the manifest <code>minSdkVersion</code> attribute.
-     * @param antProject the ant project
-     * @param androidVersion the version of the platform the project is compiling against.
-     */
-    private void checkManifest(Project antProject, AndroidVersion androidVersion) {
-        try {
-            File manifest = new File(antProject.getBaseDir(), "AndroidManifest.xml");
-
-            XPath xPath = AndroidXPathFactory.newXPath();
-
-            String value = xPath.evaluate(
-                    "/"  + AndroidManifest.NODE_MANIFEST +
-                    "/"  + AndroidManifest.NODE_USES_SDK +
-                    "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX + ":" +
-                            AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
-                    new InputSource(new FileInputStream(manifest)));
-
-            if (androidVersion.isPreview()) {
-                // in preview mode, the content of the minSdkVersion must match exactly the
-                // platform codename.
-                String codeName = androidVersion.getCodename();
-                if (codeName.equals(value) == false) {
-                    throw new BuildException(String.format(
-                            "For '%1$s' SDK Preview, attribute minSdkVersion in AndroidManifest.xml must be '%1$s'",
-                            codeName));
-                }
-            } else if (value.length() > 0) {
-                // for normal platform, we'll only display warnings if the value is lower or higher
-                // than the target api level.
-                // First convert to an int.
-                int minSdkValue = -1;
-                try {
-                    minSdkValue = Integer.parseInt(value);
-                } catch (NumberFormatException e) {
-                    // looks like it's not a number: error!
-                    throw new BuildException(String.format(
-                            "Attribute %1$s in AndroidManifest.xml must be an Integer!",
-                            AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION));
-                }
-
-                int projectApiLevel = androidVersion.getApiLevel();
-                if (minSdkValue < projectApiLevel) {
-                    System.out.println(String.format(
-                            "WARNING: Attribute %1$s in AndroidManifest.xml (%2$d) is lower than the project target API level (%3$d)",
-                            AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
-                            minSdkValue, projectApiLevel));
-                } else if (minSdkValue > androidVersion.getApiLevel()) {
-                    System.out.println(String.format(
-                            "WARNING: Attribute %1$s in AndroidManifest.xml (%2$d) is higher than the project target API level (%3$d)",
-                            AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
-                            minSdkValue, projectApiLevel));
-                }
-            } else {
-                // no minSdkVersion? display a warning
-                System.out.println(
-                        "WARNING: No minSdkVersion value set. Application will install on all Android versions.");
-            }
-
-        } catch (XPathExpressionException e) {
-            throw new BuildException(e);
-        } catch (FileNotFoundException e) {
-            throw new BuildException(e);
-        }
-    }
-}
diff --git a/tools/anttasks/src/com/android/ant/XPathTask.java b/tools/anttasks/src/com/android/ant/XPathTask.java
deleted file mode 100644
index b9cfb71..0000000
--- a/tools/anttasks/src/com/android/ant/XPathTask.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ant;
-
-import com.android.sdklib.xml.AndroidXPathFactory;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Path;
-import org.xml.sax.InputSource;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Android specific XPath task.
- * The goal is to get the result of an XPath expression on Android XML files. The android namespace
- * (http://schemas.android.com/apk/res/android) must be associated to the "android" prefix.
- */
-public class XPathTask extends Task {
-
-    private Path mManifestFile;
-    private String mProperty;
-    private String mExpression;
-
-    public void setInput(Path manifestFile) {
-        mManifestFile = manifestFile;
-    }
-
-    public void setOutput(String property) {
-        mProperty = property;
-    }
-
-    public void setExpression(String expression) {
-        mExpression = expression;
-    }
-
-    @Override
-    public void execute() throws BuildException {
-        try {
-            if (mManifestFile == null || mManifestFile.list().length == 0) {
-                throw new BuildException("input attribute is missing!");
-            }
-
-            if (mProperty == null) {
-                throw new BuildException("output attribute is missing!");
-            }
-
-            if (mExpression == null) {
-                throw new BuildException("expression attribute is missing!");
-            }
-
-            XPath xpath = AndroidXPathFactory.newXPath();
-
-            String file = mManifestFile.list()[0];
-            String result = xpath.evaluate(mExpression, new InputSource(new FileInputStream(file)));
-
-            getProject().setProperty(mProperty, result);
-        } catch (XPathExpressionException e) {
-            throw new BuildException(e);
-        } catch (FileNotFoundException e) {
-            throw new BuildException(e);
-        }
-    }
-}
diff --git a/tools/apkbuilder/.classpath b/tools/apkbuilder/.classpath
deleted file mode 100644
index f1768fc..0000000
--- a/tools/apkbuilder/.classpath
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/JarUtils"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/apkbuilder/.gitignore b/tools/apkbuilder/.gitignore
deleted file mode 100644
index fe99505..0000000
--- a/tools/apkbuilder/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin
-
diff --git a/tools/apkbuilder/.project b/tools/apkbuilder/.project
deleted file mode 100644
index cc97afc..0000000
--- a/tools/apkbuilder/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ApkBuilder</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/apkbuilder/Android.mk b/tools/apkbuilder/Android.mk
deleted file mode 100644
index bdfe5c8..0000000
--- a/tools/apkbuilder/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-APKBUILDER_LOCAL_DIR := $(call my-dir)
-include $(APKBUILDER_LOCAL_DIR)/etc/Android.mk
-include $(APKBUILDER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/apkbuilder/etc/Android.mk b/tools/apkbuilder/etc/Android.mk
deleted file mode 100644
index d74db17..0000000
--- a/tools/apkbuilder/etc/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := apkbuilder
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/apkbuilder/etc/apkbuilder b/tools/apkbuilder/etc/apkbuilder
deleted file mode 100755
index 3e7e822..0000000
--- a/tools/apkbuilder/etc/apkbuilder
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/sh
-# Copyright 2005-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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=apkbuilder.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
-    # add this in for debugging
-    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
-    shift 1
-else
-    java_debug=
-fi
-
-# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
-if [ `uname` = "Darwin" ]; then
-    os_opts="-XstartOnFirstThread"
-else
-    os_opts=
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
diff --git a/tools/apkbuilder/etc/apkbuilder.bat b/tools/apkbuilder/etc/apkbuilder.bat
deleted file mode 100755
index c4689c6..0000000
--- a/tools/apkbuilder/etc/apkbuilder.bat
+++ /dev/null
@@ -1,43 +0,0 @@
-@echo off
-rem Copyright (C) 2007 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-set jarfile=apkbuilder.jar
-set frameworkdir=
-set libdir=
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=lib\
-    set libdir=lib\
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=..\framework\
-    set libdir=..\lib\
-
-:JarFileOk
-
-set jarpath=%frameworkdir%%jarfile%
-
-call java -Djava.ext.dirs=%frameworkdir% -Djava.library.path=%libdir% -jar %jarpath% %*
diff --git a/tools/apkbuilder/etc/manifest.txt b/tools/apkbuilder/etc/manifest.txt
deleted file mode 100644
index 6aafb16..0000000
--- a/tools/apkbuilder/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.apkbuilder.ApkBuilder
diff --git a/tools/apkbuilder/src/Android.mk b/tools/apkbuilder/src/Android.mk
deleted file mode 100644
index e403ca7..0000000
--- a/tools/apkbuilder/src/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-        androidprefs \
-        jarutils
-
-LOCAL_MODULE := apkbuilder
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/apkbuilder/src/com/android/apkbuilder/ApkBuilder.java b/tools/apkbuilder/src/com/android/apkbuilder/ApkBuilder.java
deleted file mode 100644
index db9f355..0000000
--- a/tools/apkbuilder/src/com/android/apkbuilder/ApkBuilder.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.android.apkbuilder;
-
-import com.android.apkbuilder.internal.ApkBuilderImpl;
-
-import java.io.FileNotFoundException;
-
-
-/**
- * Command line APK builder with signing support.
- */
-public final class ApkBuilder {
-
-    public final static class WrongOptionException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public WrongOptionException(String message) {
-            super(message);
-        }
-    }
-
-    public final static class ApkCreationException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public ApkCreationException(String message) {
-            super(message);
-        }
-
-        public ApkCreationException(Throwable throwable) {
-            super(throwable);
-        }
-
-    }
-
-    /**
-     * Main method. This is meant to be called from the command line through an exec.
-     * <p/>WARNING: this will call {@link System#exit(int)} if anything goes wrong.
-     * @param args command line arguments.
-     */
-    public static void main(String[] args) {
-        try {
-            new ApkBuilderImpl().run(args);
-        } catch (WrongOptionException e) {
-            printUsageAndQuit();
-        } catch (FileNotFoundException e) {
-            printAndExit(e.getMessage());
-        } catch (ApkCreationException e) {
-            printAndExit(e.getMessage());
-        }
-    }
-
-    /**
-     * API entry point similar to the {@link #main(String[])} method.
-     * <p/>Unlike {@link #main(String[])}, this will not call {@link System#exit(int)} and instead
-     * will throw exceptions.
-     * @param args command line arguments.
-     * @throws WrongOptionException if the command line arguments are incorrect.
-     * @throws FileNotFoundException if a required file was not found.
-     * @throws ApkCreationException if an error happened during the creation of the APK.
-     */
-    public static void createApk(String[] args) throws FileNotFoundException, WrongOptionException,
-            ApkCreationException {
-        new ApkBuilderImpl().run(args);
-    }
-
-    private static void printUsageAndQuit() {
-        // 80 cols marker:  01234567890123456789012345678901234567890123456789012345678901234567890123456789
-        System.err.println("A command line tool to package an Android application from various sources.");
-        System.err.println("Usage: apkbuilder <out archive> [-v][-u][-storetype STORE_TYPE] [-z inputzip]");
-        System.err.println("            [-f inputfile] [-rf input-folder] [-rj -input-path]");
-        System.err.println("");
-        System.err.println("    -v      Verbose.");
-        System.err.println("    -u      Creates an unsigned package.");
-        System.err.println("    -storetype Forces the KeyStore type. If ommited the default is used.");
-        System.err.println("");
-        System.err.println("    -z      Followed by the path to a zip archive.");
-        System.err.println("            Adds the content of the application package.");
-        System.err.println("");
-        System.err.println("    -f      Followed by the path to a file.");
-        System.err.println("            Adds the file to the application package.");
-        System.err.println("");
-        System.err.println("    -rf     Followed by the path to a source folder.");
-        System.err.println("            Adds the java resources found in that folder to the application");
-        System.err.println("            package, while keeping their path relative to the source folder.");
-        System.err.println("");
-        System.err.println("    -rj     Followed by the path to a jar file or a folder containing");
-        System.err.println("            jar files.");
-        System.err.println("            Adds the java resources found in the jar file(s) to the application");
-        System.err.println("            package.");
-        System.err.println("");
-        System.err.println("    -nf     Followed by the root folder containing native libraries to");
-        System.err.println("            include in the application package.");
-
-        System.exit(1);
-    }
-
-    private static void printAndExit(String... messages) {
-        for (String message : messages) {
-            System.err.println(message);
-        }
-        System.exit(1);
-    }
-}
diff --git a/tools/apkbuilder/src/com/android/apkbuilder/internal/ApkBuilderImpl.java b/tools/apkbuilder/src/com/android/apkbuilder/internal/ApkBuilderImpl.java
deleted file mode 100644
index 9d21c22..0000000
--- a/tools/apkbuilder/src/com/android/apkbuilder/internal/ApkBuilderImpl.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * 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.android.apkbuilder.internal;
-
-import com.android.apkbuilder.ApkBuilder.WrongOptionException;
-import com.android.apkbuilder.ApkBuilder.ApkCreationException;
-import com.android.jarutils.DebugKeyProvider;
-import com.android.jarutils.JavaResourceFilter;
-import com.android.jarutils.SignedJarBuilder;
-import com.android.jarutils.DebugKeyProvider.KeytoolException;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.regex.Pattern;
-
-/**
- * Command line APK builder with signing support.
- */
-public final class ApkBuilderImpl {
-
-    private final static Pattern PATTERN_JAR_EXT = Pattern.compile("^.+\\.jar$",
-            Pattern.CASE_INSENSITIVE);
-    private final static Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$",
-            Pattern.CASE_INSENSITIVE);
-
-    private final static String NATIVE_LIB_ROOT = "lib/";
-
-    /**
-     * A File to be added to the APK archive.
-     * <p/>This includes the {@link File} representing the file and its path in the archive.
-     */
-    public final static class ApkFile {
-        String archivePath;
-        File file;
-
-        ApkFile(File file, String path) {
-            this.file = file;
-            this.archivePath = path;
-        }
-    }
-
-    private JavaResourceFilter mResourceFilter = new JavaResourceFilter();
-    private boolean mVerbose = false;
-    private boolean mSignedPackage = true;
-    /** the optional type of the debug keystore. If <code>null</code>, the default */
-    private String mStoreType = null;
-
-    public void setVerbose(boolean verbose) {
-        mVerbose = verbose;
-    }
-
-    public void setSignedPackage(boolean signedPackage) {
-        mSignedPackage = signedPackage;
-    }
-
-    public void run(String[] args) throws WrongOptionException, FileNotFoundException,
-            ApkCreationException {
-        if (args.length < 1) {
-            throw new WrongOptionException("No options specified");
-        }
-
-        // read the first args that should be a file path
-        File outFile = getOutFile(args[0]);
-
-        ArrayList<FileInputStream> zipArchives = new ArrayList<FileInputStream>();
-        ArrayList<File> archiveFiles = new ArrayList<File>();
-        ArrayList<ApkFile> javaResources = new ArrayList<ApkFile>();
-        ArrayList<FileInputStream> resourcesJars = new ArrayList<FileInputStream>();
-        ArrayList<ApkFile> nativeLibraries = new ArrayList<ApkFile>();
-
-        int index = 1;
-        do {
-            String argument = args[index++];
-
-            if ("-v".equals(argument)) {
-                mVerbose = true;
-            } else if ("-u".equals(argument)) {
-                mSignedPackage = false;
-            } else if ("-z".equals(argument)) {
-                // quick check on the next argument.
-                if (index == args.length)  {
-                    throw new WrongOptionException("Missing value for -z");
-                }
-
-                try {
-                    FileInputStream input = new FileInputStream(args[index++]);
-                    zipArchives.add(input);
-                } catch (FileNotFoundException e) {
-                    throw new ApkCreationException("-z file is not found");
-                }
-            } else if ("-f". equals(argument)) {
-                // quick check on the next argument.
-                if (index == args.length) {
-                    throw new WrongOptionException("Missing value for -f");
-                }
-
-                archiveFiles.add(getInputFile(args[index++]));
-            } else if ("-rf". equals(argument)) {
-                // quick check on the next argument.
-                if (index == args.length) {
-                    throw new WrongOptionException("Missing value for -rf");
-                }
-
-                processSourceFolderForResource(args[index++], javaResources);
-            } else if ("-rj". equals(argument)) {
-                // quick check on the next argument.
-                if (index == args.length) {
-                    throw new WrongOptionException("Missing value for -rj");
-                }
-
-                File f = new File(args[index]);
-                if (f.isDirectory()) {
-                    processJarFolder(args[index++], resourcesJars);
-                } else if (f.isFile()) {
-                    processJarFile(args[index++], resourcesJars);
-                }
-            } else if ("-nf".equals(argument)) {
-                // quick check on the next argument.
-                if (index == args.length) {
-                    throw new WrongOptionException("Missing value for -nf");
-                }
-
-                String parameter = args[index++];
-                File f = new File(parameter);
-
-                // compute the offset to get the relative path
-                int offset = parameter.length();
-                if (parameter.endsWith(File.separator) == false) {
-                    offset++;
-                }
-
-                processNativeFolder(offset, f, nativeLibraries);
-            } else if ("-storetype".equals(argument)) {
-                // quick check on the next argument.
-                if (index == args.length) {
-                    throw new WrongOptionException("Missing value for -storetype");
-                }
-
-                mStoreType  = args[index++];
-            } else {
-                throw new WrongOptionException("Unknown argument: " + argument);
-            }
-        } while (index < args.length);
-
-        createPackage(outFile, zipArchives, archiveFiles, javaResources, resourcesJars,
-                nativeLibraries);
-    }
-
-
-    private File getOutFile(String filepath) throws ApkCreationException {
-        File f = new File(filepath);
-
-        if (f.isDirectory()) {
-            throw new ApkCreationException(filepath + " is a directory!");
-        }
-
-        if (f.exists()) { // will be a file in this case.
-            if (f.canWrite() == false) {
-                throw new ApkCreationException("Cannot write " + filepath);
-            }
-        } else {
-            try {
-                if (f.createNewFile() == false) {
-                    throw new ApkCreationException("Failed to create " + filepath);
-                }
-            } catch (IOException e) {
-                throw new ApkCreationException(
-                        "Failed to create '" + filepath + "' : " + e.getMessage());
-            }
-        }
-
-        return f;
-    }
-
-    public static File getInputFile(String filepath) throws ApkCreationException {
-        File f = new File(filepath);
-
-        if (f.isDirectory()) {
-            throw new ApkCreationException(filepath + " is a directory!");
-        }
-
-        if (f.exists()) {
-            if (f.canRead() == false) {
-                throw new ApkCreationException("Cannot read " + filepath);
-            }
-        } else {
-            throw new ApkCreationException(filepath + " does not exists!");
-        }
-
-        return f;
-    }
-
-    /**
-     * Processes a source folder and adds its java resources to a given list of {@link ApkFile}.
-     * @param folderPath the path to the source folder.
-     * @param javaResources the list of {@link ApkFile} to fill.
-     * @throws ApkCreationException
-     */
-    public static void processSourceFolderForResource(String folderPath,
-            ArrayList<ApkFile> javaResources) throws ApkCreationException {
-
-        File folder = new File(folderPath);
-
-        if (folder.isDirectory()) {
-            // file is a directory, process its content.
-            File[] files = folder.listFiles();
-            for (File file : files) {
-                processFileForResource(file, null, javaResources);
-            }
-        } else {
-            // not a directory? output error and quit.
-            if (folder.exists()) {
-                throw new ApkCreationException(folderPath + " is not a folder!");
-            } else {
-                throw new ApkCreationException(folderPath + " does not exist!");
-            }
-        }
-    }
-
-    public static void processJarFolder(String parameter, Collection<FileInputStream> resourcesJars)
-            throws FileNotFoundException {
-        File f = new File(parameter);
-        if (f.isDirectory()) {
-            String[] files = f.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
-                    return PATTERN_JAR_EXT.matcher(name).matches();
-                }
-            });
-
-            for (String file : files) {
-                String path = f.getAbsolutePath() + File.separator + file;
-                processJarFile(path, resourcesJars);
-            }
-        } else {
-            processJarFile(parameter, resourcesJars);
-        }
-    }
-
-    public static void processJarFile(String jarfilePath, Collection<FileInputStream> resourcesJars)
-            throws FileNotFoundException {
-        FileInputStream input = new FileInputStream(jarfilePath);
-        resourcesJars.add(input);
-    }
-
-    /**
-     * Processes a {@link File} that could be a {@link ApkFile}, or a folder containing
-     * java resources.
-     * @param file the {@link File} to process.
-     * @param path the relative path of this file to the source folder. Can be <code>null</code> to
-     * identify a root file.
-     * @param javaResources the Collection of {@link ApkFile} object to fill.
-     */
-    private static void processFileForResource(File file, String path,
-            Collection<ApkFile> javaResources) {
-        if (file.isDirectory()) {
-            // a directory? we check it
-            if (JavaResourceFilter.checkFolderForPackaging(file.getName())) {
-                // if it's valid, we append its name to the current path.
-                if (path == null) {
-                    path = file.getName();
-                } else {
-                    path = path + "/" + file.getName();
-                }
-
-                // and process its content.
-                File[] files = file.listFiles();
-                for (File contentFile : files) {
-                    processFileForResource(contentFile, path, javaResources);
-                }
-            }
-        } else {
-            // a file? we check it
-            if (JavaResourceFilter.checkFileForPackaging(file.getName())) {
-                // we append its name to the current path
-                if (path == null) {
-                    path = file.getName();
-                } else {
-                    path = path + "/" + file.getName();
-                }
-
-                // and add it to the list.
-                javaResources.add(new ApkFile(file, path));
-            }
-        }
-    }
-
-    /**
-     * Process a {@link File} for native library inclusion.
-     * @param offset the length of the root folder (used to compute relative path)
-     * @param f the {@link File} to process
-     * @param nativeLibraries the collection to add native libraries to.
-     */
-    public static void processNativeFolder(int offset, File f,
-            Collection<ApkFile> nativeLibraries) {
-        if (f.isDirectory()) {
-            File[] children = f.listFiles();
-
-            if (children != null) {
-                for (File child : children) {
-                    processNativeFolder(offset, child, nativeLibraries);
-                }
-            }
-        } else if (f.isFile()) {
-            if (PATTERN_NATIVELIB_EXT.matcher(f.getName()).matches()) {
-                String path = NATIVE_LIB_ROOT +
-                        f.getAbsolutePath().substring(offset).replace('\\', '/');
-
-                nativeLibraries.add(new ApkFile(f, path));
-            }
-        }
-    }
-
-    /**
-     * Creates the application package
-     * @param outFile the package file to create
-     * @param zipArchives the list of zip archive
-     * @param files the list of files to include in the archive
-     * @param javaResources the list of java resources from the source folders.
-     * @param resourcesJars the list of jar files from which to take java resources
-     * @throws ApkCreationException
-     */
-    public void createPackage(File outFile, Iterable<? extends FileInputStream> zipArchives,
-            Iterable<? extends File> files, Iterable<? extends ApkFile> javaResources,
-            Iterable<? extends FileInputStream> resourcesJars,
-            Iterable<? extends ApkFile> nativeLibraries) throws ApkCreationException {
-
-        // get the debug key
-        try {
-            SignedJarBuilder builder;
-
-            if (mSignedPackage) {
-                System.err.println(String.format("Using keystore: %s",
-                        DebugKeyProvider.getDefaultKeyStoreOsPath()));
-
-
-                DebugKeyProvider keyProvider = new DebugKeyProvider(
-                        null /* osKeyPath: use default */,
-                        mStoreType, null /* IKeyGenOutput */);
-                PrivateKey key = keyProvider.getDebugKey();
-                X509Certificate certificate = (X509Certificate)keyProvider.getCertificate();
-
-                if (key == null) {
-                    throw new ApkCreationException("Unable to get debug signature key");
-                }
-
-                // compare the certificate expiration date
-                if (certificate != null && certificate.getNotAfter().compareTo(new Date()) < 0) {
-                    // TODO, regenerate a new one.
-                    throw new ApkCreationException("Debug Certificate expired on " +
-                            DateFormat.getInstance().format(certificate.getNotAfter()));
-                }
-
-                builder = new SignedJarBuilder(
-                        new FileOutputStream(outFile.getAbsolutePath(), false /* append */), key,
-                        certificate);
-            } else {
-                builder = new SignedJarBuilder(
-                        new FileOutputStream(outFile.getAbsolutePath(), false /* append */),
-                        null /* key */, null /* certificate */);
-            }
-
-            // add the archives
-            for (FileInputStream input : zipArchives) {
-                builder.writeZip(input, null /* filter */);
-            }
-
-            // add the single files
-            for (File input : files) {
-                // always put the file at the root of the archive in this case
-                builder.writeFile(input, input.getName());
-                if (mVerbose) {
-                    System.err.println(String.format("%1$s => %2$s", input.getAbsolutePath(),
-                            input.getName()));
-                }
-            }
-
-            // add the java resource from the source folders.
-            for (ApkFile resource : javaResources) {
-                builder.writeFile(resource.file, resource.archivePath);
-                if (mVerbose) {
-                    System.err.println(String.format("%1$s => %2$s",
-                            resource.file.getAbsolutePath(), resource.archivePath));
-                }
-            }
-
-            // add the java resource from jar files.
-            for (FileInputStream input : resourcesJars) {
-                builder.writeZip(input, mResourceFilter);
-            }
-
-            // add the native files
-            for (ApkFile file : nativeLibraries) {
-                builder.writeFile(file.file, file.archivePath);
-                if (mVerbose) {
-                    System.err.println(String.format("%1$s => %2$s", file.file.getAbsolutePath(),
-                            file.archivePath));
-                }
-            }
-
-            // close and sign the application package.
-            builder.close();
-        } catch (KeytoolException e) {
-            if (e.getJavaHome() == null) {
-                throw new ApkCreationException(e.getMessage() +
-                        "\nJAVA_HOME seems undefined, setting it will help locating keytool automatically\n" +
-                        "You can also manually execute the following command\n:" +
-                        e.getCommandLine());
-            } else {
-                throw new ApkCreationException(e.getMessage() +
-                        "\nJAVA_HOME is set to: " + e.getJavaHome() +
-                        "\nUpdate it if necessary, or manually execute the following command:\n" +
-                        e.getCommandLine());
-            }
-        } catch (AndroidLocationException e) {
-            throw new ApkCreationException(e);
-        } catch (Exception e) {
-            throw new ApkCreationException(e);
-        }
-    }
-}
diff --git a/tools/archquery/.classpath b/tools/archquery/.classpath
deleted file mode 100644
index fb50116..0000000
--- a/tools/archquery/.classpath
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/archquery/.gitignore b/tools/archquery/.gitignore
deleted file mode 100644
index ba077a4..0000000
--- a/tools/archquery/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/tools/archquery/.project b/tools/archquery/.project
deleted file mode 100644
index 9886091..0000000
--- a/tools/archquery/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>archquery</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/archquery/Android.mk b/tools/archquery/Android.mk
deleted file mode 100644
index 53cad46..0000000
--- a/tools/archquery/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-ARCHQUERY_LOCAL_DIR := $(call my-dir)
-include $(ARCHQUERY_LOCAL_DIR)/src/Android.mk
diff --git a/tools/archquery/etc/manifest.txt b/tools/archquery/etc/manifest.txt
deleted file mode 100644
index a362e88..0000000
--- a/tools/archquery/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.archquery.Main
diff --git a/tools/archquery/src/Android.mk b/tools/archquery/src/Android.mk
deleted file mode 100644
index 980f002..0000000
--- a/tools/archquery/src/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-
-LOCAL_MODULE := archquery
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/archquery/src/com/android/archquery/Main.java b/tools/archquery/src/com/android/archquery/Main.java
deleted file mode 100644
index c76cca1..0000000
--- a/tools/archquery/src/com/android/archquery/Main.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.archquery;
-
-/**
- * Java command line tool to return the CPU architecture of the host java VM.
- *
- * The goal is to be able to launch SWT based applications (DDMS, Traceview, Android) on any
- * type of OS.
- *
- * Because a 64 bit OS can run a 32 bit Virtual Machine, we need to query the VM itself to know
- * whether it's 32 or 64 bit to detect which swt.jar it should use (it contains native libraries).
- * Simply querying the OS is not enough.
- *
- * The other problem is that once a VM is launched it is impossible to change its classpath to
- * point the VM to the correct version of swt.jar.
- *
- * The solution is this small command line tool, running in the VM, and returning the value of
- * the 'os.arch' property. Based on the returned value, the script launching the SWT based
- * applications will configure the Java VM with the path to the correct swt.jar
- *
- * Because different VMs return different values for 32 and 64 bit version of x86 CPUs, the program
- * handles all the possible values and normalize the returned value.
- *
- * At this time, the normalized values are:
- * x86:    32 bit x86
- * x86_64: 64 bit x86
- * ppc:    PowerPC (WARNING: the SDK doesn't actually support this architecture).
- *
- *
- */
-public final class Main {
-    public static void main(String[] args) {
-
-        for (String arg : args) {
-            System.out.println(String.format("%1$s: %2$s", arg, System.getProperty(arg)));
-        }
-
-        if (args.length == 0) {
-            // Values listed from http://lopica.sourceforge.net/os.html
-            String arch = System.getProperty("os.arch");
-
-            if (arch.equalsIgnoreCase("x86_64") || arch.equalsIgnoreCase("amd64")) {
-                System.out.print("x86_64");
-
-            } else if (arch.equalsIgnoreCase("x86")
-                    || arch.equalsIgnoreCase("i386")
-                    || arch.equalsIgnoreCase("i686")) {
-                System.out.print("x86");
-
-            } else if (arch.equalsIgnoreCase("ppc") || arch.equalsIgnoreCase("PowerPC")) {
-                System.out.print("ppc");
-            } else {
-                System.out.print(arch);
-            }
-        }
-    }
-}
diff --git a/tools/ddms/.gitignore b/tools/ddms/.gitignore
deleted file mode 100644
index 6d833a0..0000000
--- a/tools/ddms/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-app/bin
-libs/ddmlib/bin
-libs/ddmuilib/bin
-
diff --git a/tools/ddms/Android.mk b/tools/ddms/Android.mk
deleted file mode 100644
index 82c248e..0000000
--- a/tools/ddms/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-DDMS_LOCAL_DIR := $(call my-dir)
-include $(DDMS_LOCAL_DIR)/libs/Android.mk
-include $(DDMS_LOCAL_DIR)/app/Android.mk
diff --git a/tools/ddms/MODULE_LICENSE_APACHE2 b/tools/ddms/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/ddms/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/ddms/app/.classpath b/tools/ddms/app/.classpath
deleted file mode 100644
index 1040688..0000000
--- a/tools/ddms/app/.classpath
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="Makefile|resources/" kind="src" path="src"/>
-	<classpathentry kind="src" path="src/resources"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmuilib"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/SdkStatsService"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/ddms/app/.project b/tools/ddms/app/.project
deleted file mode 100644
index ffb19d7..0000000
--- a/tools/ddms/app/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ddms</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/ddms/app/Android.mk b/tools/ddms/app/Android.mk
deleted file mode 100644
index 3857706..0000000
--- a/tools/ddms/app/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-DDMSAPP_LOCAL_DIR := $(call my-dir)
-include $(DDMSAPP_LOCAL_DIR)/etc/Android.mk
-include $(DDMSAPP_LOCAL_DIR)/src/Android.mk
diff --git a/tools/ddms/app/README b/tools/ddms/app/README
deleted file mode 100644
index cc55ddd..0000000
--- a/tools/ddms/app/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Using the Eclipse projects for ddms.
-
-ddms requires SWT to compile.
-
-SWT is available in the depot under //device/prebuild/<platform>/swt
-
-Because the build path cannot contain relative path that are not inside the project directory,
-the .classpath file references a user library called ANDROID_SWT.
-
-In order to compile the project, make a user library called ANDROID_SWT containing the jar
-available at //device/prebuild/<platform>/swt.
\ No newline at end of file
diff --git a/tools/ddms/app/etc/Android.mk b/tools/ddms/app/etc/Android.mk
deleted file mode 100644
index 9d69971..0000000
--- a/tools/ddms/app/etc/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := ddms
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/ddms/app/etc/ddms b/tools/ddms/app/etc/ddms
deleted file mode 100755
index 1367aeb..0000000
--- a/tools/ddms/app/etc/ddms
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/bin/bash
-# Copyright 2005-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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=ddms.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
-    # add this in for debugging
-    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
-    shift 1
-else
-    java_debug=
-fi
-
-javaCmd="java"
-
-# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
-if [ `uname` = "Darwin" ]; then
-    os_opts="-XstartOnFirstThread"
-else
-    os_opts=
-fi
-
-if [ `uname` = "Linux" ]; then
-    export GDK_NATIVE_WINDOWS=true
-fi
-
-jarpath="$frameworkdir/$jarfile"
-
-# Figure out the path to the swt.jar for the current architecture.
-# if ANDROID_SWT is defined, then just use this.
-# else, if running in the Android source tree, then look for the correct swt folder in prebuilt
-# else, look for the correct swt folder in the SDK under tools/lib/
-swtpath=""
-if [ -n "$ANDROID_SWT" ]; then
-    swtpath="$ANDROID_SWT"
-else
-    vmarch=`${javaCmd} -jar "${frameworkdir}"/archquery.jar`
-    if [ -n "$ANDROID_BUILD_TOP" ]; then
-        osname=`uname -s | tr A-Z a-z`
-        swtpath="${ANDROID_BUILD_TOP}/prebuilt/${osname}-${vmarch}/swt"
-    else
-        swtpath="${frameworkdir}/${vmarch}"
-    fi
-fi
-
-# Combine the swtpath and the framework dir path.
-if [ -d "$swtpath" ]; then
-    frameworkdir="${swtpath}:${frameworkdir}"
-else
-    echo "SWT folder '${swtpath}' does not exist."
-    echo "Please export ANDROID_SWT to point to the folder containing swt.jar for your platform."
-    exit 1
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec "$javaCmd" -Xmx256M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Dcom.android.ddms.bindir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/ddms/app/etc/ddms.bat b/tools/ddms/app/etc/ddms.bat
deleted file mode 100755
index ffe536d..0000000
--- a/tools/ddms/app/etc/ddms.bat
+++ /dev/null
@@ -1,64 +0,0 @@
-@echo off
-rem Copyright (C) 2007 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-set jarfile=ddms.jar
-set frameworkdir=
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=lib\
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=..\framework\
-
-:JarFileOk
-
-if debug NEQ "%1" goto NoDebug
-    set java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
-    shift 1
-:NoDebug
-
-set jarpath=%frameworkdir%%jarfile%
-
-if not defined ANDROID_SWT goto QueryArch
-    set swt_path=%ANDROID_SWT%
-    goto SwtDone
-
-:QueryArch
-
-    for /f %%a in ('java -jar %frameworkdir%archquery.jar') do set swt_path=%frameworkdir%%%a
-
-:SwtDone
-
-if exist %swt_path% goto SetPath
-    echo SWT folder '%swt_path%' does not exist.
-    echo Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.
-    exit /B
-
-:SetPath
-set javaextdirs=%swt_path%;%frameworkdir%
-
-call java %java_debug% -Djava.ext.dirs=%javaextdirs% -Dcom.android.ddms.bindir= -jar %jarpath% %*
-
diff --git a/tools/ddms/app/etc/manifest.txt b/tools/ddms/app/etc/manifest.txt
deleted file mode 100644
index 84c8acd..0000000
--- a/tools/ddms/app/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.ddms.Main
diff --git a/tools/ddms/app/src/Android.mk b/tools/ddms/app/src/Android.mk
deleted file mode 100644
index c62b678..0000000
--- a/tools/ddms/app/src/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	androidprefs \
-	sdkstats \
-	ddmlib \
-	ddmuilib \
-	swt \
-	org.eclipse.jface_3.4.2.M20090107-0800 \
-	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
-	org.eclipse.core.commands_3.4.0.I20080509-2000
-LOCAL_MODULE := ddms
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/ddms/app/src/com/android/ddms/AboutDialog.java b/tools/ddms/app/src/com/android/ddms/AboutDialog.java
deleted file mode 100644
index e946aee..0000000
--- a/tools/ddms/app/src/com/android/ddms/AboutDialog.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/* //device/tools/ddms/src/com/android/ddms/AboutDialog.java
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.ddms;
-
-import com.android.ddmlib.Log;
-import com.android.ddmuilib.ImageHelper;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.InputStream;
-
-/**
- * Our "about" box.
- */
-public class AboutDialog extends Dialog {
-
-    private Image logoImage;
-
-    /**
-     * Create with default style.
-     */
-    public AboutDialog(Shell parent) {
-        this(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-    }
-
-    /**
-     * Create with app-defined style.
-     */
-    public AboutDialog(Shell parent, int style) {
-        super(parent, style);
-    }
-
-    /**
-     * Prepare and display the dialog.
-     */
-    public void open() {
-        Shell parent = getParent();
-        Shell shell = new Shell(parent, getStyle());
-        shell.setText("About...");
-
-        logoImage = loadImage(shell, "ddms-logo.png"); // $NON-NLS-1$
-        createContents(shell);
-        shell.pack();
-
-        shell.open();
-        Display display = parent.getDisplay();
-        while (!shell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-
-        logoImage.dispose();
-    }
-
-    /*
-     * Load an image file from a resource.
-     *
-     * This depends on Display, so I'm not sure what the rules are for
-     * loading once and caching in a static class field.
-     */
-    private Image loadImage(Shell shell, String fileName) {
-        InputStream imageStream;
-        String pathName = "/images/" + fileName;  // $NON-NLS-1$
-
-        imageStream = this.getClass().getResourceAsStream(pathName);
-        if (imageStream == null) {
-            //throw new NullPointerException("couldn't find " + pathName);
-            Log.w("ddms", "Couldn't load " + pathName);
-            Display display = shell.getDisplay();
-            return ImageHelper.createPlaceHolderArt(display, 100, 50,
-                    display.getSystemColor(SWT.COLOR_BLUE));
-        }
-
-        Image img = new Image(shell.getDisplay(), imageStream);
-        if (img == null)
-            throw new NullPointerException("couldn't load " + pathName);
-        return img;
-    }
-
-    /*
-     * Create the about box contents.
-     */
-    private void createContents(final Shell shell) {
-        GridLayout layout;
-        GridData data;
-        Label label;
-
-        shell.setLayout(new GridLayout(2, false));
-
-        // Fancy logo
-        Label logo = new Label(shell, SWT.BORDER);
-        logo.setImage(logoImage);
-
-        // Text Area
-        Composite textArea = new Composite(shell, SWT.NONE);
-        layout = new GridLayout(1, true);
-        textArea.setLayout(layout);
-
-        // Text lines
-        label = new Label(textArea, SWT.NONE);
-        if (Main.sRevision != null && Main.sRevision.length() > 0) {
-            label.setText("Dalvik Debug Monitor Revision " + Main.sRevision);
-        } else {
-            label.setText("Dalvik Debug Monitor");
-        }
-        label = new Label(textArea, SWT.NONE);
-        label.setText("Copyright 2007, The Android Open Source Project");
-        label = new Label(textArea, SWT.NONE);
-        label.setText("All Rights Reserved.");
-
-        // blank spot in grid
-        label = new Label(shell, SWT.NONE);
-
-        // "OK" button
-        Button ok = new Button(shell, SWT.PUSH);
-        ok.setText("OK");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_END);
-        data.widthHint = 80;
-        ok.setLayoutData(data);
-        ok.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                shell.close();
-            }
-        });
-
-        shell.pack();
-
-        shell.setDefaultButton(ok);
-    }
-}
diff --git a/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java b/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java
deleted file mode 100644
index 76a86b7..0000000
--- a/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.android.ddms;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * DDMS implementation of the IDebugPortProvider interface.
- * This class handles saving/loading the list of static debug port from
- * the preference store and provides the port number to the Device Monitor.
- */
-public class DebugPortProvider implements IDebugPortProvider {
-
-    private static DebugPortProvider sThis  = new DebugPortProvider();
-
-    /** Preference name for the static port list. */
-    public static final String PREFS_STATIC_PORT_LIST = "android.staticPortList"; //$NON-NLS-1$
-
-    /**
-     * Mapping device serial numbers to maps. The embedded maps are mapping application names to
-     * debugger ports.
-     */
-    private Map<String, Map<String, Integer>> mMap;
-
-    public static DebugPortProvider getInstance() {
-        return sThis;
-    }
-
-    private DebugPortProvider() {
-        computePortList();
-    }
-
-    /**
-         * Returns a static debug port for the specified application running on the
-         * specified {@link IDevice}.
-         * @param device The device the application is running on.
-         * @param appName The application name, as defined in the
-         *  AndroidManifest.xml package attribute.
-         * @return The static debug port or {@link #NO_STATIC_PORT} if there is none setup.
-     *
-     * @see IDebugPortProvider#getPort(IDevice, String)
-     */
-    public int getPort(IDevice device, String appName) {
-        if (mMap != null) {
-            Map<String, Integer> deviceMap = mMap.get(device.getSerialNumber());
-            if (deviceMap != null) {
-                Integer i = deviceMap.get(appName);
-                if (i != null) {
-                    return i.intValue();
-                }
-            }
-        }
-        return IDebugPortProvider.NO_STATIC_PORT;
-    }
-
-    /**
-     * Returns the map of Static debugger ports. The map links device serial numbers to
-     * a map linking application name to debugger ports.
-     */
-    public Map<String, Map<String, Integer>> getPortList() {
-        return mMap;
-    }
-
-    /**
-     * Create the map member from the values contained in the Preference Store.
-     */
-    private void computePortList() {
-        mMap = new HashMap<String, Map<String, Integer>>();
-
-        // get the prefs store
-        IPreferenceStore store = PrefsDialog.getStore();
-        String value = store.getString(PREFS_STATIC_PORT_LIST);
-
-        if (value != null && value.length() > 0) {
-            // format is
-            // port1|port2|port3|...
-            // where port# is
-            // appPackageName:appPortNumber:device-serial-number
-            String[] portSegments = value.split("\\|");  //$NON-NLS-1$
-            for (String seg : portSegments) {
-                String[] entry = seg.split(":");  //$NON-NLS-1$
-
-                // backward compatibility support. if we have only 2 entry, we default
-                // to the first emulator.
-                String deviceName = null;
-                if (entry.length == 3) {
-                    deviceName = entry[2];
-                } else {
-                    deviceName = IDevice.FIRST_EMULATOR_SN;
-                }
-
-                // get the device map
-                Map<String, Integer> deviceMap = mMap.get(deviceName);
-                if (deviceMap == null) {
-                    deviceMap = new HashMap<String, Integer>();
-                    mMap.put(deviceName, deviceMap);
-                }
-
-                deviceMap.put(entry[0], Integer.valueOf(entry[1]));
-            }
-        }
-    }
-
-    /**
-     * Sets new [device, app, port] values.
-     * The values are also sync'ed in the preference store.
-     * @param map The map containing the new values.
-     */
-    public void setPortList(Map<String, Map<String,Integer>> map) {
-        // update the member map.
-        mMap.clear();
-        mMap.putAll(map);
-
-        // create the value to store in the preference store.
-        // see format definition in getPortList
-        StringBuilder sb = new StringBuilder();
-
-        Set<String> deviceKeys = map.keySet();
-        for (String deviceKey : deviceKeys) {
-            Map<String, Integer> deviceMap = map.get(deviceKey);
-            if (deviceMap != null) {
-                Set<String> appKeys = deviceMap.keySet();
-
-                for (String appKey : appKeys) {
-                    Integer port = deviceMap.get(appKey);
-                    if (port != null) {
-                        sb.append(appKey).append(':').append(port.intValue()).append(':').
-                            append(deviceKey).append('|');
-                    }
-                }
-            }
-        }
-
-        String value = sb.toString();
-
-        // get the prefs store.
-        IPreferenceStore store = PrefsDialog.getStore();
-
-        // and give it the new value.
-        store.setValue(PREFS_STATIC_PORT_LIST, value);
-    }
-}
diff --git a/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java b/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
deleted file mode 100644
index 6145733..0000000
--- a/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/* //device/tools/ddms/src/com/android/ddms/DeviceCommandDialog.java
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.ddms;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.Log;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.BufferedOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-
-/**
- * Execute a command on an ADB-attached device and save the output.
- *
- * There are several ways to do this.  One is to run a single command
- * and show the output.  Another is to have several possible commands and
- * let the user click a button next to the one (or ones) they want.  This
- * currently uses the simple 1:1 form.
- */
-public class DeviceCommandDialog extends Dialog {
-
-    public static final int DEVICE_STATE = 0;
-    public static final int APP_STATE = 1;
-    public static final int RADIO_STATE = 2;
-    public static final int LOGCAT = 3;
-
-    private String mCommand;
-    private String mFileName;
-
-    private Label mStatusLabel;
-    private Button mCancelDone;
-    private Button mSave;
-    private Text mText;
-    private Font mFont = null;
-    private boolean mCancel;
-    private boolean mFinished;
-
-
-    /**
-     * Create with default style.
-     */
-    public DeviceCommandDialog(String command, String fileName, Shell parent) {
-        // don't want a close button, but it seems hard to get rid of on GTK
-        // keep it on all platforms for consistency
-        this(command, fileName, parent,
-            SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE);
-    }
-
-    /**
-     * Create with app-defined style.
-     */
-    public DeviceCommandDialog(String command, String fileName, Shell parent,
-        int style)
-    {
-        super(parent, style);
-        mCommand = command;
-        mFileName = fileName;
-    }
-
-    /**
-     * Prepare and display the dialog.
-     * @param currentDevice
-     */
-    public void open(IDevice currentDevice) {
-        Shell parent = getParent();
-        Shell shell = new Shell(parent, getStyle());
-        shell.setText("Remote Command");
-
-        mFinished = false;
-        mFont = findFont(shell.getDisplay());
-        createContents(shell);
-
-        // Getting weird layout behavior under Linux when Text is added --
-        // looks like text widget has min width of 400 when FILL_HORIZONTAL
-        // is used, and layout gets tweaked to force this.  (Might be even
-        // more with the scroll bars in place -- it wigged out when the
-        // file save dialog was invoked.)
-        shell.setMinimumSize(500, 200);
-        shell.setSize(800, 600);
-        shell.open();
-
-        executeCommand(shell, currentDevice);
-
-        Display display = parent.getDisplay();
-        while (!shell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-
-        if (mFont != null)
-            mFont.dispose();
-    }
-
-    /*
-     * Create a text widget to show the output and some buttons to
-     * manage things.
-     */
-    private void createContents(final Shell shell) {
-        GridData data;
-
-        shell.setLayout(new GridLayout(2, true));
-
-        shell.addListener(SWT.Close, new Listener() {
-            public void handleEvent(Event event) {
-                if (!mFinished) {
-                    Log.d("ddms", "NOT closing - cancelling command");
-                    event.doit = false;
-                    mCancel = true;
-                }
-            }
-        });
-
-        mStatusLabel = new Label(shell, SWT.NONE);
-        mStatusLabel.setText("Executing '" + shortCommandString() + "'");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-        data.horizontalSpan = 2;
-        mStatusLabel.setLayoutData(data);
-
-        mText = new Text(shell, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-        mText.setEditable(false);
-        mText.setFont(mFont);
-        data = new GridData(GridData.FILL_BOTH);
-        data.horizontalSpan = 2;
-        mText.setLayoutData(data);
-
-        // "save" button
-        mSave = new Button(shell, SWT.PUSH);
-        mSave.setText("Save");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.widthHint = 80;
-        mSave.setLayoutData(data);
-        mSave.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                saveText(shell);
-            }
-        });
-        mSave.setEnabled(false);
-
-        // "cancel/done" button
-        mCancelDone = new Button(shell, SWT.PUSH);
-        mCancelDone.setText("Cancel");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.widthHint = 80;
-        mCancelDone.setLayoutData(data);
-        mCancelDone.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (!mFinished)
-                    mCancel = true;
-                else
-                    shell.close();
-            }
-        });
-    }
-
-    /*
-     * Figure out what font to use.
-     *
-     * Returns "null" if we can't figure it out, which SWT understands to
-     * mean "use default system font".
-     */
-    private Font findFont(Display display) {
-        String fontStr = PrefsDialog.getStore().getString("textOutputFont");
-        if (fontStr != null) {
-            FontData fdat = new FontData(fontStr);
-            if (fdat != null)
-                return new Font(display, fdat);
-        }
-        return null;
-    }
-
-
-    /*
-     * Callback class for command execution.
-     */
-    class Gatherer extends Thread implements IShellOutputReceiver {
-        public static final int RESULT_UNKNOWN = 0;
-        public static final int RESULT_SUCCESS = 1;
-        public static final int RESULT_FAILURE = 2;
-        public static final int RESULT_CANCELLED = 3;
-
-        private Shell mShell;
-        private String mCommand;
-        private Text mText;
-        private int mResult;
-        private IDevice mDevice;
-
-        /**
-         * Constructor; pass in the text widget that will receive the output.
-         * @param device
-         */
-        public Gatherer(Shell shell, IDevice device, String command, Text text) {
-            mShell = shell;
-            mDevice = device;
-            mCommand = command;
-            mText = text;
-            mResult = RESULT_UNKNOWN;
-
-            // this is in outer class
-            mCancel = false;
-        }
-
-        /**
-         * Thread entry point.
-         */
-        @Override
-        public void run() {
-
-            if (mDevice == null) {
-                Log.w("ddms", "Cannot execute command: no device selected.");
-                mResult = RESULT_FAILURE;
-            } else {
-                try {
-                    mDevice.executeShellCommand(mCommand, this);
-                    if (mCancel)
-                        mResult = RESULT_CANCELLED;
-                    else
-                        mResult = RESULT_SUCCESS;
-                }
-                catch (IOException ioe) {
-                    Log.w("ddms", "Remote exec failed: " + ioe.getMessage());
-                    mResult = RESULT_FAILURE;
-                }
-            }
-
-            mShell.getDisplay().asyncExec(new Runnable() {
-                public void run() {
-                    updateForResult(mResult);
-                }
-            });
-        }
-
-        /**
-         * Called by executeRemoteCommand().
-         */
-        public void addOutput(byte[] data, int offset, int length) {
-
-            Log.v("ddms", "received " + length + " bytes");
-            try {
-                final String text;
-                text = new String(data, offset, length, "ISO-8859-1");
-
-                // add to text widget; must do in UI thread
-                mText.getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        mText.append(text);
-                    }
-                });
-            }
-            catch (UnsupportedEncodingException uee) {
-                uee.printStackTrace();      // not expected
-            }
-        }
-
-        public void flush() {
-            // nothing to flush.
-        }
-
-        /**
-         * Called by executeRemoteCommand().
-         */
-        public boolean isCancelled() {
-            return mCancel;
-        }
-    };
-
-    /*
-     * Execute a remote command, add the output to the text widget, and
-     * update controls.
-     *
-     * We have to run the command in a thread so that the UI continues
-     * to work.
-     */
-    private void executeCommand(Shell shell, IDevice device) {
-        Gatherer gath = new Gatherer(shell, device, commandString(), mText);
-        gath.start();
-    }
-
-    /*
-     * Update the controls after the remote operation completes.  This
-     * must be called from the UI thread.
-     */
-    private void updateForResult(int result) {
-        if (result == Gatherer.RESULT_SUCCESS) {
-            mStatusLabel.setText("Successfully executed '"
-                + shortCommandString() + "'");
-            mSave.setEnabled(true);
-        } else if (result == Gatherer.RESULT_CANCELLED) {
-            mStatusLabel.setText("Execution cancelled; partial results below");
-            mSave.setEnabled(true);     // save partial
-        } else if (result == Gatherer.RESULT_FAILURE) {
-            mStatusLabel.setText("Failed");
-        }
-        mStatusLabel.pack();
-        mCancelDone.setText("Done");
-        mFinished = true;
-    }
-
-    /*
-     * Allow the user to save the contents of the text dialog.
-     */
-    private void saveText(Shell shell) {
-        FileDialog dlg = new FileDialog(shell, SWT.SAVE);
-        String fileName;
-
-        dlg.setText("Save output...");
-        dlg.setFileName(defaultFileName());
-        dlg.setFilterPath(PrefsDialog.getStore().getString("lastTextSaveDir"));
-        dlg.setFilterNames(new String[] {
-            "Text Files (*.txt)"
-        });
-        dlg.setFilterExtensions(new String[] {
-            "*.txt"
-        });
-
-        fileName = dlg.open();
-        if (fileName != null) {
-            PrefsDialog.getStore().setValue("lastTextSaveDir",
-                                            dlg.getFilterPath());
-
-            Log.d("ddms", "Saving output to " + fileName);
-
-            /*
-             * Convert to 8-bit characters.
-             */
-            String text = mText.getText();
-            byte[] ascii;
-            try {
-                ascii = text.getBytes("ISO-8859-1");
-            }
-            catch (UnsupportedEncodingException uee) {
-                uee.printStackTrace();
-                ascii = new byte[0];
-            }
-
-            /*
-             * Output data, converting CRLF to LF.
-             */
-            try {
-                int length = ascii.length;
-
-                FileOutputStream outFile = new FileOutputStream(fileName);
-                BufferedOutputStream out = new BufferedOutputStream(outFile);
-                for (int i = 0; i < length; i++) {
-                    if (i < length-1 &&
-                        ascii[i] == 0x0d && ascii[i+1] == 0x0a)
-                    {
-                        continue;
-                    }
-                    out.write(ascii[i]);
-                }
-                out.close();        // flush buffer, close file
-            }
-            catch (IOException ioe) {
-                Log.w("ddms", "Unable to save " + fileName + ": " + ioe);
-            }
-        }
-    }
-
-
-    /*
-     * Return the shell command we're going to use.
-     */
-    private String commandString() {
-        return mCommand;
-
-    }
-
-    /*
-     * Return a default filename for the "save" command.
-     */
-    private String defaultFileName() {
-        return mFileName;
-    }
-
-    /*
-     * Like commandString(), but length-limited.
-     */
-    private String shortCommandString() {
-        String str = commandString();
-        if (str.length() > 50)
-            return str.substring(0, 50) + "...";
-        else
-            return str;
-    }
-}
-
diff --git a/tools/ddms/app/src/com/android/ddms/DropdownSelectionListener.java b/tools/ddms/app/src/com/android/ddms/DropdownSelectionListener.java
deleted file mode 100644
index 04d921c..0000000
--- a/tools/ddms/app/src/com/android/ddms/DropdownSelectionListener.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/* //device/tools/ddms/src/com/android/ddms/DropdownSelectionListener.java
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.ddms;
-
-import com.android.ddmlib.Log;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.ToolItem;
-
-/**
- * Helper class for drop-down menus in toolbars.
- */
-public class DropdownSelectionListener extends SelectionAdapter {
-    private Menu mMenu;
-    private ToolItem mDropdown;
-
-    /**
-     * Basic constructor.  Creates an empty Menu to hold items.
-     */
-    public DropdownSelectionListener(ToolItem item) {
-        mDropdown = item;
-        mMenu = new Menu(item.getParent().getShell(), SWT.POP_UP);
-    }
-
-    /**
-     * Add an item to the dropdown menu.
-     */
-    public void add(String label) {
-        MenuItem item = new MenuItem(mMenu, SWT.NONE);
-        item.setText(label);
-        item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // update the dropdown's text to match the selection
-                MenuItem sel = (MenuItem) e.widget;
-                mDropdown.setText(sel.getText());
-            }
-        });
-    }
-
-    /**
-     * Invoked when dropdown or neighboring arrow is clicked.
-     */
-    @Override
-    public void widgetSelected(SelectionEvent e) {
-        if (e.detail == SWT.ARROW) {
-            // arrow clicked, show menu
-            ToolItem item = (ToolItem) e.widget;
-            Rectangle rect = item.getBounds();
-            Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y));
-            mMenu.setLocation(pt.x, pt.y + rect.height);
-            mMenu.setVisible(true);
-        } else {
-            // button clicked
-            Log.d("ddms", mDropdown.getText() + " Pressed");
-        }
-    }
-}
-
diff --git a/tools/ddms/app/src/com/android/ddms/Main.java b/tools/ddms/app/src/com/android/ddms/Main.java
deleted file mode 100644
index 050519f..0000000
--- a/tools/ddms/app/src/com/android/ddms/Main.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.android.ddms;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.DebugPortManager;
-import com.android.ddmlib.Log;
-import com.android.sdkstats.SdkStatsService;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.util.Properties;
-
-
-/**
- * Start the UI and network.
- */
-public class Main {
-
-    public static String sRevision;
-
-    public Main() {
-    }
-
-    /*
-     * If a thread bails with an uncaught exception, bring the whole
-     * thing down.
-     */
-    private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
-        public void uncaughtException(Thread t, Throwable e) {
-            Log.e("ddms", "shutting down due to uncaught exception");
-
-            StringWriter sw = new StringWriter();
-            PrintWriter pw = new PrintWriter(sw);
-            e.printStackTrace(pw);
-            Log.e("ddms", sw.toString());
-
-            System.exit(1);
-        }
-    }
-
-    /**
-     * Parse args, start threads.
-     */
-    public static void main(String[] args) {
-        // In order to have the AWT/SWT bridge work on Leopard, we do this little hack.
-        String os = System.getProperty("os.name"); //$NON-NLS-1$
-        if (os.startsWith("Mac OS")) { //$NON-NLS-1$
-            RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
-            System.setProperty(
-                    "JAVA_STARTED_ON_FIRST_THREAD_" + (rt.getName().split("@"))[0], //$NON-NLS-1$
-                    "1"); //$NON-NLS-1$
-        }
-
-        Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
-
-        // load prefs and init the default values
-        PrefsDialog.init();
-
-        Log.d("ddms", "Initializing");
-
-        // the "ping" argument means to check in with the server and exit
-        // the application name and version number must also be supplied
-        if (args.length >= 3 && args[0].equals("ping")) {
-            SdkStatsService.ping(args[1], args[2], null);
-            return;
-        } else if (args.length > 0) {
-            Log.e("ddms", "Unknown argument: " + args[0]);
-            System.exit(1);
-        }
-
-        // get the ddms parent folder location
-        String ddmsParentLocation = System.getProperty("com.android.ddms.bindir"); //$NON-NLS-1$
-
-        // we're past the point where ddms can be called just to send a ping, so we can
-        // ping for ddms itself.
-        ping(ddmsParentLocation);
-
-        DebugPortManager.setProvider(DebugPortProvider.getInstance());
-
-        // create the three main threads
-        UIThread ui = UIThread.getInstance();
-
-        try {
-            ui.runUI(ddmsParentLocation);
-        } finally {
-            PrefsDialog.save();
-
-            AndroidDebugBridge.terminate();
-        }
-
-        Log.d("ddms", "Bye");
-
-        // this is kinda bad, but on MacOS the shutdown doesn't seem to finish because of
-        // a thread called AWT-Shutdown. This will help while I track this down.
-        System.exit(0);
-    }
-
-    public static void ping(String ddmsParentLocation) {
-        Properties p = new Properties();
-        try{
-            File sourceProp;
-            if (ddmsParentLocation != null && ddmsParentLocation.length() > 0) {
-                sourceProp = new File(ddmsParentLocation, "source.properties"); //$NON-NLS-1$
-            } else {
-                sourceProp = new File("source.properties"); //$NON-NLS-1$
-            }
-            p.load(new FileInputStream(sourceProp));
-            sRevision = p.getProperty("Pkg.Revision"); //$NON-NLS-1$
-            if (sRevision != null && sRevision.length() > 0) {
-                SdkStatsService.ping("ddms", sRevision, null);  //$NON-NLS-1$
-            }
-        } catch (FileNotFoundException e) {
-            // couldn't find the file? don't ping.
-        } catch (IOException e) {
-            // couldn't find the file? don't ping.
-        }
-    }
-}
diff --git a/tools/ddms/app/src/com/android/ddms/PrefsDialog.java b/tools/ddms/app/src/com/android/ddms/PrefsDialog.java
deleted file mode 100644
index fbdbfe6..0000000
--- a/tools/ddms/app/src/com/android/ddms/PrefsDialog.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/* //device/tools/ddms/src/com/android/ddms/PrefsDialog.java
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.ddms;
-
-import com.android.ddmlib.DdmConstants;
-import com.android.ddmlib.DdmPreferences;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.PortFieldEditor;
-import com.android.sdkstats.SdkStatsService;
-
-import org.eclipse.jface.preference.BooleanFieldEditor;
-import org.eclipse.jface.preference.DirectoryFieldEditor;
-import org.eclipse.jface.preference.FieldEditorPreferencePage;
-import org.eclipse.jface.preference.FontFieldEditor;
-import org.eclipse.jface.preference.IntegerFieldEditor;
-import org.eclipse.jface.preference.PreferenceDialog;
-import org.eclipse.jface.preference.PreferenceManager;
-import org.eclipse.jface.preference.PreferenceNode;
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.jface.preference.PreferenceStore;
-import org.eclipse.jface.preference.RadioGroupFieldEditor;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Preferences dialog.
- */
-public final class PrefsDialog {
-
-    // Preference store.
-    private static PreferenceStore mPrefStore;
-
-    // public const values for storage
-    public final static String SHELL_X = "shellX"; //$NON-NLS-1$
-    public final static String SHELL_Y = "shellY"; //$NON-NLS-1$
-    public final static String SHELL_WIDTH = "shellWidth"; //$NON-NLS-1$
-    public final static String SHELL_HEIGHT = "shellHeight"; //$NON-NLS-1$
-    public final static String EXPLORER_SHELL_X = "explorerShellX"; //$NON-NLS-1$
-    public final static String EXPLORER_SHELL_Y = "explorerShellY"; //$NON-NLS-1$
-    public final static String EXPLORER_SHELL_WIDTH = "explorerShellWidth"; //$NON-NLS-1$
-    public final static String EXPLORER_SHELL_HEIGHT = "explorerShellHeight"; //$NON-NLS-1$
-    public final static String SHOW_NATIVE_HEAP = "native"; //$NON-NLS-1$
-
-    public final static String LOGCAT_COLUMN_MODE = "ddmsLogColumnMode"; //$NON-NLS-1$
-    public final static String LOGCAT_FONT = "ddmsLogFont"; //$NON-NLS-1$
-
-    public final static String LOGCAT_COLUMN_MODE_AUTO = "auto"; //$NON-NLS-1$
-    public final static String LOGCAT_COLUMN_MODE_MANUAL = "manual"; //$NON-NLS-1$
-
-    private final static String PREFS_DEBUG_PORT_BASE = "adbDebugBasePort"; //$NON-NLS-1$
-    private final static String PREFS_SELECTED_DEBUG_PORT = "debugSelectedPort"; //$NON-NLS-1$
-    private final static String PREFS_DEFAULT_THREAD_UPDATE = "defaultThreadUpdateEnabled"; //$NON-NLS-1$
-    private final static String PREFS_DEFAULT_HEAP_UPDATE = "defaultHeapUpdateEnabled"; //$NON-NLS-1$
-    private final static String PREFS_THREAD_REFRESH_INTERVAL = "threadStatusInterval"; //$NON-NLS-1$
-    private final static String PREFS_LOG_LEVEL = "ddmsLogLevel"; //$NON-NLS-1$
-    private final static String PREFS_TIMEOUT = "timeOut"; //$NON-NLS-1$
-
-
-    /**
-     * Private constructor -- do not instantiate.
-     */
-    private PrefsDialog() {}
-
-    /**
-     * Return the PreferenceStore that holds our values.
-     */
-    public static PreferenceStore getStore() {
-        return mPrefStore;
-    }
-
-    /**
-     * Save the prefs to the config file.
-     */
-    public static void save() {
-        try {
-            mPrefStore.save();
-        }
-        catch (IOException ioe) {
-            Log.w("ddms", "Failed saving prefs file: " + ioe.getMessage());
-        }
-    }
-
-    /**
-     * Do some one-time prep.
-     *
-     * The original plan was to let the individual classes define their
-     * own defaults, which we would get and then override with the config
-     * file.  However, PreferencesStore.load() doesn't trigger the "changed"
-     * events, which means we have to pull the loaded config values out by
-     * hand.
-     *
-     * So, we set the defaults, load the values from the config file, and
-     * then run through and manually export the values.  Then we duplicate
-     * the second part later on for the "changed" events.
-     */
-    public static void init() {
-        assert mPrefStore == null;
-
-        mPrefStore = SdkStatsService.getPreferenceStore();
-
-        if (mPrefStore == null) {
-            // we have a serious issue here...
-            Log.e("ddms",
-                    "failed to access both the user HOME directory and the system wide temp folder. Quitting.");
-            System.exit(1);
-        }
-
-        // configure default values
-        setDefaults(System.getProperty("user.home")); //$NON-NLS-1$
-
-        // listen for changes
-        mPrefStore.addPropertyChangeListener(new ChangeListener());
-
-        // Now we initialize the value of the preference, from the values in the store.
-
-        // First the ddm lib.
-        DdmPreferences.setDebugPortBase(mPrefStore.getInt(PREFS_DEBUG_PORT_BASE));
-        DdmPreferences.setSelectedDebugPort(mPrefStore.getInt(PREFS_SELECTED_DEBUG_PORT));
-        DdmPreferences.setLogLevel(mPrefStore.getString(PREFS_LOG_LEVEL));
-        DdmPreferences.setInitialThreadUpdate(mPrefStore.getBoolean(PREFS_DEFAULT_THREAD_UPDATE));
-        DdmPreferences.setInitialHeapUpdate(mPrefStore.getBoolean(PREFS_DEFAULT_HEAP_UPDATE));
-        DdmPreferences.setTimeOut(mPrefStore.getInt(PREFS_TIMEOUT));
-
-        // some static values
-        String out = System.getenv("ANDROID_PRODUCT_OUT"); //$NON-NLS-1$
-        DdmUiPreferences.setSymbolsLocation(out + File.separator + "symbols"); //$NON-NLS-1$
-        DdmUiPreferences.setAddr2LineLocation("arm-eabi-addr2line"); //$NON-NLS-1$
-
-        String traceview = System.getProperty("com.android.ddms.bindir");  //$NON-NLS-1$
-        if (traceview != null && traceview.length() != 0) {
-            traceview += File.separator + DdmConstants.FN_TRACEVIEW;
-        } else {
-            traceview = DdmConstants.FN_TRACEVIEW;
-        }
-        DdmUiPreferences.setTraceviewLocation(traceview);
-
-        // Now the ddmui lib
-        DdmUiPreferences.setStore(mPrefStore);
-        DdmUiPreferences.setThreadRefreshInterval(mPrefStore.getInt(PREFS_THREAD_REFRESH_INTERVAL));
-    }
-
-    /*
-     * Set default values for all preferences.  These are either defined
-     * statically or are based on the values set by the class initializers
-     * in other classes.
-     *
-     * The other threads (e.g. VMWatcherThread) haven't been created yet,
-     * so we want to use static values rather than reading fields from
-     * class.getInstance().
-     */
-    private static void setDefaults(String homeDir) {
-        mPrefStore.setDefault(PREFS_DEBUG_PORT_BASE, DdmPreferences.DEFAULT_DEBUG_PORT_BASE);
-
-        mPrefStore.setDefault(PREFS_SELECTED_DEBUG_PORT,
-                DdmPreferences.DEFAULT_SELECTED_DEBUG_PORT);
-
-        mPrefStore.setDefault(PREFS_DEFAULT_THREAD_UPDATE, true);
-        mPrefStore.setDefault(PREFS_DEFAULT_HEAP_UPDATE, false);
-        mPrefStore.setDefault(PREFS_THREAD_REFRESH_INTERVAL,
-            DdmUiPreferences.DEFAULT_THREAD_REFRESH_INTERVAL);
-
-        mPrefStore.setDefault("textSaveDir", homeDir); //$NON-NLS-1$
-        mPrefStore.setDefault("imageSaveDir", homeDir); //$NON-NLS-1$
-
-        mPrefStore.setDefault(PREFS_LOG_LEVEL, "info"); //$NON-NLS-1$
-
-        mPrefStore.setDefault(PREFS_TIMEOUT, DdmPreferences.DEFAULT_TIMEOUT);
-
-        // choose a default font for the text output
-        FontData fdat = new FontData("Courier", 10, SWT.NORMAL); //$NON-NLS-1$
-        mPrefStore.setDefault("textOutputFont", fdat.toString()); //$NON-NLS-1$
-
-        // layout information.
-        mPrefStore.setDefault(SHELL_X, 100);
-        mPrefStore.setDefault(SHELL_Y, 100);
-        mPrefStore.setDefault(SHELL_WIDTH, 800);
-        mPrefStore.setDefault(SHELL_HEIGHT, 600);
-
-        mPrefStore.setDefault(EXPLORER_SHELL_X, 50);
-        mPrefStore.setDefault(EXPLORER_SHELL_Y, 50);
-
-        mPrefStore.setDefault(SHOW_NATIVE_HEAP, false);
-    }
-
-
-    /*
-     * Create a "listener" to take action when preferences change.  These are
-     * required for ongoing activities that don't check prefs on each use.
-     *
-     * This is only invoked when something explicitly changes the value of
-     * a preference (e.g. not when the prefs file is loaded).
-     */
-    private static class ChangeListener implements IPropertyChangeListener {
-        public void propertyChange(PropertyChangeEvent event) {
-            String changed = event.getProperty();
-
-            if (changed.equals(PREFS_DEBUG_PORT_BASE)) {
-                DdmPreferences.setDebugPortBase(mPrefStore.getInt(PREFS_DEBUG_PORT_BASE));
-            } else if (changed.equals(PREFS_SELECTED_DEBUG_PORT)) {
-                DdmPreferences.setSelectedDebugPort(mPrefStore.getInt(PREFS_SELECTED_DEBUG_PORT));
-            } else if (changed.equals(PREFS_LOG_LEVEL)) {
-                DdmPreferences.setLogLevel((String)event.getNewValue());
-            } else if (changed.equals("textSaveDir")) {
-                mPrefStore.setValue("lastTextSaveDir",
-                    (String) event.getNewValue());
-            } else if (changed.equals("imageSaveDir")) {
-                mPrefStore.setValue("lastImageSaveDir",
-                    (String) event.getNewValue());
-            } else if (changed.equals(PREFS_TIMEOUT)) {
-                DdmPreferences.setTimeOut(mPrefStore.getInt(PREFS_TIMEOUT));
-            } else {
-                Log.v("ddms", "Preference change: " + event.getProperty()
-                    + ": '" + event.getOldValue()
-                    + "' --> '" + event.getNewValue() + "'");
-            }
-        }
-    }
-
-
-    /**
-     * Create and display the dialog.
-     */
-    public static void run(Shell shell) {
-        assert mPrefStore != null;
-
-        PreferenceManager prefMgr = new PreferenceManager();
-
-        PreferenceNode node, subNode;
-
-        // this didn't work -- got NPE, possibly from class lookup:
-        //PreferenceNode app = new PreferenceNode("app", "Application", null,
-        //    AppPrefs.class.getName());
-
-        node = new PreferenceNode("debugger", new DebuggerPrefs());
-        prefMgr.addToRoot(node);
-
-        subNode = new PreferenceNode("panel", new PanelPrefs());
-        //prefMgr.addTo(node.getId(), subNode);
-        prefMgr.addToRoot(subNode);
-
-        node = new PreferenceNode("LogCat", new LogCatPrefs());
-        prefMgr.addToRoot(node);
-
-        node = new PreferenceNode("misc", new MiscPrefs());
-        prefMgr.addToRoot(node);
-
-        node = new PreferenceNode("stats", new UsageStatsPrefs());
-        prefMgr.addToRoot(node);
-
-        PreferenceDialog dlg = new PreferenceDialog(shell, prefMgr);
-        dlg.setPreferenceStore(mPrefStore);
-
-        // run it
-        dlg.open();
-
-        // save prefs
-        try {
-            mPrefStore.save();
-        }
-        catch (IOException ioe) {
-        }
-
-        // discard the stuff we created
-        //prefMgr.dispose();
-        //dlg.dispose();
-    }
-
-    /**
-     * "Debugger" prefs page.
-     */
-    private static class DebuggerPrefs extends FieldEditorPreferencePage {
-
-        /**
-         * Basic constructor.
-         */
-        public DebuggerPrefs() {
-            super(GRID);        // use "grid" layout so edit boxes line up
-            setTitle("Debugger");
-        }
-
-         /**
-         * Create field editors.
-         */
-        @Override
-        protected void createFieldEditors() {
-            IntegerFieldEditor ife;
-
-            ife = new PortFieldEditor(PREFS_DEBUG_PORT_BASE,
-                "Starting value for local port:", getFieldEditorParent());
-            addField(ife);
-
-            ife = new PortFieldEditor(PREFS_SELECTED_DEBUG_PORT,
-                "Port of Selected VM:", getFieldEditorParent());
-            addField(ife);
-        }
-    }
-
-    /**
-     * "Panel" prefs page.
-     */
-    private static class PanelPrefs extends FieldEditorPreferencePage {
-
-        /**
-         * Basic constructor.
-         */
-        public PanelPrefs() {
-            super(FLAT);        // use "flat" layout
-            setTitle("Info Panels");
-        }
-
-        /**
-         * Create field editors.
-         */
-        @Override
-        protected void createFieldEditors() {
-            BooleanFieldEditor bfe;
-            IntegerFieldEditor ife;
-
-            bfe = new BooleanFieldEditor(PREFS_DEFAULT_THREAD_UPDATE,
-                "Thread updates enabled by default", getFieldEditorParent());
-            addField(bfe);
-
-            bfe = new BooleanFieldEditor(PREFS_DEFAULT_HEAP_UPDATE,
-                "Heap updates enabled by default", getFieldEditorParent());
-            addField(bfe);
-
-            ife = new IntegerFieldEditor(PREFS_THREAD_REFRESH_INTERVAL,
-                "Thread status interval (seconds):", getFieldEditorParent());
-            ife.setValidRange(1, 60);
-            addField(ife);
-        }
-    }
-
-    /**
-     * "logcat" prefs page.
-     */
-    private static class LogCatPrefs extends FieldEditorPreferencePage {
-
-        /**
-         * Basic constructor.
-         */
-        public LogCatPrefs() {
-            super(FLAT);        // use "flat" layout
-            setTitle("Logcat");
-        }
-
-        /**
-         * Create field editors.
-         */
-        @Override
-        protected void createFieldEditors() {
-            RadioGroupFieldEditor rgfe;
-
-            rgfe = new RadioGroupFieldEditor(PrefsDialog.LOGCAT_COLUMN_MODE,
-                "Message Column Resizing Mode", 1, new String[][] {
-                    { "Manual", PrefsDialog.LOGCAT_COLUMN_MODE_MANUAL },
-                    { "Automatic", PrefsDialog.LOGCAT_COLUMN_MODE_AUTO },
-                    },
-                getFieldEditorParent(), true);
-            addField(rgfe);
-
-            FontFieldEditor ffe = new FontFieldEditor(PrefsDialog.LOGCAT_FONT, "Text output font:",
-                    getFieldEditorParent());
-            addField(ffe);
-        }
-    }
-
-    /**
-     * "misc" prefs page.
-     */
-    private static class MiscPrefs extends FieldEditorPreferencePage {
-
-        /**
-         * Basic constructor.
-         */
-        public MiscPrefs() {
-            super(FLAT);        // use "flat" layout
-            setTitle("Misc");
-        }
-
-        /**
-         * Create field editors.
-         */
-        @Override
-        protected void createFieldEditors() {
-            DirectoryFieldEditor dfe;
-            FontFieldEditor ffe;
-
-            IntegerFieldEditor ife = new IntegerFieldEditor(PREFS_TIMEOUT,
-                    "ADB connection time out (ms):", getFieldEditorParent());
-            addField(ife);
-
-            dfe = new DirectoryFieldEditor("textSaveDir",
-                "Default text save dir:", getFieldEditorParent());
-            addField(dfe);
-
-            dfe = new DirectoryFieldEditor("imageSaveDir",
-                "Default image save dir:", getFieldEditorParent());
-            addField(dfe);
-
-            ffe = new FontFieldEditor("textOutputFont", "Text output font:",
-                getFieldEditorParent());
-            addField(ffe);
-
-            RadioGroupFieldEditor rgfe;
-
-            rgfe = new RadioGroupFieldEditor(PREFS_LOG_LEVEL,
-                "Logging Level", 1, new String[][] {
-                    { "Verbose", LogLevel.VERBOSE.getStringValue() },
-                    { "Debug", LogLevel.DEBUG.getStringValue() },
-                    { "Info", LogLevel.INFO.getStringValue() },
-                    { "Warning", LogLevel.WARN.getStringValue() },
-                    { "Error", LogLevel.ERROR.getStringValue() },
-                    { "Assert", LogLevel.ASSERT.getStringValue() },
-                    },
-                getFieldEditorParent(), true);
-            addField(rgfe);
-        }
-    }
-
-    /**
-     * "Device" prefs page.
-     */
-    private static class UsageStatsPrefs extends PreferencePage {
-
-        private BooleanFieldEditor mOptInCheckbox;
-        private Composite mTop;
-
-        /**
-         * Basic constructor.
-         */
-        public UsageStatsPrefs() {
-            setTitle("Usage Stats");
-        }
-
-        @Override
-        protected Control createContents(Composite parent) {
-            mTop = new Composite(parent, SWT.NONE);
-            mTop.setLayout(new GridLayout(1, false));
-            mTop.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-            Link text = new Link(mTop, SWT.WRAP);
-            text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            text.setText(SdkStatsService.BODY_TEXT);
-
-            text.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent event) {
-                    SdkStatsService.openUrl(event.text);
-                }
-            });
-
-            mOptInCheckbox = new BooleanFieldEditor(SdkStatsService.PING_OPT_IN,
-                    SdkStatsService.CHECKBOX_TEXT, mTop);
-            mOptInCheckbox.setPage(this);
-            mOptInCheckbox.setPreferenceStore(getPreferenceStore());
-            mOptInCheckbox.load();
-
-            return null;
-        }
-
-        @Override
-        protected Point doComputeSize() {
-            if (mTop != null) {
-                return mTop.computeSize(450, SWT.DEFAULT, true);
-            }
-
-            return super.doComputeSize();
-        }
-
-        @Override
-        protected void performDefaults() {
-            if (mOptInCheckbox != null) {
-                mOptInCheckbox.loadDefault();
-            }
-            super.performDefaults();
-        }
-
-        @Override
-        public void performApply() {
-            if (mOptInCheckbox != null) {
-                mOptInCheckbox.store();
-            }
-            super.performApply();
-        }
-
-        @Override
-        public boolean performOk() {
-            if (mOptInCheckbox != null) {
-                mOptInCheckbox.store();
-            }
-            return super.performOk();
-        }
-    }
-
-}
-
-
diff --git a/tools/ddms/app/src/com/android/ddms/StaticPortConfigDialog.java b/tools/ddms/app/src/com/android/ddms/StaticPortConfigDialog.java
deleted file mode 100644
index d00bc7f..0000000
--- a/tools/ddms/app/src/com/android/ddms/StaticPortConfigDialog.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * 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.android.ddms;
-
-import com.android.ddmuilib.TableHelper;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Dialog to configure the static debug ports.
- *
- */
-public class StaticPortConfigDialog extends Dialog {
-
-    /** Preference name for the 0th column width */
-    private static final String PREFS_DEVICE_COL = "spcd.deviceColumn"; //$NON-NLS-1$
-
-    /** Preference name for the 1st column width */
-    private static final String PREFS_APP_COL = "spcd.AppColumn"; //$NON-NLS-1$
-
-    /** Preference name for the 2nd column width */
-    private static final String PREFS_PORT_COL = "spcd.PortColumn"; //$NON-NLS-1$
-
-    private static final int COL_DEVICE = 0;
-    private static final int COL_APPLICATION = 1;
-    private static final int COL_PORT = 2;
-
-
-    private static final int DLG_WIDTH = 500;
-    private static final int DLG_HEIGHT = 300;
-
-    private Shell mShell;
-    private Shell mParent;
-
-    private Table mPortTable;
-
-    /**
-     * Array containing the list of already used static port to avoid
-     * duplication.
-     */
-    private ArrayList<Integer> mPorts = new ArrayList<Integer>();
-
-    /**
-     * Basic constructor.
-     * @param parent
-     */
-    public StaticPortConfigDialog(Shell parent) {
-        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-    }
-
-    /**
-     * Open and display the dialog. This method returns only when the
-     * user closes the dialog somehow.
-     *
-     */
-    public void open() {
-        createUI();
-
-        if (mParent == null || mShell == null) {
-            return;
-        }
-
-        updateFromStore();
-
-        // Set the dialog size.
-        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
-        Rectangle r = mParent.getBounds();
-        // get the center new top left.
-        int cx = r.x + r.width/2;
-        int x = cx - DLG_WIDTH / 2;
-        int cy = r.y + r.height/2;
-        int y = cy - DLG_HEIGHT / 2;
-        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
-
-        mShell.pack();
-
-        // actually open the dialog
-        mShell.open();
-
-        // event loop until the dialog is closed.
-        Display display = mParent.getDisplay();
-        while (!mShell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-    }
-
-    /**
-     * Creates the dialog ui.
-     */
-    private void createUI() {
-        mParent = getParent();
-        mShell = new Shell(mParent, getStyle());
-        mShell.setText("Static Port Configuration");
-
-        mShell.setLayout(new GridLayout(1, true));
-
-        mShell.addListener(SWT.Close, new Listener() {
-            public void handleEvent(Event event) {
-                event.doit = true;
-            }
-        });
-
-        // center part with the list on the left and the buttons
-        // on the right.
-        Composite main = new Composite(mShell, SWT.NONE);
-        main.setLayoutData(new GridData(GridData.FILL_BOTH));
-        main.setLayout(new GridLayout(2, false));
-
-        // left part: list view
-        mPortTable = new Table(main, SWT.SINGLE | SWT.FULL_SELECTION);
-        mPortTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mPortTable.setHeaderVisible(true);
-        mPortTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mPortTable, "Device Serial Number",
-                SWT.LEFT, "emulator-5554", //$NON-NLS-1$
-                PREFS_DEVICE_COL, PrefsDialog.getStore());
-
-        TableHelper.createTableColumn(mPortTable, "Application Package",
-                SWT.LEFT, "com.android.samples.phone", //$NON-NLS-1$
-                PREFS_APP_COL, PrefsDialog.getStore());
-
-        TableHelper.createTableColumn(mPortTable, "Debug Port",
-                SWT.RIGHT, "Debug Port", //$NON-NLS-1$
-                PREFS_PORT_COL, PrefsDialog.getStore());
-
-        // right part: buttons
-        Composite buttons = new Composite(main, SWT.NONE);
-        buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-        buttons.setLayout(new GridLayout(1, true));
-
-        Button newButton = new Button(buttons, SWT.NONE);
-        newButton.setText("New...");
-        newButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
-                        mPorts);
-                if (dlg.open()) {
-                    // get the text
-                    String device = dlg.getDeviceSN();
-                    String app = dlg.getAppName();
-                    int port = dlg.getPortNumber();
-
-                    // add it to the list
-                    addEntry(device, app, port);
-                }
-            }
-        });
-
-        final Button editButton = new Button(buttons, SWT.NONE);
-        editButton.setText("Edit...");
-        editButton.setEnabled(false);
-        editButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                int index = mPortTable.getSelectionIndex();
-                String oldDeviceName = getDeviceName(index);
-                String oldAppName = getAppName(index);
-                String oldPortNumber = getPortNumber(index);
-                StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
-                        mPorts, oldDeviceName, oldAppName, oldPortNumber);
-                if (dlg.open()) {
-                    // get the text
-                    String deviceName = dlg.getDeviceSN();
-                    String app = dlg.getAppName();
-                    int port = dlg.getPortNumber();
-
-                    // add it to the list
-                    replaceEntry(index, deviceName, app, port);
-                }
-            }
-        });
-
-        final Button deleteButton = new Button(buttons, SWT.NONE);
-        deleteButton.setText("Delete");
-        deleteButton.setEnabled(false);
-        deleteButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                int index = mPortTable.getSelectionIndex();
-                removeEntry(index);
-            }
-        });
-
-        // bottom part with the ok/cancel
-        Composite bottomComp = new Composite(mShell, SWT.NONE);
-        bottomComp.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_CENTER));
-        bottomComp.setLayout(new GridLayout(2, true));
-
-        Button okButton = new Button(bottomComp, SWT.NONE);
-        okButton.setText("OK");
-        okButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateStore();
-                mShell.close();
-            }
-        });
-
-        Button cancelButton = new Button(bottomComp, SWT.NONE);
-        cancelButton.setText("Cancel");
-        cancelButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mShell.close();
-            }
-        });
-
-        mPortTable.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // get the selection index
-                int index = mPortTable.getSelectionIndex();
-
-                boolean enabled = index != -1;
-                editButton.setEnabled(enabled);
-                deleteButton.setEnabled(enabled);
-            }
-        });
-
-        mShell.pack();
-
-    }
-
-    /**
-     * Add a new entry in the list.
-     * @param deviceName the serial number of the device
-     * @param appName java package for the application
-     * @param portNumber port number
-     */
-    private void addEntry(String deviceName, String appName, int portNumber) {
-        // create a new item for the table
-        TableItem item = new TableItem(mPortTable, SWT.NONE);
-
-        item.setText(COL_DEVICE, deviceName);
-        item.setText(COL_APPLICATION, appName);
-        item.setText(COL_PORT, Integer.toString(portNumber));
-
-        // add the port to the list of port number used.
-        mPorts.add(portNumber);
-    }
-
-    /**
-     * Remove an entry from the list.
-     * @param index The index of the entry to be removed
-     */
-    private void removeEntry(int index) {
-        // remove from the ui
-        mPortTable.remove(index);
-
-        // and from the port list.
-        mPorts.remove(index);
-    }
-
-    /**
-     * Replace an entry in the list with new values.
-     * @param index The index of the item to be replaced
-     * @param deviceName the serial number of the device
-     * @param appName The new java package for the application
-     * @param portNumber The new port number.
-     */
-    private void replaceEntry(int index, String deviceName, String appName, int portNumber) {
-        // get the table item by index
-        TableItem item = mPortTable.getItem(index);
-
-        // set its new value
-        item.setText(COL_DEVICE, deviceName);
-        item.setText(COL_APPLICATION, appName);
-        item.setText(COL_PORT, Integer.toString(portNumber));
-
-        // and replace the port number in the port list.
-        mPorts.set(index, portNumber);
-    }
-
-
-    /**
-     * Returns the device name for a specific index
-     * @param index The index
-     * @return the java package name of the application
-     */
-    private String getDeviceName(int index) {
-        TableItem item = mPortTable.getItem(index);
-        return item.getText(COL_DEVICE);
-    }
-
-    /**
-     * Returns the application name for a specific index
-     * @param index The index
-     * @return the java package name of the application
-     */
-    private String getAppName(int index) {
-        TableItem item = mPortTable.getItem(index);
-        return item.getText(COL_APPLICATION);
-    }
-
-    /**
-     * Returns the port number for a specific index
-     * @param index The index
-     * @return the port number
-     */
-    private String getPortNumber(int index) {
-        TableItem item = mPortTable.getItem(index);
-        return item.getText(COL_PORT);
-    }
-
-    /**
-     * Updates the ui from the value in the preference store.
-     */
-    private void updateFromStore() {
-        // get the map from the debug port manager
-        DebugPortProvider provider = DebugPortProvider.getInstance();
-        Map<String, Map<String, Integer>> map = provider.getPortList();
-
-        // we're going to loop on the keys and fill the table.
-        Set<String> deviceKeys = map.keySet();
-
-        for (String deviceKey : deviceKeys) {
-            Map<String, Integer> deviceMap = map.get(deviceKey);
-            if (deviceMap != null) {
-                Set<String> appKeys = deviceMap.keySet();
-
-                for (String appKey : appKeys) {
-                    Integer port = deviceMap.get(appKey);
-                    if (port != null) {
-                        addEntry(deviceKey, appKey, port);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Update the store from the content of the ui.
-     */
-    private void updateStore() {
-        // create a new Map object and fill it.
-        HashMap<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();
-
-        int count = mPortTable.getItemCount();
-
-        for (int i = 0 ; i < count ; i++) {
-            TableItem item = mPortTable.getItem(i);
-            String deviceName = item.getText(COL_DEVICE);
-
-            Map<String, Integer> deviceMap = map.get(deviceName);
-            if (deviceMap == null) {
-                deviceMap = new HashMap<String, Integer>();
-                map.put(deviceName, deviceMap);
-            }
-
-            deviceMap.put(item.getText(COL_APPLICATION), Integer.valueOf(item.getText(COL_PORT)));
-        }
-
-        // set it in the store through the debug port manager.
-        DebugPortProvider provider = DebugPortProvider.getInstance();
-        provider.setPortList(map);
-    }
-}
diff --git a/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java b/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java
deleted file mode 100644
index b224967..0000000
--- a/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * 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.android.ddms;
-
-import com.android.ddmlib.IDevice;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.ArrayList;
-
-/**
- * Small dialog box to edit a static port number.
- */
-public class StaticPortEditDialog extends Dialog {
-
-    private static final int DLG_WIDTH = 400;
-    private static final int DLG_HEIGHT = 200;
-
-    private Shell mParent;
-
-    private Shell mShell;
-
-    private boolean mOk = false;
-
-    private String mAppName;
-
-    private String mPortNumber;
-
-    private Button mOkButton;
-
-    private Label mWarning;
-
-    /** List of ports already in use */
-    private ArrayList<Integer> mPorts;
-
-    /** This is the port being edited. */
-    private int mEditPort = -1;
-    private String mDeviceSn;
-
-    /**
-     * Creates a dialog with empty fields.
-     * @param parent The parent Shell
-     * @param ports The list of already used port numbers.
-     */
-    public StaticPortEditDialog(Shell parent, ArrayList<Integer> ports) {
-        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-        mPorts = ports;
-        mDeviceSn = IDevice.FIRST_EMULATOR_SN;
-    }
-
-    /**
-     * Creates a dialog with predefined values.
-     * @param shell The parent shell
-     * @param ports The list of already used port numbers.
-     * @param oldDeviceSN the device serial number to display
-     * @param oldAppName The application name to display
-     * @param oldPortNumber The port number to display
-     */
-    public StaticPortEditDialog(Shell shell, ArrayList<Integer> ports,
-            String oldDeviceSN, String oldAppName, String oldPortNumber) {
-        this(shell, ports);
-
-        mDeviceSn = oldDeviceSN;
-        mAppName = oldAppName;
-        mPortNumber = oldPortNumber;
-        mEditPort = Integer.valueOf(mPortNumber);
-    }
-
-    /**
-     * Opens the dialog. The method will return when the user closes the dialog
-     * somehow.
-     *
-     * @return true if ok was pressed, false if cancelled.
-     */
-    public boolean open() {
-        createUI();
-
-        if (mParent == null || mShell == null) {
-            return false;
-        }
-
-        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
-        Rectangle r = mParent.getBounds();
-        // get the center new top left.
-        int cx = r.x + r.width/2;
-        int x = cx - DLG_WIDTH / 2;
-        int cy = r.y + r.height/2;
-        int y = cy - DLG_HEIGHT / 2;
-        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
-
-        mShell.open();
-
-        Display display = mParent.getDisplay();
-        while (!mShell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-
-        return mOk;
-    }
-
-    public String getDeviceSN() {
-        return mDeviceSn;
-    }
-
-    public String getAppName() {
-        return mAppName;
-    }
-
-    public int getPortNumber() {
-        return Integer.valueOf(mPortNumber);
-    }
-
-    private void createUI() {
-        mParent = getParent();
-        mShell = new Shell(mParent, getStyle());
-        mShell.setText("Static Port");
-
-        mShell.setLayout(new GridLayout(1, false));
-
-        mShell.addListener(SWT.Close, new Listener() {
-            public void handleEvent(Event event) {
-            }
-        });
-
-        // center part with the edit field
-        Composite main = new Composite(mShell, SWT.NONE);
-        main.setLayoutData(new GridData(GridData.FILL_BOTH));
-        main.setLayout(new GridLayout(2, false));
-
-        Label l0 = new Label(main, SWT.NONE);
-        l0.setText("Device Name:");
-
-        final Text deviceSNText = new Text(main, SWT.SINGLE | SWT.BORDER);
-        deviceSNText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        if (mDeviceSn != null) {
-            deviceSNText.setText(mDeviceSn);
-        }
-        deviceSNText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mDeviceSn = deviceSNText.getText().trim();
-                validate();
-            }
-        });
-
-        Label l = new Label(main, SWT.NONE);
-        l.setText("Application Name:");
-
-        final Text appNameText = new Text(main, SWT.SINGLE | SWT.BORDER);
-        if (mAppName != null) {
-            appNameText.setText(mAppName);
-        }
-        appNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        appNameText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mAppName = appNameText.getText().trim();
-                validate();
-            }
-        });
-
-        Label l2 = new Label(main, SWT.NONE);
-        l2.setText("Debug Port:");
-
-        final Text debugPortText = new Text(main, SWT.SINGLE | SWT.BORDER);
-        if (mPortNumber != null) {
-            debugPortText.setText(mPortNumber);
-        }
-        debugPortText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        debugPortText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mPortNumber = debugPortText.getText().trim();
-                validate();
-            }
-        });
-
-        // warning label
-        Composite warningComp = new Composite(mShell, SWT.NONE);
-        warningComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        warningComp.setLayout(new GridLayout(1, true));
-
-        mWarning = new Label(warningComp, SWT.NONE);
-        mWarning.setText("");
-        mWarning.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        // bottom part with the ok/cancel
-        Composite bottomComp = new Composite(mShell, SWT.NONE);
-        bottomComp
-                .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
-        bottomComp.setLayout(new GridLayout(2, true));
-
-        mOkButton = new Button(bottomComp, SWT.NONE);
-        mOkButton.setText("OK");
-        mOkButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mOk = true;
-                mShell.close();
-            }
-        });
-        mOkButton.setEnabled(false);
-        mShell.setDefaultButton(mOkButton);
-
-        Button cancelButton = new Button(bottomComp, SWT.NONE);
-        cancelButton.setText("Cancel");
-        cancelButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mShell.close();
-            }
-        });
-
-        validate();
-    }
-
-    /**
-     * Validates the content of the 2 text fields and enable/disable "ok", while
-     * setting up the warning/error message.
-     */
-    private void validate() {
-        // first we reset the warning dialog. This allows us to latter
-        // display warnings.
-        mWarning.setText(""); // $NON-NLS-1$
-
-        // check the device name field is not empty
-        if (mDeviceSn == null || mDeviceSn.length() == 0) {
-            mWarning.setText("Device name missing.");
-            mOkButton.setEnabled(false);
-            return;
-        }
-
-        // check the application name field is not empty
-        if (mAppName == null || mAppName.length() == 0) {
-            mWarning.setText("Application name missing.");
-            mOkButton.setEnabled(false);
-            return;
-        }
-
-        String packageError = "Application name must be a valid Java package name.";
-
-        // validate the package name as well. It must be a fully qualified
-        // java package.
-        String[] packageSegments = mAppName.split("\\."); // $NON-NLS-1$
-        for (String p : packageSegments) {
-            if (p.matches("^[a-zA-Z][a-zA-Z0-9]*") == false) { // $NON-NLS-1$
-                mWarning.setText(packageError);
-                mOkButton.setEnabled(false);
-                return;
-            }
-
-            // lets also display a warning if the package contains upper case
-            // letters.
-            if (p.matches("^[a-z][a-z0-9]*") == false) { // $NON-NLS-1$
-                mWarning.setText("Lower case is recommended for Java packages.");
-            }
-        }
-
-        // the split will not detect the last char being a '.'
-        // so we test it manually
-        if (mAppName.charAt(mAppName.length()-1) == '.') {
-            mWarning.setText(packageError);
-            mOkButton.setEnabled(false);
-            return;
-        }
-
-        // now we test the package name field is not empty.
-        if (mPortNumber == null || mPortNumber.length() == 0) {
-            mWarning.setText("Port Number missing.");
-            mOkButton.setEnabled(false);
-            return;
-        }
-
-        // then we check it only contains digits.
-        if (mPortNumber.matches("[0-9]*") == false) { // $NON-NLS-1$
-            mWarning.setText("Port Number invalid.");
-            mOkButton.setEnabled(false);
-            return;
-        }
-
-        // get the int from the port number to validate
-        long port = Long.valueOf(mPortNumber);
-        if (port >= 32767) {
-            mOkButton.setEnabled(false);
-            return;
-        }
-
-        // check if its in the list of already used ports
-        if (port != mEditPort) {
-            for (Integer i : mPorts) {
-                if (port == i.intValue()) {
-                    mWarning.setText("Port already in use.");
-                    mOkButton.setEnabled(false);
-                    return;
-                }
-            }
-        }
-
-        // at this point there's not error, so we enable the ok button.
-        mOkButton.setEnabled(true);
-    }
-}
diff --git a/tools/ddms/app/src/com/android/ddms/UIThread.java b/tools/ddms/app/src/com/android/ddms/UIThread.java
deleted file mode 100644
index c98b3f1..0000000
--- a/tools/ddms/app/src/com/android/ddms/UIThread.java
+++ /dev/null
@@ -1,1693 +0,0 @@
-/*
- * 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.android.ddms;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.ClientData.IHprofDumpHandler;
-import com.android.ddmlib.ClientData.MethodProfilingStatus;
-import com.android.ddmlib.Log.ILogOutput;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmuilib.AllocationPanel;
-import com.android.ddmuilib.DevicePanel;
-import com.android.ddmuilib.EmulatorControlPanel;
-import com.android.ddmuilib.HeapPanel;
-import com.android.ddmuilib.ITableFocusListener;
-import com.android.ddmuilib.ImageHelper;
-import com.android.ddmuilib.ImageLoader;
-import com.android.ddmuilib.InfoPanel;
-import com.android.ddmuilib.NativeHeapPanel;
-import com.android.ddmuilib.ScreenShotDialog;
-import com.android.ddmuilib.SysinfoPanel;
-import com.android.ddmuilib.TablePanel;
-import com.android.ddmuilib.ThreadPanel;
-import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
-import com.android.ddmuilib.actions.ToolItemAction;
-import com.android.ddmuilib.explorer.DeviceExplorer;
-import com.android.ddmuilib.handler.BaseFileHandler;
-import com.android.ddmuilib.handler.MethodProfilingHandler;
-import com.android.ddmuilib.log.event.EventLogPanel;
-import com.android.ddmuilib.logcat.LogColors;
-import com.android.ddmuilib.logcat.LogFilter;
-import com.android.ddmuilib.logcat.LogPanel;
-import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.preference.PreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTError;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.events.MenuAdapter;
-import org.eclipse.swt.events.MenuEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.events.ShellListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.MessageBox;
-import org.eclipse.swt.widgets.Sash;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.swt.widgets.TabItem;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-
-import java.io.File;
-import java.util.ArrayList;
-
-/**
- * This acts as the UI builder. This cannot be its own thread since this prevent using AWT in an
- * SWT application. So this class mainly builds the ui, and manages communication between the panels
- * when {@link IDevice} / {@link Client} selection changes.
- */
-public class UIThread implements IUiSelectionListener, IClientChangeListener {
-    /*
-     * UI tab panel definitions. The constants here must match up with the array
-     * indices in mPanels. PANEL_CLIENT_LIST is a "virtual" panel representing
-     * the client list.
-     */
-    public static final int PANEL_CLIENT_LIST = -1;
-
-    public static final int PANEL_INFO = 0;
-
-    public static final int PANEL_THREAD = 1;
-
-    public static final int PANEL_HEAP = 2;
-
-    public static final int PANEL_NATIVE_HEAP = 3;
-
-    private static final int PANEL_ALLOCATIONS = 4;
-
-    private static final int PANEL_SYSINFO = 5;
-
-    private static final int PANEL_COUNT = 6;
-
-    /** Content is setup in the constructor */
-    private static TablePanel[] mPanels = new TablePanel[PANEL_COUNT];
-
-    private static final String[] mPanelNames = new String[] {
-            "Info", "Threads", "VM Heap", "Native Heap", "Allocation Tracker", "Sysinfo"
-    };
-
-    private static final String[] mPanelTips = new String[] {
-            "Client information", "Thread status", "VM heap status",
-            "Native heap status", "Allocation Tracker", "Sysinfo graphs"
-    };
-
-    private static final String PREFERENCE_LOGSASH =
-        "logSashLocation"; //$NON-NLS-1$
-    private static final String PREFERENCE_SASH =
-        "sashLocation"; //$NON-NLS-1$
-
-    private static final String PREFS_COL_TIME =
-        "logcat.time"; //$NON-NLS-1$
-    private static final String PREFS_COL_LEVEL =
-        "logcat.level"; //$NON-NLS-1$
-    private static final String PREFS_COL_PID =
-        "logcat.pid"; //$NON-NLS-1$
-    private static final String PREFS_COL_TAG =
-        "logcat.tag"; //$NON-NLS-1$
-    private static final String PREFS_COL_MESSAGE =
-        "logcat.message"; //$NON-NLS-1$
-
-    private static final String PREFS_FILTERS = "logcat.filter"; //$NON-NLS-1$
-
-    // singleton instance
-    private static UIThread mInstance = new UIThread();
-
-    // our display
-    private Display mDisplay;
-
-    // the table we show in the left-hand pane
-    private DevicePanel mDevicePanel;
-
-    private IDevice mCurrentDevice = null;
-    private Client mCurrentClient = null;
-
-    // status line at the bottom of the app window
-    private Label mStatusLine;
-
-    // some toolbar items we need to update
-    private ToolItem mTBShowThreadUpdates;
-    private ToolItem mTBShowHeapUpdates;
-    private ToolItem mTBHalt;
-    private ToolItem mTBCauseGc;
-    private ToolItem mTBDumpHprof;
-    private ToolItem mTBProfiling;
-
-    private ImageLoader mDdmsImageLoader;
-    private ImageLoader mDdmuiLibImageLoader;
-
-    private final class FilterStorage implements ILogFilterStorageManager {
-
-        public LogFilter[] getFilterFromStore() {
-            String filterPrefs = PrefsDialog.getStore().getString(
-                    PREFS_FILTERS);
-
-            // split in a string per filter
-            String[] filters = filterPrefs.split("\\|"); //$NON-NLS-1$
-
-            ArrayList<LogFilter> list =
-                new ArrayList<LogFilter>(filters.length);
-
-            for (String f : filters) {
-                if (f.length() > 0) {
-                    LogFilter logFilter = new LogFilter();
-                    if (logFilter.loadFromString(f)) {
-                        list.add(logFilter);
-                    }
-                }
-            }
-
-            return list.toArray(new LogFilter[list.size()]);
-        }
-
-        public void saveFilters(LogFilter[] filters) {
-            StringBuilder sb = new StringBuilder();
-            for (LogFilter f : filters) {
-                String filterString = f.toString();
-                sb.append(filterString);
-                sb.append('|');
-            }
-
-            PrefsDialog.getStore().setValue(PREFS_FILTERS, sb.toString());
-        }
-
-        public boolean requiresDefaultFilter() {
-            return true;
-        }
-    }
-
-
-    private LogPanel mLogPanel;
-
-    private ToolItemAction mCreateFilterAction;
-    private ToolItemAction mDeleteFilterAction;
-    private ToolItemAction mEditFilterAction;
-    private ToolItemAction mExportAction;
-    private ToolItemAction mClearAction;
-
-    private ToolItemAction[] mLogLevelActions;
-    private String[] mLogLevelIcons = {
-            "v.png", //$NON-NLS-1S
-            "d.png", //$NON-NLS-1S
-            "i.png", //$NON-NLS-1S
-            "w.png", //$NON-NLS-1S
-            "e.png", //$NON-NLS-1S
-    };
-
-    protected Clipboard mClipboard;
-
-    private MenuItem mCopyMenuItem;
-
-    private MenuItem mSelectAllMenuItem;
-
-    private TableFocusListener mTableListener;
-
-    private DeviceExplorer mExplorer = null;
-    private Shell mExplorerShell = null;
-
-    private EmulatorControlPanel mEmulatorPanel;
-
-    private EventLogPanel mEventLogPanel;
-
-    private Image mTracingStartImage;
-
-    private Image mTracingStopImage;
-
-    private class TableFocusListener implements ITableFocusListener {
-
-        private IFocusedTableActivator mCurrentActivator;
-
-        public void focusGained(IFocusedTableActivator activator) {
-            mCurrentActivator = activator;
-            if (mCopyMenuItem.isDisposed() == false) {
-                mCopyMenuItem.setEnabled(true);
-                mSelectAllMenuItem.setEnabled(true);
-            }
-        }
-
-        public void focusLost(IFocusedTableActivator activator) {
-            // if we move from one table to another, it's unclear
-            // if the old table lose its focus before the new
-            // one gets the focus, so we need to check.
-            if (activator == mCurrentActivator) {
-                activator = null;
-                if (mCopyMenuItem.isDisposed() == false) {
-                    mCopyMenuItem.setEnabled(false);
-                    mSelectAllMenuItem.setEnabled(false);
-                }
-            }
-        }
-
-        public void copy(Clipboard clipboard) {
-            if (mCurrentActivator != null) {
-                mCurrentActivator.copy(clipboard);
-            }
-        }
-
-        public void selectAll() {
-            if (mCurrentActivator != null) {
-                mCurrentActivator.selectAll();
-            }
-        }
-
-    }
-
-    /**
-     * Handler for HPROF dumps.
-     * This will always prompt the user to save the HPROF file.
-     */
-    private class HProfHandler extends BaseFileHandler implements IHprofDumpHandler {
-
-        public HProfHandler(Shell parentShell) {
-            super(parentShell);
-        }
-
-        public void onFailure(final Client client) {
-            mDisplay.asyncExec(new Runnable() {
-                public void run() {
-                    try {
-                        displayError("Unable to create HPROF file for application '%1$s'.\n" +
-                                "Check logcat for more information.",
-                                client.getClientData().getClientDescription());
-                    } finally {
-                        // this will make sure the dump hprof button is re-enabled for the
-                        // current selection. as the client is finished dumping an hprof file
-                        enableButtons();
-                    }
-                }
-            });
-        }
-
-        public void onSuccess(final String remoteFilePath, final Client client) {
-            mDisplay.asyncExec(new Runnable() {
-                public void run() {
-                    final IDevice device = client.getDevice();
-                    try {
-                        // get the sync service to pull the HPROF file
-                        final SyncService sync = client.getDevice().getSyncService();
-                        if (sync != null) {
-                            SyncResult result = promptAndPull(sync,
-                                    client.getClientData().getClientDescription() + ".hprof",
-                                    remoteFilePath, "Save HPROF file");
-                            if (result != null && result.getCode() != SyncService.RESULT_OK) {
-                                displayError(
-                                        "Unable to download HPROF file from device '%1$s'.\n\n%2$s",
-                                        device.getSerialNumber(), result.getMessage());
-                            }
-                        } else {
-                            displayError("Unable to download HPROF file from device '%1$s'.",
-                                    device.getSerialNumber());
-                        }
-                    } catch (Exception e) {
-                        displayError("Unable to download HPROF file from device '%1$s'.",
-                                device.getSerialNumber());
-
-                    } finally {
-                        // this will make sure the dump hprof button is re-enabled for the
-                        // current selection. as the client is finished dumping an hprof file
-                        enableButtons();
-                    }
-                }
-            });
-        }
-
-        private void displayError(String format, Object... args) {
-            MessageDialog.openError(mParentShell, "HPROF Error",
-                    String.format(format, args));
-        }
-    }
-
-
-    /**
-     * Generic constructor.
-     */
-    private UIThread() {
-        mPanels[PANEL_INFO] = new InfoPanel();
-        mPanels[PANEL_THREAD] = new ThreadPanel();
-        mPanels[PANEL_HEAP] = new HeapPanel();
-        if (PrefsDialog.getStore().getBoolean(PrefsDialog.SHOW_NATIVE_HEAP)) {
-            mPanels[PANEL_NATIVE_HEAP] = new NativeHeapPanel();
-        } else {
-            mPanels[PANEL_NATIVE_HEAP] = null;
-        }
-        mPanels[PANEL_ALLOCATIONS] = new AllocationPanel();
-        mPanels[PANEL_SYSINFO] = new SysinfoPanel();
-    }
-
-    /**
-     * Get singleton instance of the UI thread.
-     */
-    public static UIThread getInstance() {
-        return mInstance;
-    }
-
-    /**
-     * Return the Display. Don't try this unless you're in the UI thread.
-     */
-    public Display getDisplay() {
-        return mDisplay;
-    }
-
-    public void asyncExec(Runnable r) {
-        if (mDisplay != null && mDisplay.isDisposed() == false) {
-            mDisplay.asyncExec(r);
-        }
-    }
-
-    /** returns the IPreferenceStore */
-    public IPreferenceStore getStore() {
-        return PrefsDialog.getStore();
-    }
-
-    /**
-     * Create SWT objects and drive the user interface event loop.
-     * @param location location of the folder that contains ddms.
-     */
-    public void runUI(String ddmsParentLocation) {
-        Display.setAppName("ddms");
-        mDisplay = new Display();
-        final Shell shell = new Shell(mDisplay);
-
-        // create the image loaders for DDMS and DDMUILIB
-        mDdmsImageLoader = new ImageLoader(this.getClass());
-        mDdmuiLibImageLoader = new ImageLoader(DevicePanel.class);
-
-        shell.setImage(ImageHelper.loadImage(mDdmsImageLoader, mDisplay,
-                "ddms-icon.png", //$NON-NLS-1$
-                100, 50, null));
-
-        Log.setLogOutput(new ILogOutput() {
-            public void printAndPromptLog(final LogLevel logLevel, final String tag,
-                    final String message) {
-                Log.printLog(logLevel, tag, message);
-                // dialog box only run in UI thread..
-                mDisplay.asyncExec(new Runnable() {
-                    public void run() {
-                        Shell shell = mDisplay.getActiveShell();
-                        if (logLevel == LogLevel.ERROR) {
-                            MessageDialog.openError(shell, tag, message);
-                        } else {
-                            MessageDialog.openWarning(shell, tag, message);
-                        }
-                    }
-                });
-            }
-
-            public void printLog(LogLevel logLevel, String tag, String message) {
-                Log.printLog(logLevel, tag, message);
-            }
-        });
-
-        // set the handler for hprof dump
-        ClientData.setHprofDumpHandler(new HProfHandler(shell));
-        ClientData.setMethodProfilingHandler(new MethodProfilingHandler(shell));
-
-        // [try to] ensure ADB is running
-        String adbLocation;
-        if (ddmsParentLocation != null && ddmsParentLocation.length() != 0) {
-            adbLocation = ddmsParentLocation + File.separator + "adb"; //$NON-NLS-1$
-        } else {
-            adbLocation = "adb"; //$NON-NLS-1$
-        }
-
-        AndroidDebugBridge.init(true /* debugger support */);
-        AndroidDebugBridge.createBridge(adbLocation, true /* forceNewBridge */);
-
-        // we need to listen to client change to be notified of client status (profiling) change
-        AndroidDebugBridge.addClientChangeListener(this);
-
-        shell.setText("Dalvik Debug Monitor");
-        setConfirmClose(shell);
-        createMenus(shell);
-        createWidgets(shell);
-
-        shell.pack();
-        setSizeAndPosition(shell);
-        shell.open();
-
-        Log.d("ddms", "UI is up");
-
-        while (!shell.isDisposed()) {
-            if (!mDisplay.readAndDispatch())
-                mDisplay.sleep();
-        }
-        mLogPanel.stopLogCat(true);
-
-        mDevicePanel.dispose();
-        for (TablePanel panel : mPanels) {
-            if (panel != null) {
-                panel.dispose();
-            }
-        }
-
-        mDisplay.dispose();
-        Log.d("ddms", "UI is down");
-    }
-
-    /**
-     * Set the size and position of the main window from the preference, and
-     * setup listeners for control events (resize/move of the window)
-     */
-    private void setSizeAndPosition(final Shell shell) {
-        shell.setMinimumSize(400, 200);
-
-        // get the x/y and w/h from the prefs
-        PreferenceStore prefs = PrefsDialog.getStore();
-        int x = prefs.getInt(PrefsDialog.SHELL_X);
-        int y = prefs.getInt(PrefsDialog.SHELL_Y);
-        int w = prefs.getInt(PrefsDialog.SHELL_WIDTH);
-        int h = prefs.getInt(PrefsDialog.SHELL_HEIGHT);
-
-        // check that we're not out of the display area
-        Rectangle rect = mDisplay.getClientArea();
-        // first check the width/height
-        if (w > rect.width) {
-            w = rect.width;
-            prefs.setValue(PrefsDialog.SHELL_WIDTH, rect.width);
-        }
-        if (h > rect.height) {
-            h = rect.height;
-            prefs.setValue(PrefsDialog.SHELL_HEIGHT, rect.height);
-        }
-        // then check x. Make sure the left corner is in the screen
-        if (x < rect.x) {
-            x = rect.x;
-            prefs.setValue(PrefsDialog.SHELL_X, rect.x);
-        } else if (x >= rect.x + rect.width) {
-            x = rect.x + rect.width - w;
-            prefs.setValue(PrefsDialog.SHELL_X, rect.x);
-        }
-        // then check y. Make sure the left corner is in the screen
-        if (y < rect.y) {
-            y = rect.y;
-            prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
-        } else if (y >= rect.y + rect.height) {
-            y = rect.y + rect.height - h;
-            prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
-        }
-
-        // now we can set the location/size
-        shell.setBounds(x, y, w, h);
-
-        // add listener for resize/move
-        shell.addControlListener(new ControlListener() {
-            public void controlMoved(ControlEvent e) {
-                // get the new x/y
-                Rectangle rect = shell.getBounds();
-                // store in pref file
-                PreferenceStore prefs = PrefsDialog.getStore();
-                prefs.setValue(PrefsDialog.SHELL_X, rect.x);
-                prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
-            }
-
-            public void controlResized(ControlEvent e) {
-                // get the new w/h
-                Rectangle rect = shell.getBounds();
-                // store in pref file
-                PreferenceStore prefs = PrefsDialog.getStore();
-                prefs.setValue(PrefsDialog.SHELL_WIDTH, rect.width);
-                prefs.setValue(PrefsDialog.SHELL_HEIGHT, rect.height);
-            }
-        });
-    }
-
-    /**
-     * Set the size and position of the file explorer window from the
-     * preference, and setup listeners for control events (resize/move of
-     * the window)
-     */
-    private void setExplorerSizeAndPosition(final Shell shell) {
-        shell.setMinimumSize(400, 200);
-
-        // get the x/y and w/h from the prefs
-        PreferenceStore prefs = PrefsDialog.getStore();
-        int x = prefs.getInt(PrefsDialog.EXPLORER_SHELL_X);
-        int y = prefs.getInt(PrefsDialog.EXPLORER_SHELL_Y);
-        int w = prefs.getInt(PrefsDialog.EXPLORER_SHELL_WIDTH);
-        int h = prefs.getInt(PrefsDialog.EXPLORER_SHELL_HEIGHT);
-
-        // check that we're not out of the display area
-        Rectangle rect = mDisplay.getClientArea();
-        // first check the width/height
-        if (w > rect.width) {
-            w = rect.width;
-            prefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, rect.width);
-        }
-        if (h > rect.height) {
-            h = rect.height;
-            prefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, rect.height);
-        }
-        // then check x. Make sure the left corner is in the screen
-        if (x < rect.x) {
-            x = rect.x;
-            prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
-        } else if (x >= rect.x + rect.width) {
-            x = rect.x + rect.width - w;
-            prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
-        }
-        // then check y. Make sure the left corner is in the screen
-        if (y < rect.y) {
-            y = rect.y;
-            prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
-        } else if (y >= rect.y + rect.height) {
-            y = rect.y + rect.height - h;
-            prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
-        }
-
-        // now we can set the location/size
-        shell.setBounds(x, y, w, h);
-
-        // add listener for resize/move
-        shell.addControlListener(new ControlListener() {
-            public void controlMoved(ControlEvent e) {
-                // get the new x/y
-                Rectangle rect = shell.getBounds();
-                // store in pref file
-                PreferenceStore prefs = PrefsDialog.getStore();
-                prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
-                prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
-            }
-
-            public void controlResized(ControlEvent e) {
-                // get the new w/h
-                Rectangle rect = shell.getBounds();
-                // store in pref file
-                PreferenceStore prefs = PrefsDialog.getStore();
-                prefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, rect.width);
-                prefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, rect.height);
-            }
-        });
-    }
-
-    /*
-     * Set the confirm-before-close dialog. TODO: enable/disable in prefs. TODO:
-     * is there any point in having this?
-     */
-    private void setConfirmClose(final Shell shell) {
-        if (true)
-            return;
-
-        shell.addListener(SWT.Close, new Listener() {
-            public void handleEvent(Event event) {
-                int style = SWT.APPLICATION_MODAL | SWT.YES | SWT.NO;
-                MessageBox msgBox = new MessageBox(shell, style);
-                msgBox.setText("Confirm...");
-                msgBox.setMessage("Close DDM?");
-                event.doit = (msgBox.open() == SWT.YES);
-            }
-        });
-    }
-
-    /*
-     * Create the menu bar and items.
-     */
-    private void createMenus(final Shell shell) {
-        // create menu bar
-        Menu menuBar = new Menu(shell, SWT.BAR);
-
-        // create top-level items
-        MenuItem fileItem = new MenuItem(menuBar, SWT.CASCADE);
-        fileItem.setText("&File");
-        MenuItem editItem = new MenuItem(menuBar, SWT.CASCADE);
-        editItem.setText("&Edit");
-        MenuItem actionItem = new MenuItem(menuBar, SWT.CASCADE);
-        actionItem.setText("&Actions");
-        MenuItem deviceItem = new MenuItem(menuBar, SWT.CASCADE);
-        deviceItem.setText("&Device");
-        MenuItem helpItem = new MenuItem(menuBar, SWT.CASCADE);
-        helpItem.setText("&Help");
-
-        // create top-level menus
-        Menu fileMenu = new Menu(menuBar);
-        fileItem.setMenu(fileMenu);
-        Menu editMenu = new Menu(menuBar);
-        editItem.setMenu(editMenu);
-        Menu actionMenu = new Menu(menuBar);
-        actionItem.setMenu(actionMenu);
-        Menu deviceMenu = new Menu(menuBar);
-        deviceItem.setMenu(deviceMenu);
-        Menu helpMenu = new Menu(menuBar);
-        helpItem.setMenu(helpMenu);
-
-        MenuItem item;
-
-        // create File menu items
-        item = new MenuItem(fileMenu, SWT.NONE);
-        item.setText("&Preferences...");
-        item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                PrefsDialog.run(shell);
-            }
-        });
-
-        item = new MenuItem(fileMenu, SWT.NONE);
-        item.setText("&Static Port Configuration...");
-        item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                StaticPortConfigDialog dlg = new StaticPortConfigDialog(shell);
-                dlg.open();
-            }
-        });
-
-        new MenuItem(fileMenu, SWT.SEPARATOR);
-
-        item = new MenuItem(fileMenu, SWT.NONE);
-        item.setText("E&xit\tCtrl-Q");
-        item.setAccelerator('Q' | SWT.CONTROL);
-        item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                shell.close();
-            }
-        });
-
-        // create edit menu items
-        mCopyMenuItem = new MenuItem(editMenu, SWT.NONE);
-        mCopyMenuItem.setText("&Copy\tCtrl-C");
-        mCopyMenuItem.setAccelerator('C' | SWT.COMMAND);
-        mCopyMenuItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mTableListener.copy(mClipboard);
-            }
-        });
-
-        new MenuItem(editMenu, SWT.SEPARATOR);
-
-        mSelectAllMenuItem = new MenuItem(editMenu, SWT.NONE);
-        mSelectAllMenuItem.setText("Select &All\tCtrl-A");
-        mSelectAllMenuItem.setAccelerator('A' | SWT.COMMAND);
-        mSelectAllMenuItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mTableListener.selectAll();
-            }
-        });
-
-        // create Action menu items
-        // TODO: this should come with a confirmation dialog
-        final MenuItem actionHaltItem = new MenuItem(actionMenu, SWT.NONE);
-        actionHaltItem.setText("&Halt VM");
-        actionHaltItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mDevicePanel.killSelectedClient();
-            }
-        });
-
-        final MenuItem actionCauseGcItem = new MenuItem(actionMenu, SWT.NONE);
-        actionCauseGcItem.setText("Cause &GC");
-        actionCauseGcItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mDevicePanel.forceGcOnSelectedClient();
-            }
-        });
-
-        // configure Action items based on current state
-        actionMenu.addMenuListener(new MenuAdapter() {
-            @Override
-            public void menuShown(MenuEvent e) {
-                actionHaltItem.setEnabled(mTBHalt.getEnabled() && mCurrentClient != null);
-                actionCauseGcItem.setEnabled(mTBCauseGc.getEnabled() && mCurrentClient != null);
-            }
-        });
-
-        // create Device menu items
-        final MenuItem screenShotItem = new MenuItem(deviceMenu, SWT.NONE);
-        screenShotItem.setText("&Screen capture...\tCTrl-S");
-        screenShotItem.setAccelerator('S' | SWT.CONTROL);
-        screenShotItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mCurrentDevice != null) {
-                    ScreenShotDialog dlg = new ScreenShotDialog(shell);
-                    dlg.open(mCurrentDevice);
-                }
-            }
-        });
-
-        new MenuItem(deviceMenu, SWT.SEPARATOR);
-
-        final MenuItem explorerItem = new MenuItem(deviceMenu, SWT.NONE);
-        explorerItem.setText("File Explorer...");
-        explorerItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                createFileExplorer();
-            }
-        });
-
-        new MenuItem(deviceMenu, SWT.SEPARATOR);
-
-        final MenuItem processItem = new MenuItem(deviceMenu, SWT.NONE);
-        processItem.setText("Show &process status...");
-        processItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceCommandDialog dlg;
-                dlg = new DeviceCommandDialog("ps -x", "ps-x.txt", shell);
-                dlg.open(mCurrentDevice);
-            }
-        });
-
-        final MenuItem deviceStateItem = new MenuItem(deviceMenu, SWT.NONE);
-        deviceStateItem.setText("Dump &device state...");
-        deviceStateItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceCommandDialog dlg;
-                dlg = new DeviceCommandDialog("/system/bin/dumpstate /proc/self/fd/0",
-                        "device-state.txt", shell);
-                dlg.open(mCurrentDevice);
-            }
-        });
-
-        final MenuItem appStateItem = new MenuItem(deviceMenu, SWT.NONE);
-        appStateItem.setText("Dump &app state...");
-        appStateItem.setEnabled(false);
-        appStateItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceCommandDialog dlg;
-                dlg = new DeviceCommandDialog("dumpsys", "app-state.txt", shell);
-                dlg.open(mCurrentDevice);
-            }
-        });
-
-        final MenuItem radioStateItem = new MenuItem(deviceMenu, SWT.NONE);
-        radioStateItem.setText("Dump &radio state...");
-        radioStateItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceCommandDialog dlg;
-                dlg = new DeviceCommandDialog(
-                        "cat /data/logs/radio.4 /data/logs/radio.3"
-                        + " /data/logs/radio.2 /data/logs/radio.1"
-                        + " /data/logs/radio",
-                        "radio-state.txt", shell);
-                dlg.open(mCurrentDevice);
-            }
-        });
-
-        final MenuItem logCatItem = new MenuItem(deviceMenu, SWT.NONE);
-        logCatItem.setText("Run &logcat...");
-        logCatItem.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceCommandDialog dlg;
-                dlg = new DeviceCommandDialog("logcat '*:d jdwp:w'", "log.txt",
-                        shell);
-                dlg.open(mCurrentDevice);
-            }
-        });
-
-        // configure Action items based on current state
-        deviceMenu.addMenuListener(new MenuAdapter() {
-            @Override
-            public void menuShown(MenuEvent e) {
-                boolean deviceEnabled = mCurrentDevice != null;
-                screenShotItem.setEnabled(deviceEnabled);
-                explorerItem.setEnabled(deviceEnabled);
-                processItem.setEnabled(deviceEnabled);
-                deviceStateItem.setEnabled(deviceEnabled);
-                appStateItem.setEnabled(deviceEnabled);
-                radioStateItem.setEnabled(deviceEnabled);
-                logCatItem.setEnabled(deviceEnabled);
-            }
-        });
-
-        // create Help menu items
-        item = new MenuItem(helpMenu, SWT.NONE);
-        item.setText("&Contents...");
-        item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                int style = SWT.APPLICATION_MODAL | SWT.OK;
-                MessageBox msgBox = new MessageBox(shell, style);
-                msgBox.setText("Help!");
-                msgBox.setMessage("Help wanted.");
-                msgBox.open();
-            }
-        });
-
-        new MenuItem(helpMenu, SWT.SEPARATOR);
-
-        item = new MenuItem(helpMenu, SWT.NONE);
-        item.setText("&About...");
-        item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                AboutDialog dlg = new AboutDialog(shell);
-                dlg.open();
-            }
-        });
-
-        // tell the shell to use this menu
-        shell.setMenuBar(menuBar);
-    }
-
-    /*
-     * Create the widgets in the main application window. The basic layout is a
-     * two-panel sash, with a scrolling list of VMs on the left and detailed
-     * output for a single VM on the right.
-     */
-    private void createWidgets(final Shell shell) {
-        Color darkGray = shell.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
-
-        /*
-         * Create three areas: tool bar, split panels, status line
-         */
-        shell.setLayout(new GridLayout(1, false));
-
-        // 1. panel area
-        final Composite panelArea = new Composite(shell, SWT.BORDER);
-
-        // make the panel area absorb all space
-        panelArea.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        // 2. status line.
-        mStatusLine = new Label(shell, SWT.NONE);
-
-        // make status line extend all the way across
-        mStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mStatusLine.setText("Initializing...");
-
-        /*
-         * Configure the split-panel area.
-         */
-        final PreferenceStore prefs = PrefsDialog.getStore();
-
-        Composite topPanel = new Composite(panelArea, SWT.NONE);
-        final Sash sash = new Sash(panelArea, SWT.HORIZONTAL);
-        sash.setBackground(darkGray);
-        Composite bottomPanel = new Composite(panelArea, SWT.NONE);
-
-        panelArea.setLayout(new FormLayout());
-
-        createTopPanel(topPanel, darkGray);
-        createBottomPanel(bottomPanel);
-
-        // form layout data
-        FormData data = new FormData();
-        data.top = new FormAttachment(0, 0);
-        data.bottom = new FormAttachment(sash, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        topPanel.setLayoutData(data);
-
-        final FormData sashData = new FormData();
-        if (prefs != null && prefs.contains(PREFERENCE_LOGSASH)) {
-            sashData.top = new FormAttachment(0, prefs.getInt(
-                    PREFERENCE_LOGSASH));
-        } else {
-            sashData.top = new FormAttachment(50,0); // 50% across
-        }
-        sashData.left = new FormAttachment(0, 0);
-        sashData.right = new FormAttachment(100, 0);
-        sash.setLayoutData(sashData);
-
-        data = new FormData();
-        data.top = new FormAttachment(sash, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        bottomPanel.setLayoutData(data);
-
-        // allow resizes, but cap at minPanelWidth
-        sash.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                Rectangle sashRect = sash.getBounds();
-                Rectangle panelRect = panelArea.getClientArea();
-                int bottom = panelRect.height - sashRect.height - 100;
-                e.y = Math.max(Math.min(e.y, bottom), 100);
-                if (e.y != sashRect.y) {
-                    sashData.top = new FormAttachment(0, e.y);
-                    prefs.setValue(PREFERENCE_LOGSASH, e.y);
-                    panelArea.layout();
-                }
-            }
-        });
-
-        // add a global focus listener for all the tables
-        mTableListener = new TableFocusListener();
-
-        // now set up the listener in the various panels
-        mLogPanel.setTableFocusListener(mTableListener);
-        mEventLogPanel.setTableFocusListener(mTableListener);
-        for (TablePanel p : mPanels) {
-            if (p != null) {
-                p.setTableFocusListener(mTableListener);
-            }
-        }
-
-        mStatusLine.setText("");
-    }
-
-    /*
-     * Populate the tool bar.
-     */
-    private void createDevicePanelToolBar(ToolBar toolBar) {
-        Display display = toolBar.getDisplay();
-
-        // add "show heap updates" button
-        mTBShowHeapUpdates = new ToolItem(toolBar, SWT.CHECK);
-        mTBShowHeapUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
-                DevicePanel.ICON_HEAP, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mTBShowHeapUpdates.setToolTipText("Show heap updates");
-        mTBShowHeapUpdates.setEnabled(false);
-        mTBShowHeapUpdates.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mCurrentClient != null) {
-                    // boolean status = ((ToolItem)e.item).getSelection();
-                    // invert previous state
-                    boolean enable = !mCurrentClient.isHeapUpdateEnabled();
-                    mCurrentClient.setHeapUpdateEnabled(enable);
-                } else {
-                    e.doit = false; // this has no effect?
-                }
-            }
-        });
-
-        // add "dump HPROF" button
-        mTBDumpHprof = new ToolItem(toolBar, SWT.PUSH);
-        mTBDumpHprof.setToolTipText("Dump HPROF file");
-        mTBDumpHprof.setEnabled(false);
-        mTBDumpHprof.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
-                DevicePanel.ICON_HPROF, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mTBDumpHprof.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mDevicePanel.dumpHprof();
-
-                // this will make sure the dump hprof button is disabled for the current selection
-                // as the client is already dumping an hprof file
-                enableButtons();
-            }
-        });
-
-        // add "cause GC" button
-        mTBCauseGc = new ToolItem(toolBar, SWT.PUSH);
-        mTBCauseGc.setToolTipText("Cause an immediate GC");
-        mTBCauseGc.setEnabled(false);
-        mTBCauseGc.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
-                DevicePanel.ICON_GC, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mTBCauseGc.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mDevicePanel.forceGcOnSelectedClient();
-            }
-        });
-
-        new ToolItem(toolBar, SWT.SEPARATOR);
-
-        // add "show thread updates" button
-        mTBShowThreadUpdates = new ToolItem(toolBar, SWT.CHECK);
-        mTBShowThreadUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
-                DevicePanel.ICON_THREAD, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mTBShowThreadUpdates.setToolTipText("Show thread updates");
-        mTBShowThreadUpdates.setEnabled(false);
-        mTBShowThreadUpdates.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mCurrentClient != null) {
-                    // boolean status = ((ToolItem)e.item).getSelection();
-                    // invert previous state
-                    boolean enable = !mCurrentClient.isThreadUpdateEnabled();
-
-                    mCurrentClient.setThreadUpdateEnabled(enable);
-                } else {
-                    e.doit = false; // this has no effect?
-                }
-            }
-        });
-
-        // add a start/stop method tracing
-        mTracingStartImage = ImageHelper.loadImage(mDdmuiLibImageLoader, display,
-                DevicePanel.ICON_TRACING_START,
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null);
-        mTracingStopImage = ImageHelper.loadImage(mDdmuiLibImageLoader, display,
-                DevicePanel.ICON_TRACING_STOP,
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null);
-        mTBProfiling = new ToolItem(toolBar, SWT.PUSH);
-        mTBProfiling.setToolTipText("Start Method Profiling");
-        mTBProfiling.setEnabled(false);
-        mTBProfiling.setImage(mTracingStartImage);
-        mTBProfiling.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mDevicePanel.toggleMethodProfiling();
-            }
-        });
-
-        new ToolItem(toolBar, SWT.SEPARATOR);
-
-        // add "kill VM" button; need to make this visually distinct from
-        // the status update buttons
-        mTBHalt = new ToolItem(toolBar, SWT.PUSH);
-        mTBHalt.setToolTipText("Halt the target VM");
-        mTBHalt.setEnabled(false);
-        mTBHalt.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
-                DevicePanel.ICON_HALT, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mTBHalt.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mDevicePanel.killSelectedClient();
-            }
-        });
-
-       toolBar.pack();
-    }
-
-    private void createTopPanel(final Composite comp, Color darkGray) {
-        final PreferenceStore prefs = PrefsDialog.getStore();
-
-        comp.setLayout(new FormLayout());
-
-        Composite leftPanel = new Composite(comp, SWT.NONE);
-        final Sash sash = new Sash(comp, SWT.VERTICAL);
-        sash.setBackground(darkGray);
-        Composite rightPanel = new Composite(comp, SWT.NONE);
-
-        createLeftPanel(leftPanel);
-        createRightPanel(rightPanel);
-
-        FormData data = new FormData();
-        data.top = new FormAttachment(0, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(sash, 0);
-        leftPanel.setLayoutData(data);
-
-        final FormData sashData = new FormData();
-        sashData.top = new FormAttachment(0, 0);
-        sashData.bottom = new FormAttachment(100, 0);
-        if (prefs != null && prefs.contains(PREFERENCE_SASH)) {
-            sashData.left = new FormAttachment(0, prefs.getInt(
-                    PREFERENCE_SASH));
-        } else {
-            // position the sash 380 from the right instead of x% (done by using
-            // FormAttachment(x, 0)) in order to keep the sash at the same
-            // position
-            // from the left when the window is resized.
-            // 380px is just enough to display the left table with no horizontal
-            // scrollbar with the default font.
-            sashData.left = new FormAttachment(0, 380);
-        }
-        sash.setLayoutData(sashData);
-
-        data = new FormData();
-        data.top = new FormAttachment(0, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(sash, 0);
-        data.right = new FormAttachment(100, 0);
-        rightPanel.setLayoutData(data);
-
-        final int minPanelWidth = 60;
-
-        // allow resizes, but cap at minPanelWidth
-        sash.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                Rectangle sashRect = sash.getBounds();
-                Rectangle panelRect = comp.getClientArea();
-                int right = panelRect.width - sashRect.width - minPanelWidth;
-                e.x = Math.max(Math.min(e.x, right), minPanelWidth);
-                if (e.x != sashRect.x) {
-                    sashData.left = new FormAttachment(0, e.x);
-                    prefs.setValue(PREFERENCE_SASH, e.x);
-                    comp.layout();
-                }
-            }
-        });
-    }
-
-    private void createBottomPanel(final Composite comp) {
-        final PreferenceStore prefs = PrefsDialog.getStore();
-
-        // create clipboard
-        Display display = comp.getDisplay();
-        mClipboard = new Clipboard(display);
-
-        LogColors colors = new LogColors();
-
-        colors.infoColor = new Color(display, 0, 127, 0);
-        colors.debugColor = new Color(display, 0, 0, 127);
-        colors.errorColor = new Color(display, 255, 0, 0);
-        colors.warningColor = new Color(display, 255, 127, 0);
-        colors.verboseColor = new Color(display, 0, 0, 0);
-
-        // set the preferences names
-        LogPanel.PREFS_TIME = PREFS_COL_TIME;
-        LogPanel.PREFS_LEVEL = PREFS_COL_LEVEL;
-        LogPanel.PREFS_PID = PREFS_COL_PID;
-        LogPanel.PREFS_TAG = PREFS_COL_TAG;
-        LogPanel.PREFS_MESSAGE = PREFS_COL_MESSAGE;
-
-        comp.setLayout(new GridLayout(1, false));
-
-        ToolBar toolBar = new ToolBar(comp, SWT.HORIZONTAL);
-
-        mCreateFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
-        mCreateFilterAction.item.setToolTipText("Create Filter");
-        mCreateFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
-                "add.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mCreateFilterAction.item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mLogPanel.addFilter();
-            }
-        });
-
-        mEditFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
-        mEditFilterAction.item.setToolTipText("Edit Filter");
-        mEditFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
-                "edit.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mEditFilterAction.item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mLogPanel.editFilter();
-            }
-        });
-
-        mDeleteFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
-        mDeleteFilterAction.item.setToolTipText("Delete Filter");
-        mDeleteFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
-                "delete.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mDeleteFilterAction.item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mLogPanel.deleteFilter();
-            }
-        });
-
-
-        new ToolItem(toolBar, SWT.SEPARATOR);
-
-        LogLevel[] levels = LogLevel.values();
-        mLogLevelActions = new ToolItemAction[mLogLevelIcons.length];
-        for (int i = 0 ; i < mLogLevelActions.length; i++) {
-            String name = levels[i].getStringValue();
-            final ToolItemAction newAction = new ToolItemAction(toolBar, SWT.CHECK);
-            mLogLevelActions[i] = newAction;
-            //newAction.item.setText(name);
-            newAction.item.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    // disable the other actions and record current index
-                    for (int i = 0 ; i < mLogLevelActions.length; i++) {
-                        ToolItemAction a = mLogLevelActions[i];
-                        if (a == newAction) {
-                            a.setChecked(true);
-
-                            // set the log level
-                            mLogPanel.setCurrentFilterLogLevel(i+2);
-                        } else {
-                            a.setChecked(false);
-                        }
-                    }
-                }
-            });
-
-            newAction.item.setToolTipText(name);
-            newAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
-                    mLogLevelIcons[i],
-                    DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        }
-
-        new ToolItem(toolBar, SWT.SEPARATOR);
-
-        mClearAction = new ToolItemAction(toolBar, SWT.PUSH);
-        mClearAction.item.setToolTipText("Clear Log");
-
-        mClearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
-                "clear.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mClearAction.item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mLogPanel.clear();
-            }
-        });
-
-        new ToolItem(toolBar, SWT.SEPARATOR);
-
-        mExportAction = new ToolItemAction(toolBar, SWT.PUSH);
-        mExportAction.item.setToolTipText("Export Selection As Text...");
-        mExportAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
-                "save.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-        mExportAction.item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mLogPanel.save();
-            }
-        });
-
-
-        toolBar.pack();
-
-        // now create the log view
-        mLogPanel = new LogPanel(new ImageLoader(LogPanel.class), colors, new FilterStorage(),
-                LogPanel.FILTER_MANUAL);
-
-        mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
-
-        String colMode = prefs.getString(PrefsDialog.LOGCAT_COLUMN_MODE);
-        if (PrefsDialog.LOGCAT_COLUMN_MODE_AUTO.equals(colMode)) {
-            mLogPanel.setColumnMode(LogPanel.COLUMN_MODE_AUTO);
-        }
-
-        String fontStr = PrefsDialog.getStore().getString(PrefsDialog.LOGCAT_FONT);
-        if (fontStr != null) {
-            try {
-                FontData fdat = new FontData(fontStr);
-                mLogPanel.setFont(new Font(display, fdat));
-            } catch (IllegalArgumentException e) {
-                // Looks like fontStr isn't a valid font representation.
-                // We do nothing in this case, the logcat view will use the default font.
-            } catch (SWTError e2) {
-                // Looks like the Font() constructor failed.
-                // We do nothing in this case, the logcat view will use the default font.
-            }
-        }
-
-        mLogPanel.createPanel(comp);
-
-        // and start the logcat
-        mLogPanel.startLogCat(mCurrentDevice);
-    }
-
-    /*
-     * Create the contents of the left panel: a table of VMs.
-     */
-    private void createLeftPanel(final Composite comp) {
-        comp.setLayout(new GridLayout(1, false));
-        ToolBar toolBar = new ToolBar(comp, SWT.HORIZONTAL | SWT.RIGHT | SWT.WRAP);
-        toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        createDevicePanelToolBar(toolBar);
-
-        Composite c = new Composite(comp, SWT.NONE);
-        c.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        mDevicePanel = new DevicePanel(new ImageLoader(DevicePanel.class), true /* showPorts */);
-        mDevicePanel.createPanel(c);
-
-        // add ourselves to the device panel selection listener
-        mDevicePanel.addSelectionListener(this);
-    }
-
-    /*
-     * Create the contents of the right panel: tabs with VM information.
-     */
-    private void createRightPanel(final Composite comp) {
-        TabItem item;
-        TabFolder tabFolder;
-
-        comp.setLayout(new FillLayout());
-
-        tabFolder = new TabFolder(comp, SWT.NONE);
-
-        for (int i = 0; i < mPanels.length; i++) {
-            if (mPanels[i] != null) {
-                item = new TabItem(tabFolder, SWT.NONE);
-                item.setText(mPanelNames[i]);
-                item.setToolTipText(mPanelTips[i]);
-                item.setControl(mPanels[i].createPanel(tabFolder));
-            }
-        }
-
-        // add the emulator control panel to the folders.
-        item = new TabItem(tabFolder, SWT.NONE);
-        item.setText("Emulator Control");
-        item.setToolTipText("Emulator Control Panel");
-        mEmulatorPanel = new EmulatorControlPanel(mDdmuiLibImageLoader);
-        item.setControl(mEmulatorPanel.createPanel(tabFolder));
-
-        // add the event log panel to the folders.
-        item = new TabItem(tabFolder, SWT.NONE);
-        item.setText("Event Log");
-        item.setToolTipText("Event Log");
-
-        // create the composite that will hold the toolbar and the event log panel.
-        Composite eventLogTopComposite = new Composite(tabFolder, SWT.NONE);
-        item.setControl(eventLogTopComposite);
-        eventLogTopComposite.setLayout(new GridLayout(1, false));
-
-        // create the toolbar and the actions
-        ToolBar toolbar = new ToolBar(eventLogTopComposite, SWT.HORIZONTAL);
-        toolbar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        ToolItemAction optionsAction = new ToolItemAction(toolbar, SWT.PUSH);
-        optionsAction.item.setToolTipText("Opens the options panel");
-        optionsAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
-                "edit.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-
-        ToolItemAction clearAction = new ToolItemAction(toolbar, SWT.PUSH);
-        clearAction.item.setToolTipText("Clears the event log");
-        clearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
-                "clear.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-
-        new ToolItem(toolbar, SWT.SEPARATOR);
-
-        ToolItemAction saveAction = new ToolItemAction(toolbar, SWT.PUSH);
-        saveAction.item.setToolTipText("Saves the event log");
-        saveAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
-                "save.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-
-        ToolItemAction loadAction = new ToolItemAction(toolbar, SWT.PUSH);
-        loadAction.item.setToolTipText("Loads an event log");
-        loadAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
-                "load.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-
-        ToolItemAction importBugAction = new ToolItemAction(toolbar, SWT.PUSH);
-        importBugAction.item.setToolTipText("Imports a bug report");
-        importBugAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
-                "importBug.png", //$NON-NLS-1$
-                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
-
-        // create the event log panel
-        mEventLogPanel = new EventLogPanel(mDdmuiLibImageLoader);
-
-        // set the external actions
-        mEventLogPanel.setActions(optionsAction, clearAction, saveAction, loadAction,
-                importBugAction);
-
-        // create the panel
-        mEventLogPanel.createPanel(eventLogTopComposite);
-    }
-
-    private void createFileExplorer() {
-        if (mExplorer == null) {
-            mExplorerShell = new Shell(mDisplay);
-
-            // create the ui
-            mExplorerShell.setLayout(new GridLayout(1, false));
-
-            // toolbar + action
-            ToolBar toolBar = new ToolBar(mExplorerShell, SWT.HORIZONTAL);
-            toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-            ToolItemAction pullAction = new ToolItemAction(toolBar, SWT.PUSH);
-            pullAction.item.setToolTipText("Pull File from Device");
-            Image image = mDdmuiLibImageLoader.loadImage("pull.png", mDisplay); //$NON-NLS-1$
-            if (image != null) {
-                pullAction.item.setImage(image);
-            } else {
-                // this is for debugging purpose when the icon is missing
-                pullAction.item.setText("Pull"); //$NON-NLS-1$
-            }
-
-            ToolItemAction pushAction = new ToolItemAction(toolBar, SWT.PUSH);
-            pushAction.item.setToolTipText("Push file onto Device");
-            image = mDdmuiLibImageLoader.loadImage("push.png", mDisplay); //$NON-NLS-1$
-            if (image != null) {
-                pushAction.item.setImage(image);
-            } else {
-                // this is for debugging purpose when the icon is missing
-                pushAction.item.setText("Push"); //$NON-NLS-1$
-            }
-
-            ToolItemAction deleteAction = new ToolItemAction(toolBar, SWT.PUSH);
-            deleteAction.item.setToolTipText("Delete");
-            image = mDdmuiLibImageLoader.loadImage("delete.png", mDisplay); //$NON-NLS-1$
-            if (image != null) {
-                deleteAction.item.setImage(image);
-            } else {
-                // this is for debugging purpose when the icon is missing
-                deleteAction.item.setText("Delete"); //$NON-NLS-1$
-            }
-
-            // device explorer
-            mExplorer = new DeviceExplorer();
-
-            mExplorer.setImages(mDdmuiLibImageLoader.loadImage("file.png", mDisplay), //$NON-NLS-1$
-                    mDdmuiLibImageLoader.loadImage("folder.png", mDisplay), //$NON-NLS-1$
-                    mDdmuiLibImageLoader.loadImage("android.png", mDisplay), //$NON-NLS-1$
-                    null);
-            mExplorer.setActions(pushAction, pullAction, deleteAction);
-
-            pullAction.item.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    mExplorer.pullSelection();
-                }
-            });
-            pullAction.setEnabled(false);
-
-            pushAction.item.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    mExplorer.pushIntoSelection();
-                }
-            });
-            pushAction.setEnabled(false);
-
-            deleteAction.item.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    mExplorer.deleteSelection();
-                }
-            });
-            deleteAction.setEnabled(false);
-
-            Composite parent = new Composite(mExplorerShell, SWT.NONE);
-            parent.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-            mExplorer.createPanel(parent);
-            mExplorer.switchDevice(mCurrentDevice);
-
-            mExplorerShell.addShellListener(new ShellListener() {
-                public void shellActivated(ShellEvent e) {
-                    // pass
-                }
-
-                public void shellClosed(ShellEvent e) {
-                    mExplorer = null;
-                    mExplorerShell = null;
-                }
-
-                public void shellDeactivated(ShellEvent e) {
-                    // pass
-                }
-
-                public void shellDeiconified(ShellEvent e) {
-                    // pass
-                }
-
-                public void shellIconified(ShellEvent e) {
-                    // pass
-                }
-            });
-
-            mExplorerShell.pack();
-            setExplorerSizeAndPosition(mExplorerShell);
-            mExplorerShell.open();
-        } else {
-            if (mExplorerShell != null) {
-                mExplorerShell.forceActive();
-            }
-        }
-    }
-
-    /**
-     * Set the status line. TODO: make this a stack, so we can safely have
-     * multiple things trying to set it all at once. Also specify an expiration?
-     */
-    public void setStatusLine(final String str) {
-        try {
-            mDisplay.asyncExec(new Runnable() {
-                public void run() {
-                    doSetStatusLine(str);
-                }
-            });
-        } catch (SWTException swte) {
-            if (!mDisplay.isDisposed())
-                throw swte;
-        }
-    }
-
-    private void doSetStatusLine(String str) {
-        if (mStatusLine.isDisposed())
-            return;
-
-        if (!mStatusLine.getText().equals(str)) {
-            mStatusLine.setText(str);
-
-            // try { Thread.sleep(100); }
-            // catch (InterruptedException ie) {}
-        }
-    }
-
-    public void displayError(final String msg) {
-        try {
-            mDisplay.syncExec(new Runnable() {
-                public void run() {
-                    MessageDialog.openError(mDisplay.getActiveShell(), "Error",
-                            msg);
-                }
-            });
-        } catch (SWTException swte) {
-            if (!mDisplay.isDisposed())
-                throw swte;
-        }
-    }
-
-    private void enableButtons() {
-        if (mCurrentClient != null) {
-            mTBShowThreadUpdates.setSelection(mCurrentClient.isThreadUpdateEnabled());
-            mTBShowThreadUpdates.setEnabled(true);
-            mTBShowHeapUpdates.setSelection(mCurrentClient.isHeapUpdateEnabled());
-            mTBShowHeapUpdates.setEnabled(true);
-            mTBHalt.setEnabled(true);
-            mTBCauseGc.setEnabled(true);
-
-            ClientData data = mCurrentClient.getClientData();
-
-            if (data.hasFeature(ClientData.FEATURE_HPROF)) {
-                mTBDumpHprof.setEnabled(data.hasPendingHprofDump() == false);
-                mTBDumpHprof.setToolTipText("Dump HPROF file");
-            } else {
-                mTBDumpHprof.setEnabled(false);
-                mTBDumpHprof.setToolTipText("Dump HPROF file (not supported by this VM)");
-            }
-
-            if (data.hasFeature(ClientData.FEATURE_PROFILING)) {
-                mTBProfiling.setEnabled(true);
-                if (data.getMethodProfilingStatus() == MethodProfilingStatus.ON) {
-                    mTBProfiling.setToolTipText("Stop Method Profiling");
-                    mTBProfiling.setImage(mTracingStopImage);
-                } else {
-                    mTBProfiling.setToolTipText("Start Method Profiling");
-                    mTBProfiling.setImage(mTracingStartImage);
-                }
-            } else {
-                mTBProfiling.setEnabled(false);
-                mTBProfiling.setImage(mTracingStartImage);
-                mTBProfiling.setToolTipText("Start Method Profiling (not supported by this VM)");
-            }
-        } else {
-            // list is empty, disable these
-            mTBShowThreadUpdates.setSelection(false);
-            mTBShowThreadUpdates.setEnabled(false);
-            mTBShowHeapUpdates.setSelection(false);
-            mTBShowHeapUpdates.setEnabled(false);
-            mTBHalt.setEnabled(false);
-            mTBCauseGc.setEnabled(false);
-
-            mTBDumpHprof.setEnabled(false);
-            mTBDumpHprof.setToolTipText("Dump HPROF file");
-
-            mTBProfiling.setEnabled(false);
-            mTBProfiling.setImage(mTracingStartImage);
-            mTBProfiling.setToolTipText("Start Method Profiling");
-        }
-    }
-
-    /**
-     * Sent when a new {@link IDevice} and {@link Client} are selected.
-     * @param selectedDevice the selected device. If null, no devices are selected.
-     * @param selectedClient The selected client. If null, no clients are selected.
-     *
-     * @see IUiSelectionListener
-     */
-    public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
-        if (mCurrentDevice != selectedDevice) {
-            mCurrentDevice = selectedDevice;
-            for (TablePanel panel : mPanels) {
-                if (panel != null) {
-                    panel.deviceSelected(mCurrentDevice);
-                }
-            }
-
-            mEmulatorPanel.deviceSelected(mCurrentDevice);
-            mLogPanel.deviceSelected(mCurrentDevice);
-            if (mEventLogPanel != null) {
-                mEventLogPanel.deviceSelected(mCurrentDevice);
-            }
-
-            if (mExplorer != null) {
-                mExplorer.switchDevice(mCurrentDevice);
-            }
-        }
-
-        if (mCurrentClient != selectedClient) {
-            AndroidDebugBridge.getBridge().setSelectedClient(selectedClient);
-            mCurrentClient = selectedClient;
-            for (TablePanel panel : mPanels) {
-                if (panel != null) {
-                    panel.clientSelected(mCurrentClient);
-                }
-            }
-
-            enableButtons();
-        }
-    }
-
-    public void clientChanged(Client client, int changeMask) {
-        if ((changeMask & Client.CHANGE_METHOD_PROFILING_STATUS) ==
-                Client.CHANGE_METHOD_PROFILING_STATUS) {
-            if (mCurrentClient == client) {
-                mDisplay.asyncExec(new Runnable() {
-                    public void run() {
-                        // force refresh of the button enabled state.
-                        enableButtons();
-                    }
-                });
-            }
-        }
-    }
-}
diff --git a/tools/ddms/app/src/resources/images/ddms-icon.png b/tools/ddms/app/src/resources/images/ddms-icon.png
deleted file mode 100644
index 167a83b..0000000
--- a/tools/ddms/app/src/resources/images/ddms-icon.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/app/src/resources/images/ddms-logo.png b/tools/ddms/app/src/resources/images/ddms-logo.png
deleted file mode 100644
index b4708b4..0000000
--- a/tools/ddms/app/src/resources/images/ddms-logo.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/Android.mk b/tools/ddms/libs/Android.mk
deleted file mode 100644
index c62c6d0..0000000
--- a/tools/ddms/libs/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-DDMSLIBS_LOCAL_DIR := $(call my-dir)
-include $(DDMSLIBS_LOCAL_DIR)/ddmlib/Android.mk
-include $(DDMSLIBS_LOCAL_DIR)/ddmuilib/Android.mk
diff --git a/tools/ddms/libs/ddmlib/.classpath b/tools/ddms/libs/ddmlib/.classpath
deleted file mode 100644
index fb50116..0000000
--- a/tools/ddms/libs/ddmlib/.classpath
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/ddms/libs/ddmlib/.project b/tools/ddms/libs/ddmlib/.project
deleted file mode 100644
index fea25c7..0000000
--- a/tools/ddms/libs/ddmlib/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ddmlib</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/ddms/libs/ddmlib/Android.mk b/tools/ddms/libs/ddmlib/Android.mk
deleted file mode 100644
index a49bdd2..0000000
--- a/tools/ddms/libs/ddmlib/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-DDMLIB_LOCAL_DIR := $(call my-dir)
-include $(DDMLIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/ddms/libs/ddmlib/src/Android.mk b/tools/ddms/libs/ddmlib/src/Android.mk
deleted file mode 100644
index da07f97..0000000
--- a/tools/ddms/libs/ddmlib/src/Android.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_MODULE := ddmlib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java
deleted file mode 100644
index ce8d366..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.log.LogReceiver;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.SocketChannel;
-
-/**
- * Helper class to handle requests and connections to adb.
- * <p/>{@link DebugBridgeServer} is the public API to connection to adb, while {@link AdbHelper}
- * does the low level stuff.
- * <p/>This currently uses spin-wait non-blocking I/O. A Selector would be more efficient,
- * but seems like overkill for what we're doing here.
- */
-final class AdbHelper {
-
-    // public static final long kOkay = 0x59414b4fL;
-    // public static final long kFail = 0x4c494146L;
-
-    static final int WAIT_TIME = 5; // spin-wait sleep, in ms
-
-    static final String DEFAULT_ENCODING = "ISO-8859-1"; //$NON-NLS-1$
-
-    /** do not instantiate */
-    private AdbHelper() {
-    }
-
-    /**
-     * Response from ADB.
-     */
-    static class AdbResponse {
-        public AdbResponse() {
-            // ioSuccess = okay = timeout = false;
-            message = "";
-        }
-
-        public boolean ioSuccess; // read all expected data, no timeoutes
-
-        public boolean okay; // first 4 bytes in response were "OKAY"?
-
-        public boolean timeout; // TODO: implement
-
-        public String message; // diagnostic string
-    }
-
-    /**
-     * Create and connect a new pass-through socket, from the host to a port on
-     * the device.
-     *
-     * @param adbSockAddr
-     * @param device the device to connect to. Can be null in which case the connection will be
-     * to the first available device.
-     * @param devicePort the port we're opening
-     */
-    public static SocketChannel open(InetSocketAddress adbSockAddr,
-            Device device, int devicePort) throws IOException {
-
-        SocketChannel adbChan = SocketChannel.open(adbSockAddr);
-        try {
-            adbChan.socket().setTcpNoDelay(true);
-            adbChan.configureBlocking(false);
-
-            // if the device is not -1, then we first tell adb we're looking to
-            // talk to a specific device
-            setDevice(adbChan, device);
-
-            byte[] req = createAdbForwardRequest(null, devicePort);
-            // Log.hexDump(req);
-
-            if (write(adbChan, req) == false)
-                throw new IOException("failed submitting request to ADB"); //$NON-NLS-1$
-
-            AdbResponse resp = readAdbResponse(adbChan, false);
-            if (!resp.okay)
-                throw new IOException("connection request rejected"); //$NON-NLS-1$
-
-            adbChan.configureBlocking(true);
-        } catch (IOException ioe) {
-            adbChan.close();
-            throw ioe;
-        }
-
-        return adbChan;
-    }
-
-    /**
-     * Creates and connects a new pass-through socket, from the host to a port on
-     * the device.
-     *
-     * @param adbSockAddr
-     * @param device the device to connect to. Can be null in which case the connection will be
-     * to the first available device.
-     * @param pid the process pid to connect to.
-     */
-    public static SocketChannel createPassThroughConnection(InetSocketAddress adbSockAddr,
-            Device device, int pid) throws IOException {
-
-        SocketChannel adbChan = SocketChannel.open(adbSockAddr);
-        try {
-            adbChan.socket().setTcpNoDelay(true);
-            adbChan.configureBlocking(false);
-
-            // if the device is not -1, then we first tell adb we're looking to
-            // talk to a specific device
-            setDevice(adbChan, device);
-
-            byte[] req = createJdwpForwardRequest(pid);
-            // Log.hexDump(req);
-
-            if (write(adbChan, req) == false)
-                throw new IOException("failed submitting request to ADB"); //$NON-NLS-1$
-
-            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
-            if (!resp.okay)
-                throw new IOException("connection request rejected: " + resp.message); //$NON-NLS-1$
-
-            adbChan.configureBlocking(true);
-        } catch (IOException ioe) {
-            adbChan.close();
-            throw ioe;
-        }
-
-        return adbChan;
-    }
-
-    /**
-     * Creates a port forwarding request for adb. This returns an array
-     * containing "####tcp:{port}:{addStr}".
-     * @param addrStr the host. Can be null.
-     * @param port the port on the device. This does not need to be numeric.
-     */
-    private static byte[] createAdbForwardRequest(String addrStr, int port) {
-        String reqStr;
-
-        if (addrStr == null)
-            reqStr = "tcp:" + port;
-        else
-            reqStr = "tcp:" + port + ":" + addrStr;
-        return formAdbRequest(reqStr);
-    }
-
-    /**
-     * Creates a port forwarding request to a jdwp process. This returns an array
-     * containing "####jwdp:{pid}".
-     * @param pid the jdwp process pid on the device.
-     */
-    private static byte[] createJdwpForwardRequest(int pid) {
-        String reqStr = String.format("jdwp:%1$d", pid); //$NON-NLS-1$
-        return formAdbRequest(reqStr);
-    }
-
-    /**
-     * Create an ASCII string preceeded by four hex digits. The opening "####"
-     * is the length of the rest of the string, encoded as ASCII hex (case
-     * doesn't matter). "port" and "host" are what we want to forward to. If
-     * we're on the host side connecting into the device, "addrStr" should be
-     * null.
-     */
-    static byte[] formAdbRequest(String req) {
-        String resultStr = String.format("%04X%s", req.length(), req); //$NON-NLS-1$
-        byte[] result;
-        try {
-            result = resultStr.getBytes(DEFAULT_ENCODING);
-        } catch (UnsupportedEncodingException uee) {
-            uee.printStackTrace(); // not expected
-            return null;
-        }
-        assert result.length == req.length() + 4;
-        return result;
-    }
-
-    /**
-     * Reads the response from ADB after a command.
-     * @param chan The socket channel that is connected to adb.
-     * @param readDiagString If true, we're expecting an OKAY response to be
-     *      followed by a diagnostic string. Otherwise, we only expect the
-     *      diagnostic string to follow a FAIL.
-     */
-    static AdbResponse readAdbResponse(SocketChannel chan, boolean readDiagString)
-            throws IOException {
-
-        AdbResponse resp = new AdbResponse();
-
-        byte[] reply = new byte[4];
-        if (read(chan, reply) == false) {
-            return resp;
-        }
-        resp.ioSuccess = true;
-
-        if (isOkay(reply)) {
-            resp.okay = true;
-        } else {
-            readDiagString = true; // look for a reason after the FAIL
-            resp.okay = false;
-        }
-
-        // not a loop -- use "while" so we can use "break"
-        while (readDiagString) {
-            // length string is in next 4 bytes
-            byte[] lenBuf = new byte[4];
-            if (read(chan, lenBuf) == false) {
-                Log.w("ddms", "Expected diagnostic string not found");
-                break;
-            }
-
-            String lenStr = replyToString(lenBuf);
-
-            int len;
-            try {
-                len = Integer.parseInt(lenStr, 16);
-            } catch (NumberFormatException nfe) {
-                Log.w("ddms", "Expected digits, got '" + lenStr + "': "
-                        + lenBuf[0] + " " + lenBuf[1] + " " + lenBuf[2] + " "
-                        + lenBuf[3]);
-                Log.w("ddms", "reply was " + replyToString(reply));
-                break;
-            }
-
-            byte[] msg = new byte[len];
-            if (read(chan, msg) == false) {
-                Log.w("ddms", "Failed reading diagnostic string, len=" + len);
-                break;
-            }
-
-            resp.message = replyToString(msg);
-            Log.v("ddms", "Got reply '" + replyToString(reply) + "', diag='"
-                    + resp.message + "'");
-
-            break;
-        }
-
-        return resp;
-    }
-
-    /**
-     * Retrieve the frame buffer from the device.
-     */
-    public static RawImage getFrameBuffer(InetSocketAddress adbSockAddr, Device device)
-            throws IOException {
-
-        RawImage imageParams = new RawImage();
-        byte[] request = formAdbRequest("framebuffer:"); //$NON-NLS-1$
-        byte[] nudge = {
-            0
-        };
-        byte[] reply;
-
-        SocketChannel adbChan = null;
-        try {
-            adbChan = SocketChannel.open(adbSockAddr);
-            adbChan.configureBlocking(false);
-
-            // if the device is not -1, then we first tell adb we're looking to talk
-            // to a specific device
-            setDevice(adbChan, device);
-
-            if (write(adbChan, request) == false)
-                throw new IOException("failed asking for frame buffer");
-
-            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
-            if (!resp.ioSuccess || !resp.okay) {
-                Log.w("ddms", "Got timeout or unhappy response from ADB fb req: "
-                        + resp.message);
-                adbChan.close();
-                return null;
-            }
-
-            // first the protocol version.
-            reply = new byte[4];
-            if (read(adbChan, reply) == false) {
-                Log.w("ddms", "got partial reply from ADB fb:");
-                Log.hexDump("ddms", LogLevel.WARN, reply, 0, reply.length);
-                adbChan.close();
-                return null;
-            }
-            ByteBuffer buf = ByteBuffer.wrap(reply);
-            buf.order(ByteOrder.LITTLE_ENDIAN);
-
-            int version = buf.getInt();
-
-            // get the header size (this is a count of int)
-            int headerSize = RawImage.getHeaderSize(version);
-
-            // read the header
-            reply = new byte[headerSize * 4];
-            if (read(adbChan, reply) == false) {
-                Log.w("ddms", "got partial reply from ADB fb:");
-                Log.hexDump("ddms", LogLevel.WARN, reply, 0, reply.length);
-                adbChan.close();
-                return null;
-            }
-            buf = ByteBuffer.wrap(reply);
-            buf.order(ByteOrder.LITTLE_ENDIAN);
-
-            // fill the RawImage with the header
-            if (imageParams.readHeader(version, buf) == false) {
-                Log.e("Screenshot", "Unsupported protocol: " + version);
-                return null;
-            }
-
-            Log.d("ddms", "image params: bpp=" + imageParams.bpp + ", size="
-                    + imageParams.size + ", width=" + imageParams.width
-                    + ", height=" + imageParams.height);
-
-            if (write(adbChan, nudge) == false)
-                throw new IOException("failed nudging");
-
-            reply = new byte[imageParams.size];
-            if (read(adbChan, reply) == false) {
-                Log.w("ddms", "got truncated reply from ADB fb data");
-                adbChan.close();
-                return null;
-            }
-
-            imageParams.data = reply;
-        } finally {
-            if (adbChan != null) {
-                adbChan.close();
-            }
-        }
-
-        return imageParams;
-    }
-
-    /**
-     * Execute a command on the device and retrieve the output. The output is
-     * handed to "rcvr" as it arrives.
-     */
-    public static void executeRemoteCommand(InetSocketAddress adbSockAddr,
-            String command, Device device, IShellOutputReceiver rcvr)
-            throws IOException {
-        Log.v("ddms", "execute: running " + command);
-
-        SocketChannel adbChan = null;
-        try {
-            adbChan = SocketChannel.open(adbSockAddr);
-            adbChan.configureBlocking(false);
-
-            // if the device is not -1, then we first tell adb we're looking to
-            // talk
-            // to a specific device
-            setDevice(adbChan, device);
-
-            byte[] request = formAdbRequest("shell:" + command); //$NON-NLS-1$
-            if (write(adbChan, request) == false)
-                throw new IOException("failed submitting shell command");
-
-            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
-            if (!resp.ioSuccess || !resp.okay) {
-                Log.e("ddms", "ADB rejected shell command (" + command + "): " + resp.message);
-                throw new IOException("sad result from adb: " + resp.message);
-            }
-
-            byte[] data = new byte[16384];
-            ByteBuffer buf = ByteBuffer.wrap(data);
-            while (true) {
-                int count;
-
-                if (rcvr != null && rcvr.isCancelled()) {
-                    Log.v("ddms", "execute: cancelled");
-                    break;
-                }
-
-                count = adbChan.read(buf);
-                if (count < 0) {
-                    // we're at the end, we flush the output
-                    rcvr.flush();
-                    Log.v("ddms", "execute '" + command + "' on '" + device + "' : EOF hit. Read: "
-                            + count);
-                    break;
-                } else if (count == 0) {
-                    try {
-                        Thread.sleep(WAIT_TIME * 5);
-                    } catch (InterruptedException ie) {
-                    }
-                } else {
-                    if (rcvr != null) {
-                        rcvr.addOutput(buf.array(), buf.arrayOffset(), buf.position());
-                    }
-                    buf.rewind();
-                }
-            }
-        } finally {
-            if (adbChan != null) {
-                adbChan.close();
-            }
-            Log.v("ddms", "execute: returning");
-        }
-    }
-
-    /**
-     * Runs the Event log service on the {@link Device}, and provides its output to the
-     * {@link LogReceiver}.
-     * @param adbSockAddr the socket address to connect to adb
-     * @param device the Device on which to run the service
-     * @param rcvr the {@link LogReceiver} to receive the log output
-     * @throws IOException
-     */
-    public static void runEventLogService(InetSocketAddress adbSockAddr, Device device,
-            LogReceiver rcvr) throws IOException {
-        runLogService(adbSockAddr, device, "events", rcvr); //$NON-NLS-1$
-    }
-
-    /**
-     * Runs a log service on the {@link Device}, and provides its output to the {@link LogReceiver}.
-     * @param adbSockAddr the socket address to connect to adb
-     * @param device the Device on which to run the service
-     * @param logName the name of the log file to output
-     * @param rcvr the {@link LogReceiver} to receive the log output
-     * @throws IOException
-     */
-    public static void runLogService(InetSocketAddress adbSockAddr, Device device, String logName,
-            LogReceiver rcvr) throws IOException {
-        SocketChannel adbChan = null;
-
-        try {
-            adbChan = SocketChannel.open(adbSockAddr);
-            adbChan.configureBlocking(false);
-
-            // if the device is not -1, then we first tell adb we're looking to talk
-            // to a specific device
-            setDevice(adbChan, device);
-
-            byte[] request = formAdbRequest("log:" + logName);
-            if (write(adbChan, request) == false) {
-                throw new IOException("failed to submit the log command");
-            }
-
-            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
-            if (!resp.ioSuccess || !resp.okay) {
-                throw new IOException("Device rejected log command: " + resp.message);
-            }
-
-            byte[] data = new byte[16384];
-            ByteBuffer buf = ByteBuffer.wrap(data);
-            while (true) {
-                int count;
-
-                if (rcvr != null && rcvr.isCancelled()) {
-                    break;
-                }
-
-                count = adbChan.read(buf);
-                if (count < 0) {
-                    break;
-                } else if (count == 0) {
-                    try {
-                        Thread.sleep(WAIT_TIME * 5);
-                    } catch (InterruptedException ie) {
-                    }
-                } else {
-                    if (rcvr != null) {
-                        rcvr.parseNewData(buf.array(), buf.arrayOffset(), buf.position());
-                    }
-                    buf.rewind();
-                }
-            }
-        } finally {
-            if (adbChan != null) {
-                adbChan.close();
-            }
-        }
-    }
-
-    /**
-     * Creates a port forwarding between a local and a remote port.
-     * @param adbSockAddr the socket address to connect to adb
-     * @param device the device on which to do the port fowarding
-     * @param localPort the local port to forward
-     * @param remotePort the remote port.
-     * @return <code>true</code> if success.
-     * @throws IOException
-     */
-    public static boolean createForward(InetSocketAddress adbSockAddr, Device device, int localPort,
-            int remotePort) throws IOException {
-
-        SocketChannel adbChan = null;
-        try {
-            adbChan = SocketChannel.open(adbSockAddr);
-            adbChan.configureBlocking(false);
-
-            byte[] request = formAdbRequest(String.format(
-                    "host-serial:%1$s:forward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
-                    device.getSerialNumber(), localPort, remotePort));
-
-            if (write(adbChan, request) == false) {
-                throw new IOException("failed to submit the forward command.");
-            }
-
-            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
-            if (!resp.ioSuccess || !resp.okay) {
-                throw new IOException("Device rejected command: " + resp.message);
-            }
-        } finally {
-            if (adbChan != null) {
-                adbChan.close();
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Remove a port forwarding between a local and a remote port.
-     * @param adbSockAddr the socket address to connect to adb
-     * @param device the device on which to remove the port fowarding
-     * @param localPort the local port of the forward
-     * @param remotePort the remote port.
-     * @return <code>true</code> if success.
-     * @throws IOException
-     */
-    public static boolean removeForward(InetSocketAddress adbSockAddr, Device device, int localPort,
-            int remotePort) throws IOException {
-
-        SocketChannel adbChan = null;
-        try {
-            adbChan = SocketChannel.open(adbSockAddr);
-            adbChan.configureBlocking(false);
-
-            byte[] request = formAdbRequest(String.format(
-                    "host-serial:%1$s:killforward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
-                    device.getSerialNumber(), localPort, remotePort));
-
-            if (!write(adbChan, request)) {
-                throw new IOException("failed to submit the remove forward command.");
-            }
-
-            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
-            if (!resp.ioSuccess || !resp.okay) {
-                throw new IOException("Device rejected command: " + resp.message);
-            }
-        } finally {
-            if (adbChan != null) {
-                adbChan.close();
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Checks to see if the first four bytes in "reply" are OKAY.
-     */
-    static boolean isOkay(byte[] reply) {
-        return reply[0] == (byte)'O' && reply[1] == (byte)'K'
-                && reply[2] == (byte)'A' && reply[3] == (byte)'Y';
-    }
-
-    /**
-     * Converts an ADB reply to a string.
-     */
-    static String replyToString(byte[] reply) {
-        String result;
-        try {
-            result = new String(reply, DEFAULT_ENCODING);
-        } catch (UnsupportedEncodingException uee) {
-            uee.printStackTrace(); // not expected
-            result = "";
-        }
-        return result;
-    }
-
-    /**
-     * Reads from the socket until the array is filled, or no more data is coming (because
-     * the socket closed or the timeout expired).
-     *
-     * @param chan the opened socket to read from. It must be in non-blocking
-     *      mode for timeouts to work
-     * @param data the buffer to store the read data into.
-     * @return "true" if all data was read.
-     * @throws IOException
-     */
-    static boolean read(SocketChannel chan, byte[] data) {
-       try {
-           read(chan, data, -1, DdmPreferences.getTimeOut());
-       } catch (IOException e) {
-           Log.d("ddms", "readAll: IOException: " + e.getMessage());
-           return false;
-       }
-
-       return true;
-    }
-
-    /**
-     * Reads from the socket until the array is filled, the optional length
-     * is reached, or no more data is coming (because the socket closed or the
-     * timeout expired). After "timeout" milliseconds since the
-     * previous successful read, this will return whether or not new data has
-     * been found.
-     *
-     * @param chan the opened socket to read from. It must be in non-blocking
-     *      mode for timeouts to work
-     * @param data the buffer to store the read data into.
-     * @param length the length to read or -1 to fill the data buffer completely
-     * @param timeout The timeout value. A timeout of zero means "wait forever".
-     * @throws IOException
-     */
-    static void read(SocketChannel chan, byte[] data, int length, int timeout) throws IOException {
-        ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
-        int numWaits = 0;
-
-        while (buf.position() != buf.limit()) {
-            int count;
-
-            count = chan.read(buf);
-            if (count < 0) {
-                Log.d("ddms", "read: channel EOF");
-                throw new IOException("EOF");
-            } else if (count == 0) {
-                // TODO: need more accurate timeout?
-                if (timeout != 0 && numWaits * WAIT_TIME > timeout) {
-                    Log.d("ddms", "read: timeout");
-                    throw new IOException("timeout");
-                }
-                // non-blocking spin
-                try {
-                    Thread.sleep(WAIT_TIME);
-                } catch (InterruptedException ie) {
-                }
-                numWaits++;
-            } else {
-                numWaits = 0;
-            }
-        }
-    }
-
-    /**
-     * Write until all data in "data" is written or the connection fails.
-     * @param chan the opened socket to write to.
-     * @param data the buffer to send.
-     * @return "true" if all data was written.
-     */
-    static boolean write(SocketChannel chan, byte[] data) {
-        try {
-            write(chan, data, -1, DdmPreferences.getTimeOut());
-        } catch (IOException e) {
-            Log.e("ddms", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Write until all data in "data" is written, the optional length is reached,
-     * the timeout expires, or the connection fails. Returns "true" if all
-     * data was written.
-     * @param chan the opened socket to write to.
-     * @param data the buffer to send.
-     * @param length the length to write or -1 to send the whole buffer.
-     * @param timeout The timeout value. A timeout of zero means "wait forever".
-     * @throws IOException
-     */
-    static void write(SocketChannel chan, byte[] data, int length, int timeout)
-            throws IOException {
-        ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
-        int numWaits = 0;
-
-        while (buf.position() != buf.limit()) {
-            int count;
-
-            count = chan.write(buf);
-            if (count < 0) {
-                Log.d("ddms", "write: channel EOF");
-                throw new IOException("channel EOF");
-            } else if (count == 0) {
-                // TODO: need more accurate timeout?
-                if (timeout != 0 && numWaits * WAIT_TIME > timeout) {
-                    Log.d("ddms", "write: timeout");
-                    throw new IOException("timeout");
-                }
-                // non-blocking spin
-                try {
-                    Thread.sleep(WAIT_TIME);
-                } catch (InterruptedException ie) {
-                }
-                numWaits++;
-            } else {
-                numWaits = 0;
-            }
-        }
-    }
-
-    /**
-     * tells adb to talk to a specific device
-     *
-     * @param adbChan the socket connection to adb
-     * @param device The device to talk to.
-     * @throws IOException
-     */
-    static void setDevice(SocketChannel adbChan, Device device)
-            throws IOException {
-        // if the device is not -1, then we first tell adb we're looking to talk
-        // to a specific device
-        if (device != null) {
-            String msg = "host:transport:" + device.getSerialNumber(); //$NON-NLS-1$
-            byte[] device_query = formAdbRequest(msg);
-
-            if (write(adbChan, device_query) == false)
-                throw new IOException("failed submitting device (" + device +
-                        ") request to ADB");
-
-            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
-            if (!resp.okay)
-                throw new IOException("device (" + device +
-                        ") request rejected: " + resp.message);
-        }
-
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AllocationInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AllocationInfo.java
deleted file mode 100644
index c6d4b50..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AllocationInfo.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-/**
- * Holds an Allocation information.
- */
-public class AllocationInfo implements Comparable<AllocationInfo>, IStackTraceInfo {
-    private String mAllocatedClass;
-    private int mAllocationSize;
-    private short mThreadId;
-    private StackTraceElement[] mStackTrace;
-
-    /*
-     * Simple constructor.
-     */
-    AllocationInfo(String allocatedClass, int allocationSize,
-        short threadId, StackTraceElement[] stackTrace) {
-        mAllocatedClass = allocatedClass;
-        mAllocationSize = allocationSize;
-        mThreadId = threadId;
-        mStackTrace = stackTrace;
-    }
-    
-    /**
-     * Returns the name of the allocated class.
-     */
-    public String getAllocatedClass() {
-        return mAllocatedClass;
-    }
-
-    /**
-     * Returns the size of the allocation.
-     */
-    public int getSize() {
-        return mAllocationSize;
-    }
-
-    /**
-     * Returns the id of the thread that performed the allocation.
-     */
-    public short getThreadId() {
-        return mThreadId;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IStackTraceInfo#getStackTrace()
-     */
-    public StackTraceElement[] getStackTrace() {
-        return mStackTrace;
-    }
-
-    public int compareTo(AllocationInfo otherAlloc) {
-        return otherAlloc.mAllocationSize - mAllocationSize;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
deleted file mode 100644
index 6b9dccc..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.Log.LogLevel;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.Thread.State;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.security.InvalidParameterException;
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A connection to the host-side android debug bridge (adb)
- * <p/>This is the central point to communicate with any devices, emulators, or the applications
- * running on them.
- * <p/><b>{@link #init(boolean)} must be called before anything is done.</b>
- */
-public final class AndroidDebugBridge {
-
-    /*
-     * Minimum and maximum version of adb supported. This correspond to
-     * ADB_SERVER_VERSION found in //device/tools/adb/adb.h
-     */
-
-    private final static int ADB_VERSION_MICRO_MIN = 20;
-    private final static int ADB_VERSION_MICRO_MAX = -1;
-
-    private final static Pattern sAdbVersion = Pattern.compile(
-            "^.*(\\d+)\\.(\\d+)\\.(\\d+)$"); //$NON-NLS-1$
-
-    private final static String ADB = "adb"; //$NON-NLS-1$
-    private final static String DDMS = "ddms"; //$NON-NLS-1$
-
-    // Where to find the ADB bridge.
-    final static String ADB_HOST = "127.0.0.1"; //$NON-NLS-1$
-    final static int ADB_PORT = 5037;
-
-    static InetAddress sHostAddr;
-    static InetSocketAddress sSocketAddr;
-
-    static {
-        // built-in local address/port for ADB.
-        try {
-            sHostAddr = InetAddress.getByName(ADB_HOST);
-            sSocketAddr = new InetSocketAddress(sHostAddr, ADB_PORT);
-        } catch (UnknownHostException e) {
-
-        }
-    }
-
-    private static AndroidDebugBridge sThis;
-    private static boolean sClientSupport;
-
-    /** Full path to adb. */
-    private String mAdbOsLocation = null;
-
-    private boolean mVersionCheck;
-
-    private boolean mStarted = false;
-
-    private DeviceMonitor mDeviceMonitor;
-
-    private final static ArrayList<IDebugBridgeChangeListener> sBridgeListeners =
-        new ArrayList<IDebugBridgeChangeListener>();
-    private final static ArrayList<IDeviceChangeListener> sDeviceListeners =
-        new ArrayList<IDeviceChangeListener>();
-    private final static ArrayList<IClientChangeListener> sClientListeners =
-        new ArrayList<IClientChangeListener>();
-
-    // lock object for synchronization
-    private static final Object sLock = sBridgeListeners;
-
-    /**
-     * Classes which implement this interface provide a method that deals
-     * with {@link AndroidDebugBridge} changes.
-     */
-    public interface IDebugBridgeChangeListener {
-        /**
-         * Sent when a new {@link AndroidDebugBridge} is connected.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param bridge the new {@link AndroidDebugBridge} object.
-         */
-        public void bridgeChanged(AndroidDebugBridge bridge);
-    }
-
-    /**
-     * Classes which implement this interface provide methods that deal
-     * with {@link IDevice} addition, deletion, and changes.
-     */
-    public interface IDeviceChangeListener {
-        /**
-         * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param device the new device.
-         */
-        public void deviceConnected(IDevice device);
-
-        /**
-         * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param device the new device.
-         */
-        public void deviceDisconnected(IDevice device);
-
-        /**
-         * Sent when a device data changed, or when clients are started/terminated on the device.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param device the device that was updated.
-         * @param changeMask the mask describing what changed. It can contain any of the following
-         * values: {@link IDevice#CHANGE_BUILD_INFO}, {@link IDevice#CHANGE_STATE},
-         * {@link IDevice#CHANGE_CLIENT_LIST}
-         */
-        public void deviceChanged(IDevice device, int changeMask);
-    }
-
-    /**
-     * Classes which implement this interface provide methods that deal
-     * with {@link Client}  changes.
-     */
-    public interface IClientChangeListener {
-        /**
-         * Sent when an existing client information changed.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param client the updated client.
-         * @param changeMask the bit mask describing the changed properties. It can contain
-         * any of the following values: {@link Client#CHANGE_INFO},
-         * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-         * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-         * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-         */
-        public void clientChanged(Client client, int changeMask);
-    }
-
-    /**
-     * Initializes the <code>ddm</code> library.
-     * <p/>This must be called once <b>before</b> any call to
-     * {@link #createBridge(String, boolean)}.
-     * <p>The library can be initialized in 2 ways:
-     * <ul>
-     * <li>Mode 1: <var>clientSupport</var> == <code>true</code>.<br>The library monitors the
-     * devices and the applications running on them. It will connect to each application, as a
-     * debugger of sort, to be able to interact with them through JDWP packets.</li>
-     * <li>Mode 2: <var>clientSupport</var> == <code>false</code>.<br>The library only monitors
-     * devices. The applications are left untouched, letting other tools built on
-     * <code>ddmlib</code> to connect a debugger to them.</li>
-     * </ul>
-     * <p/><b>Only one tool can run in mode 1 at the same time.</b>
-     * <p/>Note that mode 1 does not prevent debugging of applications running on devices. Mode 1
-     * lets debuggers connect to <code>ddmlib</code> which acts as a proxy between the debuggers and
-     * the applications to debug. See {@link Client#getDebuggerListenPort()}.
-     * <p/>The preferences of <code>ddmlib</code> should also be initialized with whatever default
-     * values were changed from the default values.
-     * <p/>When the application quits, {@link #terminate()} should be called.
-     * @param clientSupport Indicates whether the library should enable the monitoring and
-     * interaction with applications running on the devices.
-     * @see AndroidDebugBridge#createBridge(String, boolean)
-     * @see DdmPreferences
-     */
-    public static void init(boolean clientSupport) {
-        sClientSupport = clientSupport;
-
-        MonitorThread monitorThread = MonitorThread.createInstance();
-        monitorThread.start();
-
-        HandleHello.register(monitorThread);
-        HandleAppName.register(monitorThread);
-        HandleTest.register(monitorThread);
-        HandleThread.register(monitorThread);
-        HandleHeap.register(monitorThread);
-        HandleWait.register(monitorThread);
-        HandleProfiling.register(monitorThread);
-    }
-
-    /**
-     * Terminates the ddm library. This must be called upon application termination.
-     */
-    public static void terminate() {
-        // kill the monitoring services
-        if (sThis != null && sThis.mDeviceMonitor != null) {
-            sThis.mDeviceMonitor.stop();
-            sThis.mDeviceMonitor = null;
-        }
-
-        MonitorThread monitorThread = MonitorThread.getInstance();
-        if (monitorThread != null) {
-            monitorThread.quit();
-        }
-    }
-
-    /**
-     * Returns whether the ddmlib is setup to support monitoring and interacting with
-     * {@link Client}s running on the {@link IDevice}s.
-     */
-    static boolean getClientSupport() {
-        return sClientSupport;
-    }
-
-    /**
-     * Creates a {@link AndroidDebugBridge} that is not linked to any particular executable.
-     * <p/>This bridge will expect adb to be running. It will not be able to start/stop/restart
-     * adb.
-     * <p/>If a bridge has already been started, it is directly returned with no changes (similar
-     * to calling {@link #getBridge()}).
-     * @return a connected bridge.
-     */
-    public static AndroidDebugBridge createBridge() {
-        synchronized (sLock) {
-            if (sThis != null) {
-                return sThis;
-            }
-
-            try {
-                sThis = new AndroidDebugBridge();
-                sThis.start();
-            } catch (InvalidParameterException e) {
-                sThis = null;
-            }
-
-            // because the listeners could remove themselves from the list while processing
-            // their event callback, we make a copy of the list and iterate on it instead of
-            // the main list.
-            // This mostly happens when the application quits.
-            IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
-                    new IDebugBridgeChangeListener[sBridgeListeners.size()]);
-
-            // notify the listeners of the change
-            for (IDebugBridgeChangeListener listener : listenersCopy) {
-                // we attempt to catch any exception so that a bad listener doesn't kill our
-                // thread
-                try {
-                    listener.bridgeChanged(sThis);
-                } catch (Exception e) {
-                    Log.e(DDMS, e);
-                }
-            }
-
-            return sThis;
-        }
-    }
-
-
-    /**
-     * Creates a new debug bridge from the location of the command line tool.
-     * <p/>
-     * Any existing server will be disconnected, unless the location is the same and
-     * <code>forceNewBridge</code> is set to false.
-     * @param osLocation the location of the command line tool 'adb'
-     * @param forceNewBridge force creation of a new bridge even if one with the same location
-     * already exists.
-     * @return a connected bridge.
-     */
-    public static AndroidDebugBridge createBridge(String osLocation, boolean forceNewBridge) {
-        synchronized (sLock) {
-            if (sThis != null) {
-                if (sThis.mAdbOsLocation != null && sThis.mAdbOsLocation.equals(osLocation) &&
-                        forceNewBridge == false) {
-                    return sThis;
-                } else {
-                    // stop the current server
-                    sThis.stop();
-                }
-            }
-
-            try {
-                sThis = new AndroidDebugBridge(osLocation);
-                sThis.start();
-            } catch (InvalidParameterException e) {
-                sThis = null;
-            }
-
-            // because the listeners could remove themselves from the list while processing
-            // their event callback, we make a copy of the list and iterate on it instead of
-            // the main list.
-            // This mostly happens when the application quits.
-            IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
-                    new IDebugBridgeChangeListener[sBridgeListeners.size()]);
-
-            // notify the listeners of the change
-            for (IDebugBridgeChangeListener listener : listenersCopy) {
-                // we attempt to catch any exception so that a bad listener doesn't kill our
-                // thread
-                try {
-                    listener.bridgeChanged(sThis);
-                } catch (Exception e) {
-                    Log.e(DDMS, e);
-                }
-            }
-
-            return sThis;
-        }
-    }
-
-    /**
-     * Returns the current debug bridge. Can be <code>null</code> if none were created.
-     */
-    public static AndroidDebugBridge getBridge() {
-        return sThis;
-    }
-
-    /**
-     * Disconnects the current debug bridge, and destroy the object.
-     * <p/>This also stops the current adb host server.
-     * <p/>
-     * A new object will have to be created with {@link #createBridge(String, boolean)}.
-     */
-    public static void disconnectBridge() {
-        synchronized (sLock) {
-            if (sThis != null) {
-                sThis.stop();
-                sThis = null;
-
-                // because the listeners could remove themselves from the list while processing
-                // their event callback, we make a copy of the list and iterate on it instead of
-                // the main list.
-                // This mostly happens when the application quits.
-                IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
-                        new IDebugBridgeChangeListener[sBridgeListeners.size()]);
-
-                // notify the listeners.
-                for (IDebugBridgeChangeListener listener : listenersCopy) {
-                    // we attempt to catch any exception so that a bad listener doesn't kill our
-                    // thread
-                    try {
-                        listener.bridgeChanged(sThis);
-                    } catch (Exception e) {
-                        Log.e(DDMS, e);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Adds the listener to the collection of listeners who will be notified when a new
-     * {@link AndroidDebugBridge} is connected, by sending it one of the messages defined
-     * in the {@link IDebugBridgeChangeListener} interface.
-     * @param listener The listener which should be notified.
-     */
-    public static void addDebugBridgeChangeListener(IDebugBridgeChangeListener listener) {
-        synchronized (sLock) {
-            if (sBridgeListeners.contains(listener) == false) {
-                sBridgeListeners.add(listener);
-                if (sThis != null) {
-                    // we attempt to catch any exception so that a bad listener doesn't kill our
-                    // thread
-                    try {
-                        listener.bridgeChanged(sThis);
-                    } catch (Exception e) {
-                        Log.e(DDMS, e);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Removes the listener from the collection of listeners who will be notified when a new
-     * {@link AndroidDebugBridge} is started.
-     * @param listener The listener which should no longer be notified.
-     */
-    public static void removeDebugBridgeChangeListener(IDebugBridgeChangeListener listener) {
-        synchronized (sLock) {
-            sBridgeListeners.remove(listener);
-        }
-    }
-
-    /**
-     * Adds the listener to the collection of listeners who will be notified when a {@link IDevice}
-     * is connected, disconnected, or when its properties or its {@link Client} list changed,
-     * by sending it one of the messages defined in the {@link IDeviceChangeListener} interface.
-     * @param listener The listener which should be notified.
-     */
-    public static void addDeviceChangeListener(IDeviceChangeListener listener) {
-        synchronized (sLock) {
-            if (sDeviceListeners.contains(listener) == false) {
-                sDeviceListeners.add(listener);
-            }
-        }
-    }
-
-    /**
-     * Removes the listener from the collection of listeners who will be notified when a
-     * {@link IDevice} is connected, disconnected, or when its properties or its {@link Client}
-     * list changed.
-     * @param listener The listener which should no longer be notified.
-     */
-    public static void removeDeviceChangeListener(IDeviceChangeListener listener) {
-        synchronized (sLock) {
-            sDeviceListeners.remove(listener);
-        }
-    }
-
-    /**
-     * Adds the listener to the collection of listeners who will be notified when a {@link Client}
-     * property changed, by sending it one of the messages defined in the
-     * {@link IClientChangeListener} interface.
-     * @param listener The listener which should be notified.
-     */
-    public static void addClientChangeListener(IClientChangeListener listener) {
-        synchronized (sLock) {
-            if (sClientListeners.contains(listener) == false) {
-                sClientListeners.add(listener);
-            }
-        }
-    }
-
-    /**
-     * Removes the listener from the collection of listeners who will be notified when a
-     * {@link Client} property changed.
-     * @param listener The listener which should no longer be notified.
-     */
-    public static void removeClientChangeListener(IClientChangeListener listener) {
-        synchronized (sLock) {
-            sClientListeners.remove(listener);
-        }
-    }
-
-
-    /**
-     * Returns the devices.
-     * @see #hasInitialDeviceList()
-     */
-    public IDevice[] getDevices() {
-        synchronized (sLock) {
-            if (mDeviceMonitor != null) {
-                return mDeviceMonitor.getDevices();
-            }
-        }
-
-        return new IDevice[0];
-    }
-
-    /**
-     * Returns whether the bridge has acquired the initial list from adb after being created.
-     * <p/>Calling {@link #getDevices()} right after {@link #createBridge(String, boolean)} will
-     * generally result in an empty list. This is due to the internal asynchronous communication
-     * mechanism with <code>adb</code> that does not guarantee that the {@link IDevice} list has been
-     * built before the call to {@link #getDevices()}.
-     * <p/>The recommended way to get the list of {@link IDevice} objects is to create a
-     * {@link IDeviceChangeListener} object.
-     */
-    public boolean hasInitialDeviceList() {
-        if (mDeviceMonitor != null) {
-            return mDeviceMonitor.hasInitialDeviceList();
-        }
-
-        return false;
-    }
-
-    /**
-     * Sets the client to accept debugger connection on the custom "Selected debug port".
-     * @param selectedClient the client. Can be null.
-     */
-    public void setSelectedClient(Client selectedClient) {
-        MonitorThread monitorThread = MonitorThread.getInstance();
-        if (monitorThread != null) {
-            monitorThread.setSelectedClient(selectedClient);
-        }
-    }
-
-    /**
-     * Returns whether the {@link AndroidDebugBridge} object is still connected to the adb daemon.
-     */
-    public boolean isConnected() {
-        MonitorThread monitorThread = MonitorThread.getInstance();
-        if (mDeviceMonitor != null && monitorThread != null) {
-            return mDeviceMonitor.isMonitoring() && monitorThread.getState() != State.TERMINATED;
-        }
-        return false;
-    }
-
-    /**
-     * Returns the number of times the {@link AndroidDebugBridge} object attempted to connect
-     * to the adb daemon.
-     */
-    public int getConnectionAttemptCount() {
-        if (mDeviceMonitor != null) {
-            return mDeviceMonitor.getConnectionAttemptCount();
-        }
-        return -1;
-    }
-
-    /**
-     * Returns the number of times the {@link AndroidDebugBridge} object attempted to restart
-     * the adb daemon.
-     */
-    public int getRestartAttemptCount() {
-        if (mDeviceMonitor != null) {
-            return mDeviceMonitor.getRestartAttemptCount();
-        }
-        return -1;
-    }
-
-    /**
-     * Creates a new bridge.
-     * @param osLocation the location of the command line tool
-     * @throws InvalidParameterException
-     */
-    private AndroidDebugBridge(String osLocation) throws InvalidParameterException {
-        if (osLocation == null || osLocation.length() == 0) {
-            throw new InvalidParameterException();
-        }
-        mAdbOsLocation = osLocation;
-
-        checkAdbVersion();
-    }
-
-    /**
-     * Creates a new bridge not linked to any particular adb executable.
-     */
-    private AndroidDebugBridge() {
-    }
-
-    /**
-     * Queries adb for its version number and checks it against {@link #MIN_VERSION_NUMBER} and
-     * {@link #MAX_VERSION_NUMBER}
-     */
-    private void checkAdbVersion() {
-        // default is bad check
-        mVersionCheck = false;
-
-        if (mAdbOsLocation == null) {
-            return;
-        }
-
-        try {
-            String[] command = new String[2];
-            command[0] = mAdbOsLocation;
-            command[1] = "version"; //$NON-NLS-1$
-            Log.d(DDMS, String.format("Checking '%1$s version'", mAdbOsLocation)); //$NON-NLS-1$
-            Process process = Runtime.getRuntime().exec(command);
-
-            ArrayList<String> errorOutput = new ArrayList<String>();
-            ArrayList<String> stdOutput = new ArrayList<String>();
-            int status = grabProcessOutput(process, errorOutput, stdOutput,
-                    true /* waitForReaders */);
-
-            if (status != 0) {
-                StringBuilder builder = new StringBuilder("'adb version' failed!"); //$NON-NLS-1$
-                for (String error : errorOutput) {
-                    builder.append('\n');
-                    builder.append(error);
-                }
-                Log.logAndDisplay(LogLevel.ERROR, "adb", builder.toString());
-            }
-
-            // check both stdout and stderr
-            boolean versionFound = false;
-            for (String line : stdOutput) {
-                versionFound = scanVersionLine(line);
-                if (versionFound) {
-                    break;
-                }
-            }
-            if (!versionFound) {
-                for (String line : errorOutput) {
-                    versionFound = scanVersionLine(line);
-                    if (versionFound) {
-                        break;
-                    }
-                }
-            }
-
-            if (!versionFound) {
-                // if we get here, we failed to parse the output.
-                Log.logAndDisplay(LogLevel.ERROR, ADB,
-                        "Failed to parse the output of 'adb version'"); //$NON-NLS-1$
-            }
-
-        } catch (IOException e) {
-            Log.logAndDisplay(LogLevel.ERROR, ADB,
-                    "Failed to get the adb version: " + e.getMessage()); //$NON-NLS-1$
-        } catch (InterruptedException e) {
-        } finally {
-
-        }
-    }
-
-    /**
-     * Scans a line resulting from 'adb version' for a potential version number.
-     * <p/>
-     * If a version number is found, it checks the version number against what is expected
-     * by this version of ddms.
-     * <p/>
-     * Returns true when a version number has been found so that we can stop scanning,
-     * whether the version number is in the acceptable range or not.
-     *
-     * @param line The line to scan.
-     * @return True if a version number was found (whether it is acceptable or not).
-     */
-    private boolean scanVersionLine(String line) {
-        if (line != null) {
-            Matcher matcher = sAdbVersion.matcher(line);
-            if (matcher.matches()) {
-                int majorVersion = Integer.parseInt(matcher.group(1));
-                int minorVersion = Integer.parseInt(matcher.group(2));
-                int microVersion = Integer.parseInt(matcher.group(3));
-
-                // check only the micro version for now.
-                if (microVersion < ADB_VERSION_MICRO_MIN) {
-                    String message = String.format(
-                            "Required minimum version of adb: %1$d.%2$d.%3$d." //$NON-NLS-1$
-                            + "Current version is %1$d.%2$d.%4$d", //$NON-NLS-1$
-                            majorVersion, minorVersion, ADB_VERSION_MICRO_MIN,
-                            microVersion);
-                    Log.logAndDisplay(LogLevel.ERROR, ADB, message);
-                } else if (ADB_VERSION_MICRO_MAX != -1 &&
-                        microVersion > ADB_VERSION_MICRO_MAX) {
-                    String message = String.format(
-                            "Required maximum version of adb: %1$d.%2$d.%3$d." //$NON-NLS-1$
-                            + "Current version is %1$d.%2$d.%4$d", //$NON-NLS-1$
-                            majorVersion, minorVersion, ADB_VERSION_MICRO_MAX,
-                            microVersion);
-                    Log.logAndDisplay(LogLevel.ERROR, ADB, message);
-                } else {
-                    mVersionCheck = true;
-                }
-
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Starts the debug bridge.
-     * @return true if success.
-     */
-    boolean start() {
-        if (mAdbOsLocation != null && (mVersionCheck == false || startAdb() == false)) {
-            return false;
-        }
-
-        mStarted = true;
-
-        // now that the bridge is connected, we start the underlying services.
-        mDeviceMonitor = new DeviceMonitor(this);
-        mDeviceMonitor.start();
-
-        return true;
-    }
-
-   /**
-     * Kills the debug bridge, and the adb host server.
-     * @return true if success
-     */
-    boolean stop() {
-        // if we haven't started we return false;
-        if (mStarted == false) {
-            return false;
-        }
-
-        // kill the monitoring services
-        mDeviceMonitor.stop();
-        mDeviceMonitor = null;
-
-        if (stopAdb() == false) {
-            return false;
-        }
-
-        mStarted = false;
-        return true;
-    }
-
-    /**
-     * Restarts adb, but not the services around it.
-     * @return true if success.
-     */
-    public boolean restart() {
-        if (mAdbOsLocation == null) {
-            Log.e(ADB,
-                    "Cannot restart adb when AndroidDebugBridge is created without the location of adb."); //$NON-NLS-1$
-            return false;
-        }
-
-        if (mVersionCheck == false) {
-            Log.logAndDisplay(LogLevel.ERROR, ADB,
-                    "Attempting to restart adb, but version check failed!"); //$NON-NLS-1$
-            return false;
-        }
-        synchronized (this) {
-            stopAdb();
-
-            boolean restart = startAdb();
-
-            if (restart && mDeviceMonitor == null) {
-                mDeviceMonitor = new DeviceMonitor(this);
-                mDeviceMonitor.start();
-            }
-
-            return restart;
-        }
-    }
-
-    /**
-     * Notify the listener of a new {@link IDevice}.
-     * <p/>
-     * The notification of the listeners is done in a synchronized block. It is important to
-     * expect the listeners to potentially access various methods of {@link IDevice} as well as
-     * {@link #getDevices()} which use internal locks.
-     * <p/>
-     * For this reason, any call to this method from a method of {@link DeviceMonitor},
-     * {@link IDevice} which is also inside a synchronized block, should first synchronize on
-     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
-     * @param device the new <code>IDevice</code>.
-     * @see #getLock()
-     */
-    void deviceConnected(IDevice device) {
-        // because the listeners could remove themselves from the list while processing
-        // their event callback, we make a copy of the list and iterate on it instead of
-        // the main list.
-        // This mostly happens when the application quits.
-        IDeviceChangeListener[] listenersCopy = null;
-        synchronized (sLock) {
-            listenersCopy = sDeviceListeners.toArray(
-                    new IDeviceChangeListener[sDeviceListeners.size()]);
-        }
-
-        // Notify the listeners
-        for (IDeviceChangeListener listener : listenersCopy) {
-            // we attempt to catch any exception so that a bad listener doesn't kill our
-            // thread
-            try {
-                listener.deviceConnected(device);
-            } catch (Exception e) {
-                Log.e(DDMS, e);
-            }
-        }
-    }
-
-    /**
-     * Notify the listener of a disconnected {@link IDevice}.
-     * <p/>
-     * The notification of the listeners is done in a synchronized block. It is important to
-     * expect the listeners to potentially access various methods of {@link IDevice} as well as
-     * {@link #getDevices()} which use internal locks.
-     * <p/>
-     * For this reason, any call to this method from a method of {@link DeviceMonitor},
-     * {@link IDevice} which is also inside a synchronized block, should first synchronize on
-     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
-     * @param device the disconnected <code>IDevice</code>.
-     * @see #getLock()
-     */
-    void deviceDisconnected(IDevice device) {
-        // because the listeners could remove themselves from the list while processing
-        // their event callback, we make a copy of the list and iterate on it instead of
-        // the main list.
-        // This mostly happens when the application quits.
-        IDeviceChangeListener[] listenersCopy = null;
-        synchronized (sLock) {
-            listenersCopy = sDeviceListeners.toArray(
-                    new IDeviceChangeListener[sDeviceListeners.size()]);
-        }
-
-        // Notify the listeners
-        for (IDeviceChangeListener listener : listenersCopy) {
-            // we attempt to catch any exception so that a bad listener doesn't kill our
-            // thread
-            try {
-                listener.deviceDisconnected(device);
-            } catch (Exception e) {
-                Log.e(DDMS, e);
-            }
-        }
-    }
-
-    /**
-     * Notify the listener of a modified {@link IDevice}.
-     * <p/>
-     * The notification of the listeners is done in a synchronized block. It is important to
-     * expect the listeners to potentially access various methods of {@link IDevice} as well as
-     * {@link #getDevices()} which use internal locks.
-     * <p/>
-     * For this reason, any call to this method from a method of {@link DeviceMonitor},
-     * {@link IDevice} which is also inside a synchronized block, should first synchronize on
-     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
-     * @param device the modified <code>IDevice</code>.
-     * @see #getLock()
-     */
-    void deviceChanged(IDevice device, int changeMask) {
-        // because the listeners could remove themselves from the list while processing
-        // their event callback, we make a copy of the list and iterate on it instead of
-        // the main list.
-        // This mostly happens when the application quits.
-        IDeviceChangeListener[] listenersCopy = null;
-        synchronized (sLock) {
-            listenersCopy = sDeviceListeners.toArray(
-                    new IDeviceChangeListener[sDeviceListeners.size()]);
-        }
-
-        // Notify the listeners
-        for (IDeviceChangeListener listener : listenersCopy) {
-            // we attempt to catch any exception so that a bad listener doesn't kill our
-            // thread
-            try {
-                listener.deviceChanged(device, changeMask);
-            } catch (Exception e) {
-                Log.e(DDMS, e);
-            }
-        }
-    }
-
-    /**
-     * Notify the listener of a modified {@link Client}.
-     * <p/>
-     * The notification of the listeners is done in a synchronized block. It is important to
-     * expect the listeners to potentially access various methods of {@link IDevice} as well as
-     * {@link #getDevices()} which use internal locks.
-     * <p/>
-     * For this reason, any call to this method from a method of {@link DeviceMonitor},
-     * {@link IDevice} which is also inside a synchronized block, should first synchronize on
-     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
-     * @param device the modified <code>Client</code>.
-     * @param changeMask the mask indicating what changed in the <code>Client</code>
-     * @see #getLock()
-     */
-    void clientChanged(Client client, int changeMask) {
-        // because the listeners could remove themselves from the list while processing
-        // their event callback, we make a copy of the list and iterate on it instead of
-        // the main list.
-        // This mostly happens when the application quits.
-        IClientChangeListener[] listenersCopy = null;
-        synchronized (sLock) {
-            listenersCopy = sClientListeners.toArray(
-                    new IClientChangeListener[sClientListeners.size()]);
-
-        }
-
-        // Notify the listeners
-        for (IClientChangeListener listener : listenersCopy) {
-            // we attempt to catch any exception so that a bad listener doesn't kill our
-            // thread
-            try {
-                listener.clientChanged(client, changeMask);
-            } catch (Exception e) {
-                Log.e(DDMS, e);
-            }
-        }
-    }
-
-    /**
-     * Returns the {@link DeviceMonitor} object.
-     */
-    DeviceMonitor getDeviceMonitor() {
-        return mDeviceMonitor;
-    }
-
-    /**
-     * Starts the adb host side server.
-     * @return true if success
-     */
-    synchronized boolean startAdb() {
-        if (mAdbOsLocation == null) {
-            Log.e(ADB,
-                "Cannot start adb when AndroidDebugBridge is created without the location of adb."); //$NON-NLS-1$
-            return false;
-        }
-
-        Process proc;
-        int status = -1;
-
-        try {
-            String[] command = new String[2];
-            command[0] = mAdbOsLocation;
-            command[1] = "start-server"; //$NON-NLS-1$
-            Log.d(DDMS,
-                    String.format("Launching '%1$s %2$s' to ensure ADB is running.", //$NON-NLS-1$
-                    mAdbOsLocation, command[1]));
-            proc = Runtime.getRuntime().exec(command);
-
-            ArrayList<String> errorOutput = new ArrayList<String>();
-            ArrayList<String> stdOutput = new ArrayList<String>();
-            status = grabProcessOutput(proc, errorOutput, stdOutput,
-                    false /* waitForReaders */);
-
-        } catch (IOException ioe) {
-            Log.d(DDMS, "Unable to run 'adb': " + ioe.getMessage()); //$NON-NLS-1$
-            // we'll return false;
-        } catch (InterruptedException ie) {
-            Log.d(DDMS, "Unable to run 'adb': " + ie.getMessage()); //$NON-NLS-1$
-            // we'll return false;
-        }
-
-        if (status != 0) {
-            Log.w(DDMS,
-                    "'adb start-server' failed -- run manually if necessary"); //$NON-NLS-1$
-            return false;
-        }
-
-        Log.d(DDMS, "'adb start-server' succeeded"); //$NON-NLS-1$
-
-        return true;
-    }
-
-    /**
-     * Stops the adb host side server.
-     * @return true if success
-     */
-    private synchronized boolean stopAdb() {
-        if (mAdbOsLocation == null) {
-            Log.e(ADB,
-                "Cannot stop adb when AndroidDebugBridge is created without the location of adb."); //$NON-NLS-1$
-            return false;
-        }
-
-        Process proc;
-        int status = -1;
-
-        try {
-            String[] command = new String[2];
-            command[0] = mAdbOsLocation;
-            command[1] = "kill-server"; //$NON-NLS-1$
-            proc = Runtime.getRuntime().exec(command);
-            status = proc.waitFor();
-        }
-        catch (IOException ioe) {
-            // we'll return false;
-        }
-        catch (InterruptedException ie) {
-            // we'll return false;
-        }
-
-        if (status != 0) {
-            Log.w(DDMS,
-                    "'adb kill-server' failed -- run manually if necessary"); //$NON-NLS-1$
-            return false;
-        }
-
-        Log.d(DDMS, "'adb kill-server' succeeded"); //$NON-NLS-1$
-        return true;
-    }
-
-    /**
-     * Get the stderr/stdout outputs of a process and return when the process is done.
-     * Both <b>must</b> be read or the process will block on windows.
-     * @param process The process to get the ouput from
-     * @param errorOutput The array to store the stderr output. cannot be null.
-     * @param stdOutput The array to store the stdout output. cannot be null.
-     * @param displayStdOut If true this will display stdout as well
-     * @param waitforReaders if true, this will wait for the reader threads.
-     * @return the process return code.
-     * @throws InterruptedException
-     */
-    private int grabProcessOutput(final Process process, final ArrayList<String> errorOutput,
-            final ArrayList<String> stdOutput, boolean waitforReaders)
-            throws InterruptedException {
-        assert errorOutput != null;
-        assert stdOutput != null;
-        // read the lines as they come. if null is returned, it's
-        // because the process finished
-        Thread t1 = new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            Log.e(ADB, line);
-                            errorOutput.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        Thread t2 = new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            Log.d(ADB, line);
-                            stdOutput.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        t1.start();
-        t2.start();
-
-        // it looks like on windows process#waitFor() can return
-        // before the thread have filled the arrays, so we wait for both threads and the
-        // process itself.
-        if (waitforReaders) {
-            try {
-                t1.join();
-            } catch (InterruptedException e) {
-            }
-            try {
-                t2.join();
-            } catch (InterruptedException e) {
-            }
-        }
-
-        // get the return code from the process
-        return process.waitFor();
-    }
-
-    /**
-     * Returns the singleton lock used by this class to protect any access to the listener.
-     * <p/>
-     * This includes adding/removing listeners, but also notifying listeners of new bridges,
-     * devices, and clients.
-     */
-    static Object getLock() {
-        return sLock;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java
deleted file mode 100644
index 129b312..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/* //device/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.ddmlib;
-
-/**
- * Thrown if the contents of a packet are bad.
- */
-@SuppressWarnings("serial")
-class BadPacketException extends RuntimeException {
-    public BadPacketException()
-    {
-        super();
-    }
-
-    public BadPacketException(String msg)
-    {
-        super(msg);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java
deleted file mode 100644
index 74fa318..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Subclass this with a class that handles one or more chunk types.
- */
-abstract class ChunkHandler {
-
-    public static final int CHUNK_HEADER_LEN = 8;   // 4-byte type, 4-byte len
-    public static final ByteOrder CHUNK_ORDER = ByteOrder.BIG_ENDIAN;
-
-    public static final int CHUNK_FAIL = type("FAIL");
-
-    ChunkHandler() {}
-
-    /**
-     * Client is ready.  The monitor thread calls this method on all
-     * handlers when the client is determined to be DDM-aware (usually
-     * after receiving a HELO response.)
-     *
-     * The handler can use this opportunity to initialize client-side
-     * activity.  Because there's a fair chance we'll want to send a
-     * message to the client, this method can throw an IOException.
-     */
-    abstract void clientReady(Client client) throws IOException;
-
-    /**
-     * Client has gone away.  Can be used to clean up any resources
-     * associated with this client connection.
-     */
-    abstract void clientDisconnected(Client client);
-
-    /**
-     * Handle an incoming chunk.  The data, of chunk type "type", begins
-     * at the start of "data" and continues to data.limit().
-     *
-     * If "isReply" is set, then "msgId" will be the ID of the request
-     * we sent to the client.  Otherwise, it's the ID generated by the
-     * client for this event.  Note that it's possible to receive chunks
-     * in reply packets for which we are not registered.
-     *
-     * The handler may not modify the contents of "data".
-     */
-    abstract void handleChunk(Client client, int type,
-        ByteBuffer data, boolean isReply, int msgId);
-
-    /**
-     * Handle chunks not recognized by handlers.  The handleChunk() method
-     * in sub-classes should call this if the chunk type isn't recognized.
-     */
-    protected void handleUnknownChunk(Client client, int type,
-        ByteBuffer data, boolean isReply, int msgId) {
-        if (type == CHUNK_FAIL) {
-            int errorCode, msgLen;
-            String msg;
-
-            errorCode = data.getInt();
-            msgLen = data.getInt();
-            msg = getString(data, msgLen);
-            Log.w("ddms", "WARNING: failure code=" + errorCode + " msg=" + msg);
-        } else {
-            Log.w("ddms", "WARNING: received unknown chunk " + name(type)
-                + ": len=" + data.limit() + ", reply=" + isReply
-                + ", msgId=0x" + Integer.toHexString(msgId));
-        }
-        Log.w("ddms", "         client " + client + ", handler " + this);
-    }
-
-
-    /**
-     * Utility function to copy a String out of a ByteBuffer.
-     *
-     * This is here because multiple chunk handlers can make use of it,
-     * and there's nowhere better to put it.
-     */
-    static String getString(ByteBuffer buf, int len) {
-        char[] data = new char[len];
-        for (int i = 0; i < len; i++)
-            data[i] = buf.getChar();
-        return new String(data);
-    }
-
-    /**
-     * Utility function to copy a String into a ByteBuffer.
-     */
-    static void putString(ByteBuffer buf, String str) {
-        int len = str.length();
-        for (int i = 0; i < len; i++)
-            buf.putChar(str.charAt(i));
-    }
-
-    /**
-     * Convert a 4-character string to a 32-bit type.
-     */
-    static int type(String typeName) {
-        int val = 0;
-
-        if (typeName.length() != 4) {
-            Log.e("ddms", "Type name must be 4 letter long");
-            throw new RuntimeException("Type name must be 4 letter long");
-        }
-
-        for (int i = 0; i < 4; i++) {
-            val <<= 8;
-            val |= (byte) typeName.charAt(i);
-        }
-
-        return val;
-    }
-
-    /**
-     * Convert an integer type to a 4-character string.
-     */
-    static String name(int type) {
-        char[] ascii = new char[4];
-
-        ascii[0] = (char) ((type >> 24) & 0xff);
-        ascii[1] = (char) ((type >> 16) & 0xff);
-        ascii[2] = (char) ((type >> 8) & 0xff);
-        ascii[3] = (char) (type & 0xff);
-
-        return new String(ascii);
-    }
-
-    /**
-     * Allocate a ByteBuffer with enough space to hold the JDWP packet
-     * header and one chunk header in addition to the demands of the
-     * chunk being created.
-     *
-     * "maxChunkLen" indicates the size of the chunk contents only.
-     */
-    static ByteBuffer allocBuffer(int maxChunkLen) {
-        ByteBuffer buf =
-            ByteBuffer.allocate(JdwpPacket.JDWP_HEADER_LEN + 8 +maxChunkLen);
-        buf.order(CHUNK_ORDER);
-        return buf;
-    }
-
-    /**
-     * Return the slice of the JDWP packet buffer that holds just the
-     * chunk data.
-     */
-    static ByteBuffer getChunkDataBuf(ByteBuffer jdwpBuf) {
-        ByteBuffer slice;
-
-        assert jdwpBuf.position() == 0;
-
-        jdwpBuf.position(JdwpPacket.JDWP_HEADER_LEN + CHUNK_HEADER_LEN);
-        slice = jdwpBuf.slice();
-        slice.order(CHUNK_ORDER);
-        jdwpBuf.position(0);
-
-        return slice;
-    }
-
-    /**
-     * Write the chunk header at the start of the chunk.
-     *
-     * Pass in the byte buffer returned by JdwpPacket.getPayload().
-     */
-    static void finishChunkPacket(JdwpPacket packet, int type, int chunkLen) {
-        ByteBuffer buf = packet.getPayload();
-
-        buf.putInt(0x00, type);
-        buf.putInt(0x04, chunkLen);
-
-        packet.finishPacket(CHUNK_HEADER_LEN + chunkLen);
-    }
-
-    /**
-     * Check that the client is opened with the proper debugger port for the
-     * specified application name, and if not, reopen it.
-     * @param client
-     * @param uiThread
-     * @param appName
-     * @return
-     */
-    protected static Client checkDebuggerPortForAppName(Client client, String appName) {
-        IDebugPortProvider provider = DebugPortManager.getProvider();
-        if (provider != null) {
-            Device device = client.getDeviceImpl();
-            int newPort = provider.getPort(device, appName);
-
-            if (newPort != IDebugPortProvider.NO_STATIC_PORT &&
-                    newPort != client.getDebuggerListenPort()) {
-
-                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
-                if (bridge != null) {
-                    DeviceMonitor deviceMonitor = bridge.getDeviceMonitor();
-                    if (deviceMonitor != null) {
-                        deviceMonitor.addClientToDropAndReopen(client, newPort);
-                        client = null;
-                    }
-                }
-            }
-        }
-
-        return client;
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
deleted file mode 100644
index d05fa14..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.ClientData.MethodProfilingStatus;
-import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-
-import java.io.IOException;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.util.HashMap;
-
-/**
- * This represents a single client, usually a DAlvik VM process.
- * <p/>This class gives access to basic client information, as well as methods to perform actions
- * on the client.
- * <p/>More detailed information, usually updated in real time, can be access through the
- * {@link ClientData} class. Each <code>Client</code> object has its own <code>ClientData</code>
- * accessed through {@link #getClientData()}.
- */
-public class Client {
-
-    private static final int SERVER_PROTOCOL_VERSION = 1;
-
-    /** Client change bit mask: application name change */
-    public static final int CHANGE_NAME                       = 0x0001;
-    /** Client change bit mask: debugger status change */
-    public static final int CHANGE_DEBUGGER_STATUS            = 0x0002;
-    /** Client change bit mask: debugger port change */
-    public static final int CHANGE_PORT                       = 0x0004;
-    /** Client change bit mask: thread update flag change */
-    public static final int CHANGE_THREAD_MODE                = 0x0008;
-    /** Client change bit mask: thread data updated */
-    public static final int CHANGE_THREAD_DATA                = 0x0010;
-    /** Client change bit mask: heap update flag change */
-    public static final int CHANGE_HEAP_MODE                  = 0x0020;
-    /** Client change bit mask: head data updated */
-    public static final int CHANGE_HEAP_DATA                  = 0x0040;
-    /** Client change bit mask: native heap data updated */
-    public static final int CHANGE_NATIVE_HEAP_DATA           = 0x0080;
-    /** Client change bit mask: thread stack trace updated */
-    public static final int CHANGE_THREAD_STACKTRACE          = 0x0100;
-    /** Client change bit mask: allocation information updated */
-    public static final int CHANGE_HEAP_ALLOCATIONS           = 0x0200;
-    /** Client change bit mask: allocation information updated */
-    public static final int CHANGE_HEAP_ALLOCATION_STATUS     = 0x0400;
-    /** Client change bit mask: allocation information updated */
-    public static final int CHANGE_METHOD_PROFILING_STATUS    = 0x0800;
-
-    /** Client change bit mask: combination of {@link Client#CHANGE_NAME},
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, and {@link Client#CHANGE_PORT}.
-     */
-    public static final int CHANGE_INFO = CHANGE_NAME | CHANGE_DEBUGGER_STATUS | CHANGE_PORT;
-
-    private SocketChannel mChan;
-
-    // debugger we're associated with, if any
-    private Debugger mDebugger;
-    private int mDebuggerListenPort;
-
-    // list of IDs for requests we have sent to the client
-    private HashMap<Integer,ChunkHandler> mOutstandingReqs;
-
-    // chunk handlers stash state data in here
-    private ClientData mClientData;
-
-    // User interface state.  Changing the value causes a message to be
-    // sent to the client.
-    private boolean mThreadUpdateEnabled;
-    private boolean mHeapUpdateEnabled;
-
-    /*
-     * Read/write buffers.  We can get large quantities of data from the
-     * client, e.g. the response to a "give me the list of all known classes"
-     * request from the debugger.  Requests from the debugger, and from us,
-     * are much smaller.
-     *
-     * Pass-through debugger traffic is sent without copying.  "mWriteBuffer"
-     * is only used for data generated within Client.
-     */
-    private static final int INITIAL_BUF_SIZE = 2*1024;
-    private static final int MAX_BUF_SIZE = 200*1024*1024;
-    private ByteBuffer mReadBuffer;
-
-    private static final int WRITE_BUF_SIZE = 256;
-    private ByteBuffer mWriteBuffer;
-
-    private Device mDevice;
-
-    private int mConnState;
-
-    private static final int ST_INIT         = 1;
-    private static final int ST_NOT_JDWP     = 2;
-    private static final int ST_AWAIT_SHAKE  = 10;
-    private static final int ST_NEED_DDM_PKT = 11;
-    private static final int ST_NOT_DDM      = 12;
-    private static final int ST_READY        = 13;
-    private static final int ST_ERROR        = 20;
-    private static final int ST_DISCONNECTED = 21;
-
-
-    /**
-     * Create an object for a new client connection.
-     *
-     * @param device the device this client belongs to
-     * @param chan the connected {@link SocketChannel}.
-     * @param pid the client pid.
-     */
-    Client(Device device, SocketChannel chan, int pid) {
-        mDevice = device;
-        mChan = chan;
-
-        mReadBuffer = ByteBuffer.allocate(INITIAL_BUF_SIZE);
-        mWriteBuffer = ByteBuffer.allocate(WRITE_BUF_SIZE);
-
-        mOutstandingReqs = new HashMap<Integer,ChunkHandler>();
-
-        mConnState = ST_INIT;
-
-        mClientData = new ClientData(pid);
-
-        mThreadUpdateEnabled = DdmPreferences.getInitialThreadUpdate();
-        mHeapUpdateEnabled = DdmPreferences.getInitialHeapUpdate();
-    }
-
-    /**
-     * Returns a string representation of the {@link Client} object.
-     */
-    @Override
-    public String toString() {
-        return "[Client pid: " + mClientData.getPid() + "]";
-    }
-
-    /**
-     * Returns the {@link IDevice} on which this Client is running.
-     */
-    public IDevice getDevice() {
-        return mDevice;
-    }
-
-    /** Returns the {@link Device} on which this Client is running.
-     */
-    Device getDeviceImpl() {
-        return mDevice;
-    }
-
-    /**
-     * Returns the debugger port for this client.
-     */
-    public int getDebuggerListenPort() {
-        return mDebuggerListenPort;
-    }
-
-    /**
-     * Returns <code>true</code> if the client VM is DDM-aware.
-     *
-     * Calling here is only allowed after the connection has been
-     * established.
-     */
-    public boolean isDdmAware() {
-        switch (mConnState) {
-            case ST_INIT:
-            case ST_NOT_JDWP:
-            case ST_AWAIT_SHAKE:
-            case ST_NEED_DDM_PKT:
-            case ST_NOT_DDM:
-            case ST_ERROR:
-            case ST_DISCONNECTED:
-                return false;
-            case ST_READY:
-                return true;
-            default:
-                assert false;
-                return false;
-        }
-    }
-
-    /**
-     * Returns <code>true</code> if a debugger is currently attached to the client.
-     */
-    public boolean isDebuggerAttached() {
-        return mDebugger.isDebuggerAttached();
-    }
-
-    /**
-     * Return the Debugger object associated with this client.
-     */
-    Debugger getDebugger() {
-        return mDebugger;
-    }
-
-    /**
-     * Returns the {@link ClientData} object containing this client information.
-     */
-    public ClientData getClientData() {
-        return mClientData;
-    }
-
-    /**
-     * Forces the client to execute its garbage collector.
-     */
-    public void executeGarbageCollector() {
-        try {
-            HandleHeap.sendHPGC(this);
-        } catch (IOException ioe) {
-            Log.w("ddms", "Send of HPGC message failed");
-            // ignore
-        }
-    }
-
-    /**
-     * Makes the VM dump an HPROF file
-     */
-    public void dumpHprof() {
-        try {
-            String file = "/sdcard/" + mClientData.getClientDescription().replaceAll("\\:.*", "") +
-                ".hprof";
-            HandleHeap.sendHPDU(this, file);
-        } catch (IOException e) {
-            Log.w("ddms", "Send of HPDU message failed");
-            // ignore
-        }
-    }
-
-    public void toggleMethodProfiling() {
-        try {
-            if (mClientData.getMethodProfilingStatus() == MethodProfilingStatus.ON) {
-                HandleProfiling.sendMPRE(this);
-            } else {
-                String file = "/sdcard/" + mClientData.getClientDescription().replaceAll("\\:.*", "") +
-                ".trace";
-                HandleProfiling.sendMPRS(this, file, 8*1024*1024, 0 /*flags*/);
-            }
-        } catch (IOException e) {
-            Log.w("ddms", "Toggle method profiling failed");
-            // ignore
-        }
-    }
-
-    /**
-     * Sends a request to the VM to send the enable status of the method profiling.
-     * This is asynchronous.
-     * <p/>The allocation status can be accessed by {@link ClientData#getAllocationStatus()}.
-     * The notification that the new status is available will be received through
-     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
-     * containing the mask {@link #CHANGE_HEAP_ALLOCATION_STATUS}.
-     */
-    public void requestMethodProfilingStatus() {
-        try {
-            HandleHeap.sendREAQ(this);
-        } catch (IOException e) {
-            Log.e("ddmlib", e);
-        }
-    }
-
-
-    /**
-     * Enables or disables the thread update.
-     * <p/>If <code>true</code> the VM will be able to send thread information. Thread information
-     * must be requested with {@link #requestThreadUpdate()}.
-     * @param enabled the enable flag.
-     */
-    public void setThreadUpdateEnabled(boolean enabled) {
-        mThreadUpdateEnabled = enabled;
-        if (enabled == false) {
-            mClientData.clearThreads();
-        }
-
-        try {
-            HandleThread.sendTHEN(this, enabled);
-        } catch (IOException ioe) {
-            // ignore it here; client will clean up shortly
-            ioe.printStackTrace();
-        }
-
-        update(CHANGE_THREAD_MODE);
-    }
-
-    /**
-     * Returns whether the thread update is enabled.
-     */
-    public boolean isThreadUpdateEnabled() {
-        return mThreadUpdateEnabled;
-    }
-
-    /**
-     * Sends a thread update request. This is asynchronous.
-     * <p/>The thread info can be accessed by {@link ClientData#getThreads()}. The notification
-     * that the new data is available will be received through
-     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
-     * containing the mask {@link #CHANGE_THREAD_DATA}.
-     */
-    public void requestThreadUpdate() {
-        HandleThread.requestThreadUpdate(this);
-    }
-
-    /**
-     * Sends a thread stack trace update request. This is asynchronous.
-     * <p/>The thread info can be accessed by {@link ClientData#getThreads()} and
-     * {@link ThreadInfo#getStackTrace()}.
-     * <p/>The notification that the new data is available
-     * will be received through {@link IClientChangeListener#clientChanged(Client, int)}
-     * with a <code>changeMask</code> containing the mask {@link #CHANGE_THREAD_STACKTRACE}.
-     */
-    public void requestThreadStackTrace(int threadId) {
-        HandleThread.requestThreadStackCallRefresh(this, threadId);
-    }
-
-    /**
-     * Enables or disables the heap update.
-     * <p/>If <code>true</code>, any GC will cause the client to send its heap information.
-     * <p/>The heap information can be accessed by {@link ClientData#getVmHeapData()}.
-     * <p/>The notification that the new data is available
-     * will be received through {@link IClientChangeListener#clientChanged(Client, int)}
-     * with a <code>changeMask</code> containing the value {@link #CHANGE_HEAP_DATA}.
-     * @param enabled the enable flag
-     */
-    public void setHeapUpdateEnabled(boolean enabled) {
-        mHeapUpdateEnabled = enabled;
-
-        try {
-            HandleHeap.sendHPIF(this,
-                    enabled ? HandleHeap.HPIF_WHEN_EVERY_GC : HandleHeap.HPIF_WHEN_NEVER);
-
-            HandleHeap.sendHPSG(this,
-                    enabled ? HandleHeap.WHEN_GC : HandleHeap.WHEN_DISABLE,
-                    HandleHeap.WHAT_MERGE);
-        } catch (IOException ioe) {
-            // ignore it here; client will clean up shortly
-        }
-
-        update(CHANGE_HEAP_MODE);
-    }
-
-    /**
-     * Returns whether the heap update is enabled.
-     * @see #setHeapUpdateEnabled(boolean)
-     */
-    public boolean isHeapUpdateEnabled() {
-        return mHeapUpdateEnabled;
-    }
-
-    /**
-     * Sends a native heap update request. this is asynchronous.
-     * <p/>The native heap info can be accessed by {@link ClientData#getNativeAllocationList()}.
-     * The notification that the new data is available will be received through
-     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
-     * containing the mask {@link #CHANGE_NATIVE_HEAP_DATA}.
-     */
-    public boolean requestNativeHeapInformation() {
-        try {
-            HandleNativeHeap.sendNHGT(this);
-            return true;
-        } catch (IOException e) {
-            Log.e("ddmlib", e);
-        }
-
-        return false;
-    }
-
-    /**
-     * Enables or disables the Allocation tracker for this client.
-     * <p/>If enabled, the VM will start tracking allocation informations. A call to
-     * {@link #requestAllocationDetails()} will make the VM sends the information about all the
-     * allocations that happened between the enabling and the request.
-     * @param enable
-     * @see #requestAllocationDetails()
-     */
-    public void enableAllocationTracker(boolean enable) {
-        try {
-            HandleHeap.sendREAE(this, enable);
-        } catch (IOException e) {
-            Log.e("ddmlib", e);
-        }
-    }
-
-    /**
-     * Sends a request to the VM to send the enable status of the allocation tracking.
-     * This is asynchronous.
-     * <p/>The allocation status can be accessed by {@link ClientData#getAllocationStatus()}.
-     * The notification that the new status is available will be received through
-     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
-     * containing the mask {@link #CHANGE_HEAP_ALLOCATION_STATUS}.
-     */
-    public void requestAllocationStatus() {
-        try {
-            HandleHeap.sendREAQ(this);
-        } catch (IOException e) {
-            Log.e("ddmlib", e);
-        }
-    }
-
-    /**
-     * Sends a request to the VM to send the information about all the allocations that have
-     * happened since the call to {@link #enableAllocationTracker(boolean)} with <var>enable</var>
-     * set to <code>null</code>. This is asynchronous.
-     * <p/>The allocation information can be accessed by {@link ClientData#getAllocations()}.
-     * The notification that the new data is available will be received through
-     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
-     * containing the mask {@link #CHANGE_HEAP_ALLOCATIONS}.
-     */
-    public void requestAllocationDetails() {
-        try {
-            HandleHeap.sendREAL(this);
-        } catch (IOException e) {
-            Log.e("ddmlib", e);
-        }
-    }
-
-    /**
-     * Sends a kill message to the VM.
-     */
-    public void kill() {
-        try {
-            HandleExit.sendEXIT(this, 1);
-        } catch (IOException ioe) {
-            Log.w("ddms", "Send of EXIT message failed");
-            // ignore
-        }
-    }
-
-    /**
-     * Registers the client with a Selector.
-     */
-    void register(Selector sel) throws IOException {
-        if (mChan != null) {
-            mChan.register(sel, SelectionKey.OP_READ, this);
-        }
-    }
-
-    /**
-     * Sets the client to accept debugger connection on the "selected debugger port".
-     *
-     * @see AndroidDebugBridge#setSelectedClient(Client)
-     * @see DdmPreferences#setSelectedDebugPort(int)
-     */
-    public void setAsSelectedClient() {
-        MonitorThread monitorThread = MonitorThread.getInstance();
-        if (monitorThread != null) {
-            monitorThread.setSelectedClient(this);
-        }
-    }
-
-    /**
-     * Returns whether this client is the current selected client, accepting debugger connection
-     * on the "selected debugger port".
-     *
-     * @see #setAsSelectedClient()
-     * @see AndroidDebugBridge#setSelectedClient(Client)
-     * @see DdmPreferences#setSelectedDebugPort(int)
-     */
-    public boolean isSelectedClient() {
-        MonitorThread monitorThread = MonitorThread.getInstance();
-        if (monitorThread != null) {
-            return monitorThread.getSelectedClient() == this;
-        }
-
-        return false;
-    }
-
-    /**
-     * Tell the client to open a server socket channel and listen for
-     * connections on the specified port.
-     */
-    void listenForDebugger(int listenPort) throws IOException {
-        mDebuggerListenPort = listenPort;
-        mDebugger = new Debugger(this, listenPort);
-    }
-
-    /**
-     * Initiate the JDWP handshake.
-     *
-     * On failure, closes the socket and returns false.
-     */
-    boolean sendHandshake() {
-        assert mWriteBuffer.position() == 0;
-
-        try {
-            // assume write buffer can hold 14 bytes
-            JdwpPacket.putHandshake(mWriteBuffer);
-            int expectedLen = mWriteBuffer.position();
-            mWriteBuffer.flip();
-            if (mChan.write(mWriteBuffer) != expectedLen)
-                throw new IOException("partial handshake write");
-        }
-        catch (IOException ioe) {
-            Log.e("ddms-client", "IO error during handshake: " + ioe.getMessage());
-            mConnState = ST_ERROR;
-            close(true /* notify */);
-            return false;
-        }
-        finally {
-            mWriteBuffer.clear();
-        }
-
-        mConnState = ST_AWAIT_SHAKE;
-
-        return true;
-    }
-
-
-    /**
-     * Send a non-DDM packet to the client.
-     *
-     * Equivalent to sendAndConsume(packet, null).
-     */
-    void sendAndConsume(JdwpPacket packet) throws IOException {
-        sendAndConsume(packet, null);
-    }
-
-    /**
-     * Send a DDM packet to the client.
-     *
-     * Ideally, we can do this with a single channel write.  If that doesn't
-     * happen, we have to prevent anybody else from writing to the channel
-     * until this packet completes, so we synchronize on the channel.
-     *
-     * Another goal is to avoid unnecessary buffer copies, so we write
-     * directly out of the JdwpPacket's ByteBuffer.
-     */
-    void sendAndConsume(JdwpPacket packet, ChunkHandler replyHandler)
-        throws IOException {
-
-        if (mChan == null) {
-            // can happen for e.g. THST packets
-            Log.v("ddms", "Not sending packet -- client is closed");
-            return;
-        }
-
-        if (replyHandler != null) {
-            /*
-             * Add the ID to the list of outstanding requests.  We have to do
-             * this before sending the packet, in case the response comes back
-             * before our thread returns from the packet-send function.
-             */
-            addRequestId(packet.getId(), replyHandler);
-        }
-
-        synchronized (mChan) {
-            try {
-                packet.writeAndConsume(mChan);
-            }
-            catch (IOException ioe) {
-                removeRequestId(packet.getId());
-                throw ioe;
-            }
-        }
-    }
-
-    /**
-     * Forward the packet to the debugger (if still connected to one).
-     *
-     * Consumes the packet.
-     */
-    void forwardPacketToDebugger(JdwpPacket packet)
-        throws IOException {
-
-        Debugger dbg = mDebugger;
-
-        if (dbg == null) {
-            Log.d("ddms", "Discarding packet");
-            packet.consume();
-        } else {
-            dbg.sendAndConsume(packet);
-        }
-    }
-
-    /**
-     * Read data from our channel.
-     *
-     * This is called when data is known to be available, and we don't yet
-     * have a full packet in the buffer.  If the buffer is at capacity,
-     * expand it.
-     */
-    void read()
-        throws IOException, BufferOverflowException {
-
-        int count;
-
-        if (mReadBuffer.position() == mReadBuffer.capacity()) {
-            if (mReadBuffer.capacity() * 2 > MAX_BUF_SIZE) {
-                Log.e("ddms", "Exceeded MAX_BUF_SIZE!");
-                throw new BufferOverflowException();
-            }
-            Log.d("ddms", "Expanding read buffer to "
-                + mReadBuffer.capacity() * 2);
-
-            ByteBuffer newBuffer = ByteBuffer.allocate(mReadBuffer.capacity() * 2);
-
-            // copy entire buffer to new buffer
-            mReadBuffer.position(0);
-            newBuffer.put(mReadBuffer);  // leaves "position" at end of copied
-
-            mReadBuffer = newBuffer;
-        }
-
-        count = mChan.read(mReadBuffer);
-        if (count < 0)
-            throw new IOException("read failed");
-
-        if (Log.Config.LOGV) Log.v("ddms", "Read " + count + " bytes from " + this);
-        //Log.hexDump("ddms", Log.DEBUG, mReadBuffer.array(),
-        //    mReadBuffer.arrayOffset(), mReadBuffer.position());
-    }
-
-    /**
-     * Return information for the first full JDWP packet in the buffer.
-     *
-     * If we don't yet have a full packet, return null.
-     *
-     * If we haven't yet received the JDWP handshake, we watch for it here
-     * and consume it without admitting to have done so.  Upon receipt
-     * we send out the "HELO" message, which is why this can throw an
-     * IOException.
-     */
-    JdwpPacket getJdwpPacket() throws IOException {
-
-        /*
-         * On entry, the data starts at offset 0 and ends at "position".
-         * "limit" is set to the buffer capacity.
-         */
-        if (mConnState == ST_AWAIT_SHAKE) {
-            /*
-             * The first thing we get from the client is a response to our
-             * handshake.  It doesn't look like a packet, so we have to
-             * handle it specially.
-             */
-            int result;
-
-            result = JdwpPacket.findHandshake(mReadBuffer);
-            //Log.v("ddms", "findHand: " + result);
-            switch (result) {
-                case JdwpPacket.HANDSHAKE_GOOD:
-                    Log.d("ddms",
-                        "Good handshake from client, sending HELO to " + mClientData.getPid());
-                    JdwpPacket.consumeHandshake(mReadBuffer);
-                    mConnState = ST_NEED_DDM_PKT;
-                    HandleHello.sendHelloCommands(this, SERVER_PROTOCOL_VERSION);
-                    // see if we have another packet in the buffer
-                    return getJdwpPacket();
-                case JdwpPacket.HANDSHAKE_BAD:
-                    Log.d("ddms", "Bad handshake from client");
-                    if (MonitorThread.getInstance().getRetryOnBadHandshake()) {
-                        // we should drop the client, but also attempt to reopen it.
-                        // This is done by the DeviceMonitor.
-                        mDevice.getMonitor().addClientToDropAndReopen(this,
-                                IDebugPortProvider.NO_STATIC_PORT);
-                    } else {
-                        // mark it as bad, close the socket, and don't retry
-                        mConnState = ST_NOT_JDWP;
-                        close(true /* notify */);
-                    }
-                    break;
-                case JdwpPacket.HANDSHAKE_NOTYET:
-                    Log.d("ddms", "No handshake from client yet.");
-                    break;
-                default:
-                    Log.e("ddms", "Unknown packet while waiting for client handshake");
-            }
-            return null;
-        } else if (mConnState == ST_NEED_DDM_PKT ||
-            mConnState == ST_NOT_DDM ||
-            mConnState == ST_READY) {
-            /*
-             * Normal packet traffic.
-             */
-            if (mReadBuffer.position() != 0) {
-                if (Log.Config.LOGV) Log.v("ddms",
-                    "Checking " + mReadBuffer.position() + " bytes");
-            }
-            return JdwpPacket.findPacket(mReadBuffer);
-        } else {
-            /*
-             * Not expecting data when in this state.
-             */
-            Log.e("ddms", "Receiving data in state = " + mConnState);
-        }
-
-        return null;
-    }
-
-    /*
-     * Add the specified ID to the list of request IDs for which we await
-     * a response.
-     */
-    private void addRequestId(int id, ChunkHandler handler) {
-        synchronized (mOutstandingReqs) {
-            if (Log.Config.LOGV) Log.v("ddms",
-                "Adding req 0x" + Integer.toHexString(id) +" to set");
-            mOutstandingReqs.put(id, handler);
-        }
-    }
-
-    /*
-     * Remove the specified ID from the list, if present.
-     */
-    void removeRequestId(int id) {
-        synchronized (mOutstandingReqs) {
-            if (Log.Config.LOGV) Log.v("ddms",
-                "Removing req 0x" + Integer.toHexString(id) + " from set");
-            mOutstandingReqs.remove(id);
-        }
-
-        //Log.w("ddms", "Request " + Integer.toHexString(id)
-        //    + " could not be removed from " + this);
-    }
-
-    /**
-     * Determine whether this is a response to a request we sent earlier.
-     * If so, return the ChunkHandler responsible.
-     */
-    ChunkHandler isResponseToUs(int id) {
-
-        synchronized (mOutstandingReqs) {
-            ChunkHandler handler = mOutstandingReqs.get(id);
-            if (handler != null) {
-                if (Log.Config.LOGV) Log.v("ddms",
-                    "Found 0x" + Integer.toHexString(id)
-                    + " in request set - " + handler);
-                return handler;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * An earlier request resulted in a failure.  This is the expected
-     * response to a HELO message when talking to a non-DDM client.
-     */
-    void packetFailed(JdwpPacket reply) {
-        if (mConnState == ST_NEED_DDM_PKT) {
-            Log.d("ddms", "Marking " + this + " as non-DDM client");
-            mConnState = ST_NOT_DDM;
-        } else if (mConnState != ST_NOT_DDM) {
-            Log.w("ddms", "WEIRD: got JDWP failure packet on DDM req");
-        }
-    }
-
-    /**
-     * The MonitorThread calls this when it sees a DDM request or reply.
-     * If we haven't seen a DDM packet before, we advance the state to
-     * ST_READY and return "false".  Otherwise, just return true.
-     *
-     * The idea is to let the MonitorThread know when we first see a DDM
-     * packet, so we can send a broadcast to the handlers when a client
-     * connection is made.  This method is synchronized so that we only
-     * send the broadcast once.
-     */
-    synchronized boolean ddmSeen() {
-        if (mConnState == ST_NEED_DDM_PKT) {
-            mConnState = ST_READY;
-            return false;
-        } else if (mConnState != ST_READY) {
-            Log.w("ddms", "WEIRD: in ddmSeen with state=" + mConnState);
-        }
-        return true;
-    }
-
-    /**
-     * Close the client socket channel.  If there is a debugger associated
-     * with us, close that too.
-     *
-     * Closing a channel automatically unregisters it from the selector.
-     * However, we have to iterate through the selector loop before it
-     * actually lets them go and allows the file descriptors to close.
-     * The caller is expected to manage that.
-     * @param notify Whether or not to notify the listeners of a change.
-     */
-    void close(boolean notify) {
-        Log.d("ddms", "Closing " + this.toString());
-
-        mOutstandingReqs.clear();
-
-        try {
-            if (mChan != null) {
-                mChan.close();
-                mChan = null;
-            }
-
-            if (mDebugger != null) {
-                mDebugger.close();
-                mDebugger = null;
-            }
-        }
-        catch (IOException ioe) {
-            Log.w("ddms", "failed to close " + this);
-            // swallow it -- not much else to do
-        }
-
-        mDevice.removeClient(this, notify);
-    }
-
-    /**
-     * Returns whether this {@link Client} has a valid connection to the application VM.
-     */
-    public boolean isValid() {
-        return mChan != null;
-    }
-
-    void update(int changeMask) {
-        mDevice.update(this, changeMask);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java
deleted file mode 100644
index 356f5d0..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.HeapSegment.HeapSegmentElement;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-
-/**
- * Contains the data of a {@link Client}.
- */
-public class ClientData {
-    /* This is a place to stash data associated with a Client, such as thread
-    * states or heap data.  ClientData maps 1:1 to Client, but it's a little
-    * cleaner if we separate the data out.
-    *
-    * Message handlers are welcome to stash arbitrary data here.
-    *
-    * IMPORTANT: The data here is written by HandleFoo methods and read by
-    * FooPanel methods, which run in different threads.  All non-trivial
-    * access should be synchronized against the ClientData object.
-    */
-
-
-    /** Temporary name of VM to be ignored. */
-    private final static String PRE_INITIALIZED = "<pre-initialized>"; //$NON-NLS-1$
-
-    public static enum DebuggerStatus {
-        /** Debugger connection status: not waiting on one, not connected to one, but accepting
-         * new connections. This is the default value. */
-        DEFAULT,
-        /**
-         * Debugger connection status: the application's VM is paused, waiting for a debugger to
-         * connect to it before resuming. */
-        WAITING,
-        /** Debugger connection status : Debugger is connected */
-        ATTACHED,
-        /** Debugger connection status: The listening port for debugger connection failed to listen.
-         * No debugger will be able to connect. */
-        ERROR;
-    }
-
-    public static enum AllocationTrackingStatus {
-        /**
-         * Allocation tracking status: unknown.
-         * <p/>This happens right after a {@link Client} is discovered
-         * by the {@link AndroidDebugBridge}, and before the {@link Client} answered the query
-         * regarding its allocation tracking status.
-         * @see Client#requestAllocationStatus()
-         */
-        UNKNOWN,
-        /** Allocation tracking status: the {@link Client} is not tracking allocations. */
-        OFF,
-        /** Allocation tracking status: the {@link Client} is tracking allocations. */
-        ON;
-    }
-
-    public static enum MethodProfilingStatus {
-        /**
-         * Method profiling status: unknown.
-         * <p/>This happens right after a {@link Client} is discovered
-         * by the {@link AndroidDebugBridge}, and before the {@link Client} answered the query
-         * regarding its method profiling status.
-         * @see Client#requestMethodProfilingStatus()
-         */
-        UNKNOWN,
-        /** Method profiling status: the {@link Client} is not profiling method calls. */
-        OFF,
-        /** Method profiling status: the {@link Client} is profiling method calls. */
-        ON;
-    }
-
-    /**
-     * Name of the value representing the max size of the heap, in the {@link Map} returned by
-     * {@link #getVmHeapInfo(int)}
-     */
-    public final static String HEAP_MAX_SIZE_BYTES = "maxSizeInBytes"; // $NON-NLS-1$
-    /**
-     * Name of the value representing the size of the heap, in the {@link Map} returned by
-     * {@link #getVmHeapInfo(int)}
-     */
-    public final static String HEAP_SIZE_BYTES = "sizeInBytes"; // $NON-NLS-1$
-    /**
-     * Name of the value representing the number of allocated bytes of the heap, in the
-     * {@link Map} returned by {@link #getVmHeapInfo(int)}
-     */
-    public final static String HEAP_BYTES_ALLOCATED = "bytesAllocated"; // $NON-NLS-1$
-    /**
-     * Name of the value representing the number of objects in the heap, in the {@link Map}
-     * returned by {@link #getVmHeapInfo(int)}
-     */
-    public final static String HEAP_OBJECTS_ALLOCATED = "objectsAllocated"; // $NON-NLS-1$
-
-    /**
-     * String for feature enabling starting/stopping method profiling
-     * @see #hasFeature(String)
-     */
-    public final static String FEATURE_PROFILING = "method-trace-profiling"; // $NON-NLS-1$
-
-    /**
-     * String for feature allowing to dump hprof files
-     * @see #hasFeature(String)
-     */
-    public final static String FEATURE_HPROF = "hprof-heap-dump"; // $NON-NLS-1$
-
-    private static IHprofDumpHandler sHprofDumpHandler;
-    private static IMethodProfilingHandler sMethodProfilingHandler;
-
-    // is this a DDM-aware client?
-    private boolean mIsDdmAware;
-
-    // the client's process ID
-    private final int mPid;
-
-    // Java VM identification string
-    private String mVmIdentifier;
-
-    // client's self-description
-    private String mClientDescription;
-
-    // how interested are we in a debugger?
-    private DebuggerStatus mDebuggerInterest;
-
-    // List of supported features by the client.
-    private final HashSet<String> mFeatures = new HashSet<String>();
-
-    // Thread tracking (THCR, THDE).
-    private TreeMap<Integer,ThreadInfo> mThreadMap;
-
-    /** VM Heap data */
-    private final HeapData mHeapData = new HeapData();
-    /** Native Heap data */
-    private final HeapData mNativeHeapData = new HeapData();
-
-    private HashMap<Integer, HashMap<String, Long>> mHeapInfoMap =
-            new HashMap<Integer, HashMap<String, Long>>();
-
-
-    /** library map info. Stored here since the backtrace data
-     * is computed on a need to display basis.
-     */
-    private ArrayList<NativeLibraryMapInfo> mNativeLibMapInfo =
-        new ArrayList<NativeLibraryMapInfo>();
-
-    /** Native Alloc info list */
-    private ArrayList<NativeAllocationInfo> mNativeAllocationList =
-        new ArrayList<NativeAllocationInfo>();
-    private int mNativeTotalMemory;
-
-    private AllocationInfo[] mAllocations;
-    private AllocationTrackingStatus mAllocationStatus = AllocationTrackingStatus.UNKNOWN;
-
-    private String mPendingHprofDump;
-
-    private MethodProfilingStatus mProfilingStatus = MethodProfilingStatus.UNKNOWN;
-    private String mPendingMethodProfiling;
-
-    /**
-     * Heap Information.
-     * <p/>The heap is composed of several {@link HeapSegment} objects.
-     * <p/>A call to {@link #isHeapDataComplete()} will indicate if the segments (available through
-     * {@link #getHeapSegments()}) represent the full heap.
-     */
-    public static class HeapData {
-        private TreeSet<HeapSegment> mHeapSegments = new TreeSet<HeapSegment>();
-        private boolean mHeapDataComplete = false;
-        private byte[] mProcessedHeapData;
-        private Map<Integer, ArrayList<HeapSegmentElement>> mProcessedHeapMap;
-
-        /**
-         * Abandon the current list of heap segments.
-         */
-        public synchronized void clearHeapData() {
-            /* Abandon the old segments instead of just calling .clear().
-             * This lets the user hold onto the old set if it wants to.
-             */
-            mHeapSegments = new TreeSet<HeapSegment>();
-            mHeapDataComplete = false;
-        }
-
-        /**
-         * Add raw HPSG chunk data to the list of heap segments.
-         *
-         * @param data The raw data from an HPSG chunk.
-         */
-        synchronized void addHeapData(ByteBuffer data) {
-            HeapSegment hs;
-
-            if (mHeapDataComplete) {
-                clearHeapData();
-            }
-
-            try {
-                hs = new HeapSegment(data);
-            } catch (BufferUnderflowException e) {
-                System.err.println("Discarding short HPSG data (length " + data.limit() + ")");
-                return;
-            }
-
-            mHeapSegments.add(hs);
-        }
-
-        /**
-         * Called when all heap data has arrived.
-         */
-        synchronized void sealHeapData() {
-            mHeapDataComplete = true;
-        }
-
-        /**
-         * Returns whether the heap data has been sealed.
-         */
-        public boolean isHeapDataComplete() {
-            return mHeapDataComplete;
-        }
-
-        /**
-         * Get the collected heap data, if sealed.
-         *
-         * @return The list of heap segments if the heap data has been sealed, or null if it hasn't.
-         */
-        public Collection<HeapSegment> getHeapSegments() {
-            if (isHeapDataComplete()) {
-                return mHeapSegments;
-            }
-            return null;
-        }
-
-        /**
-         * Sets the processed heap data.
-         *
-         * @param heapData The new heap data (can be null)
-         */
-        public void setProcessedHeapData(byte[] heapData) {
-            mProcessedHeapData = heapData;
-        }
-
-        /**
-         * Get the processed heap data, if present.
-         *
-         * @return the processed heap data, or null.
-         */
-        public byte[] getProcessedHeapData() {
-            return mProcessedHeapData;
-        }
-
-        public void setProcessedHeapMap(Map<Integer, ArrayList<HeapSegmentElement>> heapMap) {
-            mProcessedHeapMap = heapMap;
-        }
-
-        public Map<Integer, ArrayList<HeapSegmentElement>> getProcessedHeapMap() {
-            return mProcessedHeapMap;
-        }
-    }
-
-    /**
-     * Handlers able to act on HPROF dumps.
-     */
-    public interface IHprofDumpHandler {
-        /**
-         * Called when a HPROF dump succeeded.
-         * @param remoteFilePath the device-side path of the HPROF file.
-         * @param client the client for which the HPROF file was.
-         */
-        void onSuccess(String remoteFilePath, Client client);
-
-        /**
-         * Called when the HPROF dump failed.
-         * @param client the client for which the HPROF file was.
-         */
-        void onFailure(Client client);
-    }
-
-    /**
-     * Handlers able to act on Method profiling info
-     */
-    public interface IMethodProfilingHandler {
-        /**
-         * Called when a method tracing was successful.
-         * @param remoteFilePath the device-side path of the trace file.
-         * @param client the client that was profiled.
-         */
-        void onSuccess(String remoteFilePath, Client client);
-
-        /**
-         * Called when method tracing failed.
-         * @param client the client that was profiled.
-         */
-        void onFailure(Client client);
-    }
-
-    /**
-     * Sets the handler to receive notifications when an HPROF dump succeeded or failed.
-     */
-    public static void setHprofDumpHandler(IHprofDumpHandler handler) {
-        sHprofDumpHandler = handler;
-    }
-
-    static IHprofDumpHandler getHprofDumpHandler() {
-        return sHprofDumpHandler;
-    }
-
-    /**
-     * Sets the handler to receive notifications when an HPROF dump succeeded or failed.
-     */
-    public static void setMethodProfilingHandler(IMethodProfilingHandler handler) {
-        sMethodProfilingHandler = handler;
-    }
-
-    static IMethodProfilingHandler getMethodProfilingHandler() {
-        return sMethodProfilingHandler;
-    }
-
-    /**
-     * Generic constructor.
-     */
-    ClientData(int pid) {
-        mPid = pid;
-
-        mDebuggerInterest = DebuggerStatus.DEFAULT;
-        mThreadMap = new TreeMap<Integer,ThreadInfo>();
-    }
-
-    /**
-     * Returns whether the process is DDM-aware.
-     */
-    public boolean isDdmAware() {
-        return mIsDdmAware;
-    }
-
-    /**
-     * Sets DDM-aware status.
-     */
-    void isDdmAware(boolean aware) {
-        mIsDdmAware = aware;
-    }
-
-    /**
-     * Returns the process ID.
-     */
-    public int getPid() {
-        return mPid;
-    }
-
-    /**
-     * Returns the Client's VM identifier.
-     */
-    public String getVmIdentifier() {
-        return mVmIdentifier;
-    }
-
-    /**
-     * Sets VM identifier.
-     */
-    void setVmIdentifier(String ident) {
-        mVmIdentifier = ident;
-    }
-
-    /**
-     * Returns the client description.
-     * <p/>This is generally the name of the package defined in the
-     * <code>AndroidManifest.xml</code>.
-     *
-     * @return the client description or <code>null</code> if not the description was not yet
-     * sent by the client.
-     */
-    public String getClientDescription() {
-        return mClientDescription;
-    }
-
-    /**
-     * Sets client description.
-     *
-     * There may be a race between HELO and APNM.  Rather than try
-     * to enforce ordering on the device, we just don't allow an empty
-     * name to replace a specified one.
-     */
-    void setClientDescription(String description) {
-        if (mClientDescription == null && description.length() > 0) {
-            /*
-             * The application VM is first named <pre-initialized> before being assigned
-             * its real name.
-             * Depending on the timing, we can get an APNM chunk setting this name before
-             * another one setting the final actual name. So if we get a SetClientDescription
-             * with this value we ignore it.
-             */
-            if (PRE_INITIALIZED.equals(description) == false) {
-                mClientDescription = description;
-            }
-        }
-    }
-
-    /**
-     * Returns the debugger connection status.
-     */
-    public DebuggerStatus getDebuggerConnectionStatus() {
-        return mDebuggerInterest;
-    }
-
-    /**
-     * Sets debugger connection status.
-     */
-    void setDebuggerConnectionStatus(DebuggerStatus status) {
-        mDebuggerInterest = status;
-    }
-
-    /**
-     * Sets the current heap info values for the specified heap.
-     *
-     * @param heapId The heap whose info to update
-     * @param sizeInBytes The size of the heap, in bytes
-     * @param bytesAllocated The number of bytes currently allocated in the heap
-     * @param objectsAllocated The number of objects currently allocated in
-     *                         the heap
-     */
-    // TODO: keep track of timestamp, reason
-    synchronized void setHeapInfo(int heapId, long maxSizeInBytes,
-            long sizeInBytes, long bytesAllocated, long objectsAllocated) {
-        HashMap<String, Long> heapInfo = new HashMap<String, Long>();
-        heapInfo.put(HEAP_MAX_SIZE_BYTES, maxSizeInBytes);
-        heapInfo.put(HEAP_SIZE_BYTES, sizeInBytes);
-        heapInfo.put(HEAP_BYTES_ALLOCATED, bytesAllocated);
-        heapInfo.put(HEAP_OBJECTS_ALLOCATED, objectsAllocated);
-        mHeapInfoMap.put(heapId, heapInfo);
-    }
-
-    /**
-     * Returns the {@link HeapData} object for the VM.
-     */
-    public HeapData getVmHeapData() {
-        return mHeapData;
-    }
-
-    /**
-     * Returns the {@link HeapData} object for the native code.
-     */
-    HeapData getNativeHeapData() {
-        return mNativeHeapData;
-    }
-
-    /**
-     * Returns an iterator over the list of known VM heap ids.
-     * <p/>
-     * The caller must synchronize on the {@link ClientData} object while iterating.
-     *
-     * @return an iterator over the list of heap ids
-     */
-    public synchronized Iterator<Integer> getVmHeapIds() {
-        return mHeapInfoMap.keySet().iterator();
-    }
-
-    /**
-     * Returns the most-recent info values for the specified VM heap.
-     *
-     * @param heapId The heap whose info should be returned
-     * @return a map containing the info values for the specified heap.
-     *         Returns <code>null</code> if the heap ID is unknown.
-     */
-    public synchronized Map<String, Long> getVmHeapInfo(int heapId) {
-        return mHeapInfoMap.get(heapId);
-    }
-
-    /**
-     * Adds a new thread to the list.
-     */
-    synchronized void addThread(int threadId, String threadName) {
-        ThreadInfo attr = new ThreadInfo(threadId, threadName);
-        mThreadMap.put(threadId, attr);
-    }
-
-    /**
-     * Removes a thread from the list.
-     */
-    synchronized void removeThread(int threadId) {
-        mThreadMap.remove(threadId);
-    }
-
-    /**
-     * Returns the list of threads as {@link ThreadInfo} objects.
-     * <p/>The list is empty until a thread update was requested with
-     * {@link Client#requestThreadUpdate()}.
-     */
-    public synchronized ThreadInfo[] getThreads() {
-        Collection<ThreadInfo> threads = mThreadMap.values();
-        return threads.toArray(new ThreadInfo[threads.size()]);
-    }
-
-    /**
-     * Returns the {@link ThreadInfo} by thread id.
-     */
-    synchronized ThreadInfo getThread(int threadId) {
-        return mThreadMap.get(threadId);
-    }
-
-    synchronized void clearThreads() {
-        mThreadMap.clear();
-    }
-
-    /**
-     * Returns the list of {@link NativeAllocationInfo}.
-     * @see Client#requestNativeHeapInformation()
-     */
-    public synchronized List<NativeAllocationInfo> getNativeAllocationList() {
-        return Collections.unmodifiableList(mNativeAllocationList);
-    }
-
-    /**
-     * adds a new {@link NativeAllocationInfo} to the {@link Client}
-     * @param allocInfo The {@link NativeAllocationInfo} to add.
-     */
-    synchronized void addNativeAllocation(NativeAllocationInfo allocInfo) {
-        mNativeAllocationList.add(allocInfo);
-    }
-
-    /**
-     * Clear the current malloc info.
-     */
-    synchronized void clearNativeAllocationInfo() {
-        mNativeAllocationList.clear();
-    }
-
-    /**
-     * Returns the total native memory.
-     * @see Client#requestNativeHeapInformation()
-     */
-    public synchronized int getTotalNativeMemory() {
-        return mNativeTotalMemory;
-    }
-
-    synchronized void setTotalNativeMemory(int totalMemory) {
-        mNativeTotalMemory = totalMemory;
-    }
-
-    synchronized void addNativeLibraryMapInfo(long startAddr, long endAddr, String library) {
-        mNativeLibMapInfo.add(new NativeLibraryMapInfo(startAddr, endAddr, library));
-    }
-
-    /**
-     * Returns an {@link Iterator} on {@link NativeLibraryMapInfo} objects.
-     * <p/>
-     * The caller must synchronize on the {@link ClientData} object while iterating.
-     */
-    public synchronized Iterator<NativeLibraryMapInfo> getNativeLibraryMapInfo() {
-        return mNativeLibMapInfo.iterator();
-    }
-
-    synchronized void setAllocationStatus(AllocationTrackingStatus status) {
-        mAllocationStatus = status;
-    }
-
-    /**
-     * Returns the allocation tracking status.
-     * @see Client#requestAllocationStatus()
-     */
-    public synchronized AllocationTrackingStatus getAllocationStatus() {
-        return mAllocationStatus;
-    }
-
-    synchronized void setAllocations(AllocationInfo[] allocs) {
-        mAllocations = allocs;
-    }
-
-    /**
-     * Returns the list of tracked allocations.
-     * @see Client#requestAllocationDetails()
-     */
-    public synchronized AllocationInfo[] getAllocations() {
-        return mAllocations;
-    }
-
-    void addFeature(String feature) {
-        mFeatures.add(feature);
-    }
-
-    /**
-     * Returns true if the {@link Client} supports the given <var>feature</var>
-     * @param feature The feature to test.
-     * @return true if the feature is supported
-     *
-     * @see ClientData#FEATURE_PROFILING
-     * @see ClientData#FEATURE_HPROF
-     */
-    public boolean hasFeature(String feature) {
-        return mFeatures.contains(feature);
-    }
-
-    /**
-     * Sets the device-side path to the hprof file being written
-     * @param pendingHprofDump the file to the hprof file
-     */
-    void setPendingHprofDump(String pendingHprofDump) {
-        mPendingHprofDump = pendingHprofDump;
-    }
-
-    /**
-     * Returns the path to the device-side hprof file being written.
-     */
-    String getPendingHprofDump() {
-        return mPendingHprofDump;
-    }
-
-    public boolean hasPendingHprofDump() {
-        return mPendingHprofDump != null;
-    }
-
-    synchronized void setMethodProfilingStatus(MethodProfilingStatus status) {
-        mProfilingStatus = status;
-    }
-
-    /**
-     * Returns the method profiling status.
-     * @see Client#requestMethodProfilingStatus()
-     */
-    public synchronized MethodProfilingStatus getMethodProfilingStatus() {
-        return mProfilingStatus;
-    }
-
-    /**
-     * Sets the device-side path to the method profile file being written
-     * @param pendingMethodProfiling the file being written
-     */
-    void setPendingMethodProfiling(String pendingMethodProfiling) {
-        mPendingMethodProfiling = pendingMethodProfiling;
-    }
-
-    /**
-     * Returns the path to the device-side method profiling file being written.
-     */
-    String getPendingMethodProfiling() {
-        return mPendingMethodProfiling;
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmConstants.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmConstants.java
deleted file mode 100644
index d9823f3..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmConstants.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmlib;
-
-public final class DdmConstants {
-
-    public final static int PLATFORM_UNKNOWN = 0;
-    public final static int PLATFORM_LINUX = 1;
-    public final static int PLATFORM_WINDOWS = 2;
-    public final static int PLATFORM_DARWIN = 3;
-
-    /**
-     * Returns current platform, one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
-     * {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
-     */
-    public final static int CURRENT_PLATFORM = currentPlatform();
-
-    /** hprof-conv executable (with extension for the current OS)  */
-    public final static String FN_HPROF_CONVERTER = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "hprof-conv.exe" : "hprof-conv"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /** traceview executable (with extension for the current OS)  */
-    public final static String FN_TRACEVIEW = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "traceview.bat" : "traceview"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /**
-     * Returns current platform
-     *
-     * @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
-     * {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
-     */
-    public static int currentPlatform() {
-        String os = System.getProperty("os.name");          //$NON-NLS-1$
-        if (os.startsWith("Mac OS")) {                      //$NON-NLS-1$
-            return PLATFORM_DARWIN;
-        } else if (os.startsWith("Windows")) {              //$NON-NLS-1$
-            return PLATFORM_WINDOWS;
-        } else if (os.startsWith("Linux")) {                //$NON-NLS-1$
-            return PLATFORM_LINUX;
-        }
-
-        return PLATFORM_UNKNOWN;
-    }
-
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmPreferences.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmPreferences.java
deleted file mode 100644
index 8044ab1..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmPreferences.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.Log.LogLevel;
-
-/**
- * Preferences for the ddm library.
- * <p/>This class does not handle storing the preferences. It is merely a central point for
- * applications using the ddmlib to override the default values.
- * <p/>Various components of the ddmlib query this class to get their values.
- * <p/>Calls to some <code>set##()</code> methods will update the components using the values
- * right away, while other methods will have no effect once {@link AndroidDebugBridge#init(boolean)}
- * has been called.
- * <p/>Check the documentation of each method.
- */
-public final class DdmPreferences {
-
-    /** Default value for thread update flag upon client connection. */
-    public final static boolean DEFAULT_INITIAL_THREAD_UPDATE = false;
-    /** Default value for heap update flag upon client connection. */
-    public final static boolean DEFAULT_INITIAL_HEAP_UPDATE = false;
-    /** Default value for the selected client debug port */
-    public final static int DEFAULT_SELECTED_DEBUG_PORT = 8700;
-    /** Default value for the debug port base */
-    public final static int DEFAULT_DEBUG_PORT_BASE = 8600;
-    /** Default value for the logcat {@link LogLevel} */
-    public final static LogLevel DEFAULT_LOG_LEVEL = LogLevel.ERROR;
-    /** Default timeout values for adb connection (milliseconds) */
-    public static final int DEFAULT_TIMEOUT = 5000; // standard delay, in ms
-
-    private static boolean sThreadUpdate = DEFAULT_INITIAL_THREAD_UPDATE;
-    private static boolean sInitialHeapUpdate = DEFAULT_INITIAL_HEAP_UPDATE;
-
-    private static int sSelectedDebugPort = DEFAULT_SELECTED_DEBUG_PORT;
-    private static int sDebugPortBase = DEFAULT_DEBUG_PORT_BASE;
-    private static LogLevel sLogLevel = DEFAULT_LOG_LEVEL;
-    private static int sTimeOut = DEFAULT_TIMEOUT;
-
-    /**
-     * Returns the initial {@link Client} flag for thread updates.
-     * @see #setInitialThreadUpdate(boolean)
-     */
-    public static boolean getInitialThreadUpdate() {
-        return sThreadUpdate;
-    }
-
-    /**
-     * Sets the initial {@link Client} flag for thread updates.
-     * <p/>This change takes effect right away, for newly created {@link Client} objects.
-     */
-    public static void setInitialThreadUpdate(boolean state) {
-        sThreadUpdate = state;
-    }
-
-    /**
-     * Returns the initial {@link Client} flag for heap updates.
-     * @see #setInitialHeapUpdate(boolean)
-     */
-    public static boolean getInitialHeapUpdate() {
-        return sInitialHeapUpdate;
-    }
-
-    /**
-     * Sets the initial {@link Client} flag for heap updates.
-     * <p/>If <code>true</code>, the {@link ClientData} will automatically be updated with
-     * the VM heap information whenever a GC happens.
-     * <p/>This change takes effect right away, for newly created {@link Client} objects.
-     */
-    public static void setInitialHeapUpdate(boolean state) {
-        sInitialHeapUpdate = state;
-    }
-
-    /**
-     * Returns the debug port used by the selected {@link Client}.
-     */
-    public static int getSelectedDebugPort() {
-        return sSelectedDebugPort;
-    }
-
-    /**
-     * Sets the debug port used by the selected {@link Client}.
-     * <p/>This change takes effect right away.
-     * @param port the new port to use.
-     */
-    public static void setSelectedDebugPort(int port) {
-        sSelectedDebugPort = port;
-
-        MonitorThread monitorThread = MonitorThread.getInstance();
-        if (monitorThread != null) {
-            monitorThread.setDebugSelectedPort(port);
-        }
-    }
-
-    /**
-     * Returns the debug port used by the first {@link Client}. Following clients, will use the
-     * next port.
-     */
-    public static int getDebugPortBase() {
-        return sDebugPortBase;
-    }
-
-    /**
-     * Sets the debug port used by the first {@link Client}.
-     * <p/>Once a port is used, the next Client will use port + 1. Quitting applications will
-     * release their debug port, and new clients will be able to reuse them.
-     * <p/>This must be called before {@link AndroidDebugBridge#init(boolean)}.
-     */
-    public static void setDebugPortBase(int port) {
-        sDebugPortBase = port;
-    }
-
-    /**
-     * Returns the minimum {@link LogLevel} being displayed.
-     */
-    public static LogLevel getLogLevel() {
-        return sLogLevel;
-    }
-
-    /**
-     * Sets the minimum {@link LogLevel} to display.
-     * <p/>This change takes effect right away.
-     */
-    public static void setLogLevel(String value) {
-        sLogLevel = LogLevel.getByString(value);
-
-        Log.setLevel(sLogLevel);
-    }
-
-    /**
-     * Returns the timeout to be used in adb connections (milliseconds).
-     */
-    public static int getTimeOut() {
-        return sTimeOut;
-    }
-
-    /**
-     * Sets the timeout value for adb connection.
-     * <p/>This change takes effect for newly created connections only.
-     * @param timeOut the timeout value (milliseconds).
-     */
-    public static void setTimeOut(int timeOut) {
-        sTimeOut = timeOut;
-    }
-
-    /**
-     * Non accessible constructor.
-     */
-    private DdmPreferences() {
-        // pass, only static methods in the class.
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java
deleted file mode 100644
index defdc0e..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.Device;
-
-/**
- * Centralized point to provide a {@link IDebugPortProvider} to ddmlib.
- *
- * <p/>When {@link Client} objects are created, they start listening for debuggers on a specific
- * port. The default behavior is to start with {@link DdmPreferences#getDebugPortBase()} and
- * increment this value for each new <code>Client</code>.
- *
- * <p/>This {@link DebugPortManager} allows applications using ddmlib to provide a custom
- * port provider on a per-<code>Client</code> basis, depending on the device/emulator they are
- * running on, and/or their names.
- */
-public class DebugPortManager {
-
-    /**
-     * Classes which implement this interface provide a method that provides a non random
-     * debugger port for a newly created {@link Client}.
-     */
-    public interface IDebugPortProvider {
-
-        public static final int NO_STATIC_PORT = -1;
-
-        /**
-         * Returns a non-random debugger port for the specified application running on the
-         * specified {@link Device}.
-         * @param device The device the application is running on.
-         * @param appName The application name, as defined in the <code>AndroidManifest.xml</code>
-         * <var>package</var> attribute of the <var>manifest</var> node.
-         * @return The non-random debugger port or {@link #NO_STATIC_PORT} if the {@link Client}
-         * should use the automatic debugger port provider.
-         */
-        public int getPort(IDevice device, String appName);
-    }
-
-    private static IDebugPortProvider sProvider = null;
-
-    /**
-     * Sets the {@link IDebugPortProvider} that will be used when a new {@link Client} requests
-     * a debugger port.
-     * @param provider the <code>IDebugPortProvider</code> to use.
-     */
-    public static void setProvider(IDebugPortProvider provider) {
-        sProvider = provider;
-    }
-
-    /**
-     * Returns the
-     * @return
-     */
-    static IDebugPortProvider getProvider() {
-        return sProvider;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Debugger.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Debugger.java
deleted file mode 100644
index cebbc32..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Debugger.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.ClientData.DebuggerStatus;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-
-/**
- * This represents a pending or established connection with a JDWP debugger.
- */
-class Debugger {
-
-    /*
-     * Messages from the debugger should be pretty small; may not even
-     * need an expanding-buffer implementation for this.
-     */
-    private static final int INITIAL_BUF_SIZE = 1 * 1024;
-    private static final int MAX_BUF_SIZE = 32 * 1024;
-    private ByteBuffer mReadBuffer;
-
-    private static final int PRE_DATA_BUF_SIZE = 256;
-    private ByteBuffer mPreDataBuffer;
-
-    /* connection state */
-    private int mConnState;
-    private static final int ST_NOT_CONNECTED = 1;
-    private static final int ST_AWAIT_SHAKE   = 2;
-    private static final int ST_READY         = 3;
-
-    /* peer */
-    private Client mClient;         // client we're forwarding to/from
-    private int mListenPort;        // listen to me
-    private ServerSocketChannel mListenChannel;
-
-    /* this goes up and down; synchronize methods that access the field */
-    private SocketChannel mChannel;
-
-    /**
-     * Create a new Debugger object, configured to listen for connections
-     * on a specific port.
-     */
-    Debugger(Client client, int listenPort) throws IOException {
-
-        mClient = client;
-        mListenPort = listenPort;
-
-        mListenChannel = ServerSocketChannel.open();
-        mListenChannel.configureBlocking(false);        // required for Selector
-
-        InetSocketAddress addr = new InetSocketAddress(
-                InetAddress.getByName("localhost"), // $NON-NLS-1$
-                listenPort);
-        mListenChannel.socket().setReuseAddress(true);  // enable SO_REUSEADDR
-        mListenChannel.socket().bind(addr);
-
-        mReadBuffer = ByteBuffer.allocate(INITIAL_BUF_SIZE);
-        mPreDataBuffer = ByteBuffer.allocate(PRE_DATA_BUF_SIZE);
-        mConnState = ST_NOT_CONNECTED;
-
-        Log.d("ddms", "Created: " + this.toString());
-    }
-
-    /**
-     * Returns "true" if a debugger is currently attached to us.
-     */
-    boolean isDebuggerAttached() {
-        return mChannel != null;
-    }
-
-    /**
-     * Represent the Debugger as a string.
-     */
-    @Override
-    public String toString() {
-        // mChannel != null means we have connection, ST_READY means it's going
-        return "[Debugger " + mListenPort + "-->" + mClient.getClientData().getPid()
-                + ((mConnState != ST_READY) ? " inactive]" : " active]");
-    }
-
-    /**
-     * Register the debugger's listen socket with the Selector.
-     */
-    void registerListener(Selector sel) throws IOException {
-        mListenChannel.register(sel, SelectionKey.OP_ACCEPT, this);
-    }
-
-    /**
-     * Return the Client being debugged.
-     */
-    Client getClient() {
-        return mClient;
-    }
-
-    /**
-     * Accept a new connection, but only if we don't already have one.
-     *
-     * Must be synchronized with other uses of mChannel and mPreBuffer.
-     *
-     * Returns "null" if we're already talking to somebody.
-     */
-    synchronized SocketChannel accept() throws IOException {
-        return accept(mListenChannel);
-    }
-
-    /**
-     * Accept a new connection from the specified listen channel.  This
-     * is so we can listen on a dedicated port for the "current" client,
-     * where "current" is constantly in flux.
-     *
-     * Must be synchronized with other uses of mChannel and mPreBuffer.
-     *
-     * Returns "null" if we're already talking to somebody.
-     */
-    synchronized SocketChannel accept(ServerSocketChannel listenChan)
-        throws IOException {
-
-        if (listenChan != null) {
-            SocketChannel newChan;
-
-            newChan = listenChan.accept();
-            if (mChannel != null) {
-                Log.w("ddms", "debugger already talking to " + mClient
-                    + " on " + mListenPort);
-                newChan.close();
-                return null;
-            }
-            mChannel = newChan;
-            mChannel.configureBlocking(false);         // required for Selector
-            mConnState = ST_AWAIT_SHAKE;
-            return mChannel;
-        }
-
-        return null;
-    }
-
-    /**
-     * Close the data connection only.
-     */
-    synchronized void closeData() {
-        try {
-            if (mChannel != null) {
-                mChannel.close();
-                mChannel = null;
-                mConnState = ST_NOT_CONNECTED;
-
-                ClientData cd = mClient.getClientData();
-                cd.setDebuggerConnectionStatus(DebuggerStatus.DEFAULT);
-                mClient.update(Client.CHANGE_DEBUGGER_STATUS);
-            }
-        } catch (IOException ioe) {
-            Log.w("ddms", "Failed to close data " + this);
-        }
-    }
-
-    /**
-     * Close the socket that's listening for new connections and (if
-     * we're connected) the debugger data socket.
-     */
-    synchronized void close() {
-        try {
-            if (mListenChannel != null) {
-                mListenChannel.close();
-            }
-            mListenChannel = null;
-            closeData();
-        } catch (IOException ioe) {
-            Log.w("ddms", "Failed to close listener " + this);
-        }
-    }
-
-    // TODO: ?? add a finalizer that verifies the channel was closed
-
-    /**
-     * Read data from our channel.
-     *
-     * This is called when data is known to be available, and we don't yet
-     * have a full packet in the buffer.  If the buffer is at capacity,
-     * expand it.
-     */
-    void read() throws IOException {
-        int count;
-
-        if (mReadBuffer.position() == mReadBuffer.capacity()) {
-            if (mReadBuffer.capacity() * 2 > MAX_BUF_SIZE) {
-                throw new BufferOverflowException();
-            }
-            Log.d("ddms", "Expanding read buffer to "
-                + mReadBuffer.capacity() * 2);
-
-            ByteBuffer newBuffer =
-                    ByteBuffer.allocate(mReadBuffer.capacity() * 2);
-            mReadBuffer.position(0);
-            newBuffer.put(mReadBuffer);     // leaves "position" at end
-
-            mReadBuffer = newBuffer;
-        }
-
-        count = mChannel.read(mReadBuffer);
-        Log.v("ddms", "Read " + count + " bytes from " + this);
-        if (count < 0) throw new IOException("read failed");
-    }
-
-    /**
-     * Return information for the first full JDWP packet in the buffer.
-     *
-     * If we don't yet have a full packet, return null.
-     *
-     * If we haven't yet received the JDWP handshake, we watch for it here
-     * and consume it without admitting to have done so.  We also send
-     * the handshake response to the debugger, along with any pending
-     * pre-connection data, which is why this can throw an IOException.
-     */
-    JdwpPacket getJdwpPacket() throws IOException {
-        /*
-         * On entry, the data starts at offset 0 and ends at "position".
-         * "limit" is set to the buffer capacity.
-         */
-        if (mConnState == ST_AWAIT_SHAKE) {
-            int result;
-
-            result = JdwpPacket.findHandshake(mReadBuffer);
-            //Log.v("ddms", "findHand: " + result);
-            switch (result) {
-                case JdwpPacket.HANDSHAKE_GOOD:
-                    Log.d("ddms", "Good handshake from debugger");
-                    JdwpPacket.consumeHandshake(mReadBuffer);
-                    sendHandshake();
-                    mConnState = ST_READY;
-
-                    ClientData cd = mClient.getClientData();
-                    cd.setDebuggerConnectionStatus(DebuggerStatus.ATTACHED);
-                    mClient.update(Client.CHANGE_DEBUGGER_STATUS);
-
-                    // see if we have another packet in the buffer
-                    return getJdwpPacket();
-                case JdwpPacket.HANDSHAKE_BAD:
-                    // not a debugger, throw an exception so we drop the line
-                    Log.d("ddms", "Bad handshake from debugger");
-                    throw new IOException("bad handshake");
-                case JdwpPacket.HANDSHAKE_NOTYET:
-                    break;
-                default:
-                    Log.e("ddms", "Unknown packet while waiting for client handshake");
-            }
-            return null;
-        } else if (mConnState == ST_READY) {
-            if (mReadBuffer.position() != 0) {
-                Log.v("ddms", "Checking " + mReadBuffer.position() + " bytes");
-            }
-            return JdwpPacket.findPacket(mReadBuffer);
-        } else {
-            Log.e("ddms", "Receiving data in state = " + mConnState);
-        }
-
-        return null;
-    }
-
-    /**
-     * Forward a packet to the client.
-     *
-     * "mClient" will never be null, though it's possible that the channel
-     * in the client has closed and our send attempt will fail.
-     *
-     * Consumes the packet.
-     */
-    void forwardPacketToClient(JdwpPacket packet) throws IOException {
-        mClient.sendAndConsume(packet);
-    }
-
-    /**
-     * Send the handshake to the debugger.  We also send along any packets
-     * we already received from the client (usually just a VM_START event,
-     * if anything at all).
-     */
-    private synchronized void sendHandshake() throws IOException {
-        ByteBuffer tempBuffer = ByteBuffer.allocate(JdwpPacket.HANDSHAKE_LEN);
-        JdwpPacket.putHandshake(tempBuffer);
-        int expectedLength = tempBuffer.position();
-        tempBuffer.flip();
-        if (mChannel.write(tempBuffer) != expectedLength) {
-            throw new IOException("partial handshake write");
-        }
-
-        expectedLength = mPreDataBuffer.position();
-        if (expectedLength > 0) {
-            Log.d("ddms", "Sending " + mPreDataBuffer.position()
-                    + " bytes of saved data");
-            mPreDataBuffer.flip();
-            if (mChannel.write(mPreDataBuffer) != expectedLength) {
-                throw new IOException("partial pre-data write");
-            }
-            mPreDataBuffer.clear();
-        }
-    }
-
-    /**
-     * Send a packet to the debugger.
-     *
-     * Ideally, we can do this with a single channel write.  If that doesn't
-     * happen, we have to prevent anybody else from writing to the channel
-     * until this packet completes, so we synchronize on the channel.
-     *
-     * Another goal is to avoid unnecessary buffer copies, so we write
-     * directly out of the JdwpPacket's ByteBuffer.
-     *
-     * We must synchronize on "mChannel" before writing to it.  We want to
-     * coordinate the buffered data with mChannel creation, so this whole
-     * method is synchronized.
-     */
-    synchronized void sendAndConsume(JdwpPacket packet)
-        throws IOException {
-
-        if (mChannel == null) {
-            /*
-             * Buffer this up so we can send it to the debugger when it
-             * finally does connect.  This is essential because the VM_START
-             * message might be telling the debugger that the VM is
-             * suspended.  The alternative approach would be for us to
-             * capture and interpret VM_START and send it later if we
-             * didn't choose to un-suspend the VM for our own purposes.
-             */
-            Log.d("ddms", "Saving packet 0x"
-                    + Integer.toHexString(packet.getId()));
-            packet.movePacket(mPreDataBuffer);
-        } else {
-            packet.writeAndConsume(mChannel);
-        }
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
deleted file mode 100644
index e23d817..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmlib.log.LogReceiver;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-/**
- * A Device. It can be a physical device or an emulator.
- */
-final class Device implements IDevice {
-
-    /** Emulator Serial Number regexp. */
-    final static String RE_EMULATOR_SN = "emulator-(\\d+)"; //$NON-NLS-1$
-
-    /** Serial number of the device */
-    private String mSerialNumber = null;
-
-    /** Name of the AVD */
-    private String mAvdName = null;
-
-    /** State of the device. */
-    private DeviceState mState = null;
-
-    /** Device properties. */
-    private final Map<String, String> mProperties = new HashMap<String, String>();
-
-    private final ArrayList<Client> mClients = new ArrayList<Client>();
-    private DeviceMonitor mMonitor;
-
-    private static final String LOG_TAG = "Device";
-
-    /**
-     * Socket for the connection monitoring client connection/disconnection.
-     */
-    private SocketChannel mSocketChannel;
-
-    /**
-     * Output receiver for "pm install package.apk" command line.
-     */
-    private static final class InstallReceiver extends MultiLineReceiver {
-
-        private static final String SUCCESS_OUTPUT = "Success"; //$NON-NLS-1$
-        private static final Pattern FAILURE_PATTERN = Pattern.compile("Failure\\s+\\[(.*)\\]"); //$NON-NLS-1$
-
-        private String mErrorMessage = null;
-
-        public InstallReceiver() {
-        }
-
-        @Override
-        public void processNewLines(String[] lines) {
-            for (String line : lines) {
-                if (line.length() > 0) {
-                    if (line.startsWith(SUCCESS_OUTPUT)) {
-                        mErrorMessage = null;
-                    } else {
-                        Matcher m = FAILURE_PATTERN.matcher(line);
-                        if (m.matches()) {
-                            mErrorMessage = m.group(1);
-                        }
-                    }
-                }
-            }
-        }
-
-        public boolean isCancelled() {
-            return false;
-        }
-
-        public String getErrorMessage() {
-            return mErrorMessage;
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getSerialNumber()
-     */
-    public String getSerialNumber() {
-        return mSerialNumber;
-    }
-
-    /** {@inheritDoc} */
-    public String getAvdName() {
-        return mAvdName;
-    }
-
-    /**
-     * Sets the name of the AVD
-     */
-    void setAvdName(String avdName) {
-        if (isEmulator() == false) {
-            throw new IllegalArgumentException(
-                    "Cannot set the AVD name of the device is not an emulator");
-        }
-
-        mAvdName = avdName;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getState()
-     */
-    public DeviceState getState() {
-        return mState;
-    }
-
-    /**
-     * Changes the state of the device.
-     */
-    void setState(DeviceState state) {
-        mState = state;
-    }
-
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getProperties()
-     */
-    public Map<String, String> getProperties() {
-        return Collections.unmodifiableMap(mProperties);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getPropertyCount()
-     */
-    public int getPropertyCount() {
-        return mProperties.size();
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getProperty(java.lang.String)
-     */
-    public String getProperty(String name) {
-        return mProperties.get(name);
-    }
-
-
-    @Override
-    public String toString() {
-        return mSerialNumber;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#isOnline()
-     */
-    public boolean isOnline() {
-        return mState == DeviceState.ONLINE;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#isEmulator()
-     */
-    public boolean isEmulator() {
-        return mSerialNumber.matches(RE_EMULATOR_SN);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#isOffline()
-     */
-    public boolean isOffline() {
-        return mState == DeviceState.OFFLINE;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#isBootLoader()
-     */
-    public boolean isBootLoader() {
-        return mState == DeviceState.BOOTLOADER;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#hasClients()
-     */
-    public boolean hasClients() {
-        return mClients.size() > 0;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getClients()
-     */
-    public Client[] getClients() {
-        synchronized (mClients) {
-            return mClients.toArray(new Client[mClients.size()]);
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getClient(java.lang.String)
-     */
-    public Client getClient(String applicationName) {
-        synchronized (mClients) {
-            for (Client c : mClients) {
-                if (applicationName.equals(c.getClientData().getClientDescription())) {
-                    return c;
-                }
-            }
-
-        }
-
-        return null;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getSyncService()
-     */
-    public SyncService getSyncService() throws IOException {
-        SyncService syncService = new SyncService(AndroidDebugBridge.sSocketAddr, this);
-        if (syncService.openSync()) {
-            return syncService;
-         }
-
-        return null;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getFileListingService()
-     */
-    public FileListingService getFileListingService() {
-        return new FileListingService(this);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getScreenshot()
-     */
-    public RawImage getScreenshot() throws IOException {
-        return AdbHelper.getFrameBuffer(AndroidDebugBridge.sSocketAddr, this);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#executeShellCommand(java.lang.String, com.android.ddmlib.IShellOutputReceiver)
-     */
-    public void executeShellCommand(String command, IShellOutputReceiver receiver)
-            throws IOException {
-        AdbHelper.executeRemoteCommand(AndroidDebugBridge.sSocketAddr, command, this,
-                receiver);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#runEventLogService(com.android.ddmlib.log.LogReceiver)
-     */
-    public void runEventLogService(LogReceiver receiver) throws IOException {
-        AdbHelper.runEventLogService(AndroidDebugBridge.sSocketAddr, this, receiver);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#runLogService(com.android.ddmlib.log.LogReceiver)
-     */
-    public void runLogService(String logname,
-            LogReceiver receiver) throws IOException {
-        AdbHelper.runLogService(AndroidDebugBridge.sSocketAddr, this, logname, receiver);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#createForward(int, int)
-     */
-    public boolean createForward(int localPort, int remotePort) {
-        try {
-            return AdbHelper.createForward(AndroidDebugBridge.sSocketAddr, this,
-                    localPort, remotePort);
-        } catch (IOException e) {
-            Log.e("adb-forward", e); //$NON-NLS-1$
-            return false;
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#removeForward(int, int)
-     */
-    public boolean removeForward(int localPort, int remotePort) {
-        try {
-            return AdbHelper.removeForward(AndroidDebugBridge.sSocketAddr, this,
-                    localPort, remotePort);
-        } catch (IOException e) {
-            Log.e("adb-remove-forward", e); //$NON-NLS-1$
-            return false;
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IDevice#getClientName(int)
-     */
-    public String getClientName(int pid) {
-        synchronized (mClients) {
-            for (Client c : mClients) {
-                if (c.getClientData().getPid() == pid) {
-                    return c.getClientData().getClientDescription();
-                }
-            }
-        }
-
-        return null;
-    }
-
-
-    Device(DeviceMonitor monitor, String serialNumber, DeviceState deviceState) {
-        mMonitor = monitor;
-        mSerialNumber = serialNumber;
-        mState = deviceState;
-    }
-
-    DeviceMonitor getMonitor() {
-        return mMonitor;
-    }
-
-    void addClient(Client client) {
-        synchronized (mClients) {
-            mClients.add(client);
-        }
-    }
-
-    List<Client> getClientList() {
-        return mClients;
-    }
-
-    boolean hasClient(int pid) {
-        synchronized (mClients) {
-            for (Client client : mClients) {
-                if (client.getClientData().getPid() == pid) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    void clearClientList() {
-        synchronized (mClients) {
-            mClients.clear();
-        }
-    }
-
-    /**
-     * Sets the client monitoring socket.
-     * @param socketChannel the sockets
-     */
-    void setClientMonitoringSocket(SocketChannel socketChannel) {
-        mSocketChannel = socketChannel;
-    }
-
-    /**
-     * Returns the client monitoring socket.
-     */
-    SocketChannel getClientMonitoringSocket() {
-        return mSocketChannel;
-    }
-
-    /**
-     * Removes a {@link Client} from the list.
-     * @param client the client to remove.
-     * @param notify Whether or not to notify the listeners of a change.
-     */
-    void removeClient(Client client, boolean notify) {
-        mMonitor.addPortToAvailableList(client.getDebuggerListenPort());
-        synchronized (mClients) {
-            mClients.remove(client);
-        }
-        if (notify) {
-            mMonitor.getServer().deviceChanged(this, CHANGE_CLIENT_LIST);
-        }
-    }
-
-    void update(int changeMask) {
-        mMonitor.getServer().deviceChanged(this, changeMask);
-    }
-
-    void update(Client client, int changeMask) {
-        mMonitor.getServer().clientChanged(client, changeMask);
-    }
-
-    void addProperty(String label, String value) {
-        mProperties.put(label, value);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String installPackage(String packageFilePath, boolean reinstall)
-           throws IOException {
-       String remoteFilePath = syncPackageToDevice(packageFilePath);
-       String result = installRemotePackage(remoteFilePath, reinstall);
-       removeRemotePackage(remoteFilePath);
-       return result;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String syncPackageToDevice(String localFilePath)
-            throws IOException {
-        try {
-            String packageFileName = getFileName(localFilePath);
-            String remoteFilePath = String.format("/data/local/tmp/%1$s", packageFileName); //$NON-NLS-1$
-
-            Log.d(packageFileName, String.format("Uploading %1$s onto device '%2$s'",
-                    packageFileName, getSerialNumber()));
-
-            SyncService sync = getSyncService();
-            if (sync != null) {
-                String message = String.format("Uploading file onto device '%1$s'",
-                        getSerialNumber());
-                Log.d(LOG_TAG, message);
-                SyncResult result = sync.pushFile(localFilePath, remoteFilePath,
-                        SyncService.getNullProgressMonitor());
-
-                if (result.getCode() != SyncService.RESULT_OK) {
-                    throw new IOException(String.format("Unable to upload file: %1$s",
-                            result.getMessage()));
-                }
-            } else {
-                throw new IOException("Unable to open sync connection!");
-            }
-            return remoteFilePath;
-        } catch (IOException e) {
-            Log.e(LOG_TAG, String.format("Unable to open sync connection! reason: %1$s",
-                    e.getMessage()));
-            throw e;
-        }
-    }
-
-    /**
-     * Helper method to retrieve the file name given a local file path
-     * @param filePath full directory path to file
-     * @return {@link String} file name
-     */
-    private String getFileName(String filePath) {
-        return new File(filePath).getName();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String installRemotePackage(String remoteFilePath, boolean reinstall)
-            throws IOException {
-        InstallReceiver receiver = new InstallReceiver();
-        String cmd = String.format(reinstall ? "pm install -r \"%1$s\"" : "pm install \"%1$s\"",
-                            remoteFilePath);
-        executeShellCommand(cmd, receiver);
-        return receiver.getErrorMessage();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void removeRemotePackage(String remoteFilePath) throws IOException {
-        // now we delete the app we sync'ed
-        try {
-            executeShellCommand("rm " + remoteFilePath, new NullOutputReceiver());
-        } catch (IOException e) {
-            Log.e(LOG_TAG, String.format("Failed to delete temporary package: %1$s",
-                    e.getMessage()));
-            throw e;
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String uninstallPackage(String packageName) throws IOException {
-        InstallReceiver receiver = new InstallReceiver();
-        executeShellCommand("pm uninstall " + packageName, receiver);
-        return receiver.getErrorMessage();
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java
deleted file mode 100644
index 402699c..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.AdbHelper.AdbResponse;
-import com.android.ddmlib.ClientData.DebuggerStatus;
-import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
-import com.android.ddmlib.IDevice.DeviceState;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A Device monitor. This connects to the Android Debug Bridge and get device and
- * debuggable process information from it.
- */
-final class DeviceMonitor {
-    private byte[] mLengthBuffer = new byte[4];
-    private byte[] mLengthBuffer2 = new byte[4];
-
-    private boolean mQuit = false;
-
-    private AndroidDebugBridge mServer;
-
-    private SocketChannel mMainAdbConnection = null;
-    private boolean mMonitoring = false;
-    private int mConnectionAttempt = 0;
-    private int mRestartAttemptCount = 0;
-    private boolean mInitialDeviceListDone = false;
-
-    private Selector mSelector;
-
-    private final ArrayList<Device> mDevices = new ArrayList<Device>();
-
-    private final ArrayList<Integer> mDebuggerPorts = new ArrayList<Integer>();
-
-    private final HashMap<Client, Integer> mClientsToReopen = new HashMap<Client, Integer>();
-
-    /**
-     * Creates a new {@link DeviceMonitor} object and links it to the running
-     * {@link AndroidDebugBridge} object.
-     * @param server the running {@link AndroidDebugBridge}.
-     */
-    DeviceMonitor(AndroidDebugBridge server) {
-        mServer = server;
-
-        mDebuggerPorts.add(DdmPreferences.getDebugPortBase());
-    }
-
-    /**
-     * Starts the monitoring.
-     */
-    void start() {
-        new Thread("Device List Monitor") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                deviceMonitorLoop();
-            }
-        }.start();
-    }
-
-    /**
-     * Stops the monitoring.
-     */
-    void stop() {
-        mQuit = true;
-
-        // wakeup the main loop thread by closing the main connection to adb.
-        try {
-            if (mMainAdbConnection != null) {
-                mMainAdbConnection.close();
-            }
-        } catch (IOException e1) {
-        }
-
-        // wake up the secondary loop by closing the selector.
-        if (mSelector != null) {
-            mSelector.wakeup();
-        }
-    }
-
-
-
-    /**
-     * Returns if the monitor is currently connected to the debug bridge server.
-     * @return
-     */
-    boolean isMonitoring() {
-        return mMonitoring;
-    }
-
-    int getConnectionAttemptCount() {
-        return mConnectionAttempt;
-    }
-
-    int getRestartAttemptCount() {
-        return mRestartAttemptCount;
-    }
-
-    /**
-     * Returns the devices.
-     */
-    Device[] getDevices() {
-        synchronized (mDevices) {
-            return mDevices.toArray(new Device[mDevices.size()]);
-        }
-    }
-
-    boolean hasInitialDeviceList() {
-        return mInitialDeviceListDone;
-    }
-
-    AndroidDebugBridge getServer() {
-        return mServer;
-    }
-
-    void addClientToDropAndReopen(Client client, int port) {
-        synchronized (mClientsToReopen) {
-            Log.d("DeviceMonitor",
-                    "Adding " + client + " to list of client to reopen (" + port +").");
-            if (mClientsToReopen.get(client) == null) {
-                mClientsToReopen.put(client, port);
-            }
-        }
-        mSelector.wakeup();
-    }
-
-    /**
-     * Monitors the devices. This connects to the Debug Bridge
-     */
-    private void deviceMonitorLoop() {
-        do {
-            try {
-                if (mMainAdbConnection == null) {
-                    Log.d("DeviceMonitor", "Opening adb connection");
-                    mMainAdbConnection = openAdbConnection();
-                    if (mMainAdbConnection == null) {
-                        mConnectionAttempt++;
-                        Log.e("DeviceMonitor", "Connection attempts: " + mConnectionAttempt);
-                        if (mConnectionAttempt > 10) {
-                            if (mServer.startAdb() == false) {
-                                mRestartAttemptCount++;
-                                Log.e("DeviceMonitor",
-                                        "adb restart attempts: " + mRestartAttemptCount);
-                            } else {
-                                mRestartAttemptCount = 0;
-                            }
-                        }
-                        waitABit();
-                    } else {
-                        Log.d("DeviceMonitor", "Connected to adb for device monitoring");
-                        mConnectionAttempt = 0;
-                    }
-                }
-
-                if (mMainAdbConnection != null && mMonitoring == false) {
-                    mMonitoring = sendDeviceListMonitoringRequest();
-                }
-
-                if (mMonitoring) {
-                    // read the length of the incoming message
-                    int length = readLength(mMainAdbConnection, mLengthBuffer);
-
-                    if (length >= 0) {
-                        // read the incoming message
-                        processIncomingDeviceData(length);
-
-                        // flag the fact that we have build the list at least once.
-                        mInitialDeviceListDone = true;
-                    }
-                }
-            } catch (AsynchronousCloseException ace) {
-                // this happens because of a call to Quit. We do nothing, and the loop will break.
-            } catch (IOException ioe) {
-                if (mQuit == false) {
-                    Log.e("DeviceMonitor", "Adb connection Error:" + ioe.getMessage());
-                    mMonitoring = false;
-                    if (mMainAdbConnection != null) {
-                        try {
-                            mMainAdbConnection.close();
-                        } catch (IOException ioe2) {
-                            // we can safely ignore that one.
-                        }
-                        mMainAdbConnection = null;
-                    }
-                }
-            }
-        } while (mQuit == false);
-    }
-
-    /**
-     * Sleeps for a little bit.
-     */
-    private void waitABit() {
-        try {
-            Thread.sleep(1000);
-        } catch (InterruptedException e1) {
-        }
-    }
-
-    /**
-     * Attempts to connect to the debug bridge server.
-     * @return a connect socket if success, null otherwise
-     */
-    private SocketChannel openAdbConnection() {
-        Log.d("DeviceMonitor", "Connecting to adb for Device List Monitoring...");
-
-        SocketChannel adbChannel = null;
-        try {
-            adbChannel = SocketChannel.open(AndroidDebugBridge.sSocketAddr);
-            adbChannel.socket().setTcpNoDelay(true);
-        } catch (IOException e) {
-        }
-
-        return adbChannel;
-    }
-
-    /**
-     *
-     * @return
-     * @throws IOException
-     */
-    private boolean sendDeviceListMonitoringRequest() throws IOException {
-        byte[] request = AdbHelper.formAdbRequest("host:track-devices"); //$NON-NLS-1$
-
-        if (AdbHelper.write(mMainAdbConnection, request) == false) {
-            Log.e("DeviceMonitor", "Sending Tracking request failed!");
-            mMainAdbConnection.close();
-            throw new IOException("Sending Tracking request failed!");
-        }
-
-        AdbResponse resp = AdbHelper.readAdbResponse(mMainAdbConnection,
-                false /* readDiagString */);
-
-        if (resp.ioSuccess == false) {
-            Log.e("DeviceMonitor", "Failed to read the adb response!");
-            mMainAdbConnection.close();
-            throw new IOException("Failed to read the adb response!");
-        }
-
-        if (resp.okay == false) {
-            // request was refused by adb!
-            Log.e("DeviceMonitor", "adb refused request: " + resp.message);
-        }
-
-        return resp.okay;
-    }
-
-    /**
-     * Processes an incoming device message from the socket
-     * @param socket
-     * @param length
-     * @throws IOException
-     */
-    private void processIncomingDeviceData(int length) throws IOException {
-        ArrayList<Device> list = new ArrayList<Device>();
-
-        if (length > 0) {
-            byte[] buffer = new byte[length];
-            String result = read(mMainAdbConnection, buffer);
-
-            String[] devices = result.split("\n"); // $NON-NLS-1$
-
-            for (String d : devices) {
-                String[] param = d.split("\t"); // $NON-NLS-1$
-                if (param.length == 2) {
-                    // new adb uses only serial numbers to identify devices
-                    Device device = new Device(this, param[0] /*serialnumber*/,
-                            DeviceState.getState(param[1]));
-
-                    //add the device to the list
-                    list.add(device);
-                }
-            }
-        }
-
-        // now merge the new devices with the old ones.
-        updateDevices(list);
-    }
-
-    /**
-     *  Updates the device list with the new items received from the monitoring service.
-     */
-    private void updateDevices(ArrayList<Device> newList) {
-        // because we are going to call mServer.deviceDisconnected which will acquire this lock
-        // we lock it first, so that the AndroidDebugBridge lock is always locked first.
-        synchronized (AndroidDebugBridge.getLock()) {
-            synchronized (mDevices) {
-                // For each device in the current list, we look for a matching the new list.
-                // * if we find it, we update the current object with whatever new information
-                //   there is
-                //   (mostly state change, if the device becomes ready, we query for build info).
-                //   We also remove the device from the new list to mark it as "processed"
-                // * if we do not find it, we remove it from the current list.
-                // Once this is done, the new list contains device we aren't monitoring yet, so we
-                // add them to the list, and start monitoring them.
-
-                for (int d = 0 ; d < mDevices.size() ;) {
-                    Device device = mDevices.get(d);
-
-                    // look for a similar device in the new list.
-                    int count = newList.size();
-                    boolean foundMatch = false;
-                    for (int dd = 0 ; dd < count ; dd++) {
-                        Device newDevice = newList.get(dd);
-                        // see if it matches in id and serial number.
-                        if (newDevice.getSerialNumber().equals(device.getSerialNumber())) {
-                            foundMatch = true;
-
-                            // update the state if needed.
-                            if (device.getState() != newDevice.getState()) {
-                                device.setState(newDevice.getState());
-                                device.update(Device.CHANGE_STATE);
-
-                                // if the device just got ready/online, we need to start
-                                // monitoring it.
-                                if (device.isOnline()) {
-                                    if (AndroidDebugBridge.getClientSupport() == true) {
-                                        if (startMonitoringDevice(device) == false) {
-                                            Log.e("DeviceMonitor",
-                                                    "Failed to start monitoring "
-                                                    + device.getSerialNumber());
-                                        }
-                                    }
-
-                                    if (device.getPropertyCount() == 0) {
-                                        queryNewDeviceForInfo(device);
-                                    }
-                                }
-                            }
-
-                            // remove the new device from the list since it's been used
-                            newList.remove(dd);
-                            break;
-                        }
-                    }
-
-                    if (foundMatch == false) {
-                        // the device is gone, we need to remove it, and keep current index
-                        // to process the next one.
-                        removeDevice(device);
-                        mServer.deviceDisconnected(device);
-                    } else {
-                        // process the next one
-                        d++;
-                    }
-                }
-
-                // at this point we should still have some new devices in newList, so we
-                // process them.
-                for (Device newDevice : newList) {
-                    // add them to the list
-                    mDevices.add(newDevice);
-                    mServer.deviceConnected(newDevice);
-
-                    // start monitoring them.
-                    if (AndroidDebugBridge.getClientSupport() == true) {
-                        if (newDevice.isOnline()) {
-                            startMonitoringDevice(newDevice);
-                        }
-                    }
-
-                    // look for their build info.
-                    if (newDevice.isOnline()) {
-                        queryNewDeviceForInfo(newDevice);
-                    }
-                }
-            }
-        }
-        newList.clear();
-    }
-
-    private void removeDevice(Device device) {
-        device.clearClientList();
-        mDevices.remove(device);
-
-        SocketChannel channel = device.getClientMonitoringSocket();
-        if (channel != null) {
-            try {
-                channel.close();
-            } catch (IOException e) {
-                // doesn't really matter if the close fails.
-            }
-        }
-    }
-
-    /**
-     * Queries a device for its build info.
-     * @param device the device to query.
-     */
-    private void queryNewDeviceForInfo(Device device) {
-        // TODO: do this in a separate thread.
-        try {
-            // first get the list of properties.
-            device.executeShellCommand(GetPropReceiver.GETPROP_COMMAND,
-                    new GetPropReceiver(device));
-
-            // now get the emulator Virtual Device name (if applicable).
-            if (device.isEmulator()) {
-                EmulatorConsole console = EmulatorConsole.getConsole(device);
-                if (console != null) {
-                    device.setAvdName(console.getAvdName());
-                }
-            }
-        } catch (IOException e) {
-            // if we can't get the build info, it doesn't matter too much
-        }
-    }
-
-    /**
-     * Starts a monitoring service for a device.
-     * @param device the device to monitor.
-     * @return true if success.
-     */
-    private boolean startMonitoringDevice(Device device) {
-        SocketChannel socketChannel = openAdbConnection();
-
-        if (socketChannel != null) {
-            try {
-                boolean result = sendDeviceMonitoringRequest(socketChannel, device);
-                if (result) {
-
-                    if (mSelector == null) {
-                        startDeviceMonitorThread();
-                    }
-
-                    device.setClientMonitoringSocket(socketChannel);
-
-                    synchronized (mDevices) {
-                        // always wakeup before doing the register. The synchronized block
-                        // ensure that the selector won't select() before the end of this block.
-                        // @see deviceClientMonitorLoop
-                        mSelector.wakeup();
-
-                        socketChannel.configureBlocking(false);
-                        socketChannel.register(mSelector, SelectionKey.OP_READ, device);
-                    }
-
-                    return true;
-                }
-            } catch (IOException e) {
-                try {
-                    // attempt to close the socket if needed.
-                    socketChannel.close();
-                } catch (IOException e1) {
-                    // we can ignore that one. It may already have been closed.
-                }
-                Log.d("DeviceMonitor",
-                        "Connection Failure when starting to monitor device '"
-                        + device + "' : " + e.getMessage());
-            }
-        }
-
-        return false;
-    }
-
-    private void startDeviceMonitorThread() throws IOException {
-        mSelector = Selector.open();
-        new Thread("Device Client Monitor") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                deviceClientMonitorLoop();
-            }
-        }.start();
-    }
-
-    private void deviceClientMonitorLoop() {
-        do {
-            try {
-                // This synchronized block stops us from doing the select() if a new
-                // Device is being added.
-                // @see startMonitoringDevice()
-                synchronized (mDevices) {
-                }
-
-                int count = mSelector.select();
-
-                if (mQuit) {
-                    return;
-                }
-
-                synchronized (mClientsToReopen) {
-                    if (mClientsToReopen.size() > 0) {
-                        Set<Client> clients = mClientsToReopen.keySet();
-                        MonitorThread monitorThread = MonitorThread.getInstance();
-
-                        for (Client client : clients) {
-                            Device device = client.getDeviceImpl();
-                            int pid = client.getClientData().getPid();
-
-                            monitorThread.dropClient(client, false /* notify */);
-
-                            // This is kinda bad, but if we don't wait a bit, the client
-                            // will never answer the second handshake!
-                            waitABit();
-
-                            int port = mClientsToReopen.get(client);
-
-                            if (port == IDebugPortProvider.NO_STATIC_PORT) {
-                                port = getNextDebuggerPort();
-                            }
-                            Log.d("DeviceMonitor", "Reopening " + client);
-                            openClient(device, pid, port, monitorThread);
-                            device.update(Device.CHANGE_CLIENT_LIST);
-                        }
-
-                        mClientsToReopen.clear();
-                    }
-                }
-
-                if (count == 0) {
-                    continue;
-                }
-
-                Set<SelectionKey> keys = mSelector.selectedKeys();
-                Iterator<SelectionKey> iter = keys.iterator();
-
-                while (iter.hasNext()) {
-                    SelectionKey key = iter.next();
-                    iter.remove();
-
-                    if (key.isValid() && key.isReadable()) {
-                        Object attachment = key.attachment();
-
-                        if (attachment instanceof Device) {
-                            Device device = (Device)attachment;
-
-                            SocketChannel socket = device.getClientMonitoringSocket();
-
-                            if (socket != null) {
-                                try {
-                                    int length = readLength(socket, mLengthBuffer2);
-
-                                    processIncomingJdwpData(device, socket, length);
-                                } catch (IOException ioe) {
-                                    Log.d("DeviceMonitor",
-                                            "Error reading jdwp list: " + ioe.getMessage());
-                                    socket.close();
-
-                                    // restart the monitoring of that device
-                                    synchronized (mDevices) {
-                                        if (mDevices.contains(device)) {
-                                            Log.d("DeviceMonitor",
-                                                    "Restarting monitoring service for " + device);
-                                            startMonitoringDevice(device);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            } catch (IOException e) {
-                if (mQuit == false) {
-
-                }
-            }
-
-        } while (mQuit == false);
-    }
-
-    private boolean sendDeviceMonitoringRequest(SocketChannel socket, Device device)
-            throws IOException {
-
-        AdbHelper.setDevice(socket, device);
-
-        byte[] request = AdbHelper.formAdbRequest("track-jdwp"); //$NON-NLS-1$
-
-        if (AdbHelper.write(socket, request) == false) {
-            Log.e("DeviceMonitor", "Sending jdwp tracking request failed!");
-            socket.close();
-            throw new IOException();
-        }
-
-        AdbResponse resp = AdbHelper.readAdbResponse(socket, false /* readDiagString */);
-
-        if (resp.ioSuccess == false) {
-            Log.e("DeviceMonitor", "Failed to read the adb response!");
-            socket.close();
-            throw new IOException();
-        }
-
-        if (resp.okay == false) {
-            // request was refused by adb!
-            Log.e("DeviceMonitor", "adb refused request: " + resp.message);
-        }
-
-        return resp.okay;
-    }
-
-    private void processIncomingJdwpData(Device device, SocketChannel monitorSocket, int length)
-            throws IOException {
-        if (length >= 0) {
-            // array for the current pids.
-            ArrayList<Integer> pidList = new ArrayList<Integer>();
-
-            // get the string data if there are any
-            if (length > 0) {
-                byte[] buffer = new byte[length];
-                String result = read(monitorSocket, buffer);
-
-                // split each line in its own list and create an array of integer pid
-                String[] pids = result.split("\n"); //$NON-NLS-1$
-
-                for (String pid : pids) {
-                    try {
-                        pidList.add(Integer.valueOf(pid));
-                    } catch (NumberFormatException nfe) {
-                        // looks like this pid is not really a number. Lets ignore it.
-                        continue;
-                    }
-                }
-            }
-
-            MonitorThread monitorThread = MonitorThread.getInstance();
-
-            // Now we merge the current list with the old one.
-            // this is the same mechanism as the merging of the device list.
-
-            // For each client in the current list, we look for a matching the pid in the new list.
-            // * if we find it, we do nothing, except removing the pid from its list,
-            //   to mark it as "processed"
-            // * if we do not find any match, we remove the client from the current list.
-            // Once this is done, the new list contains pids for which we don't have clients yet,
-            // so we create clients for them, add them to the list, and start monitoring them.
-
-            List<Client> clients = device.getClientList();
-
-            boolean changed = false;
-
-            // because MonitorThread#dropClient acquires first the monitorThread lock and then the
-            // Device client list lock (when removing the Client from the list), we have to make
-            // sure we acquire the locks in the same order, since another thread (MonitorThread),
-            // could call dropClient itself.
-            synchronized (monitorThread) {
-                synchronized (clients) {
-                    for (int c = 0 ; c < clients.size() ;) {
-                        Client client = clients.get(c);
-                        int pid = client.getClientData().getPid();
-
-                        // look for a matching pid
-                        Integer match = null;
-                        for (Integer matchingPid : pidList) {
-                            if (pid == matchingPid.intValue()) {
-                                match = matchingPid;
-                                break;
-                            }
-                        }
-
-                        if (match != null) {
-                            pidList.remove(match);
-                            c++; // move on to the next client.
-                        } else {
-                            // we need to drop the client. the client will remove itself from the
-                            // list of its device which is 'clients', so there's no need to
-                            // increment c.
-                            // We ask the monitor thread to not send notification, as we'll do
-                            // it once at the end.
-                            monitorThread.dropClient(client, false /* notify */);
-                            changed = true;
-                        }
-                    }
-                }
-            }
-
-            // at this point whatever pid is left in the list needs to be converted into Clients.
-            for (int newPid : pidList) {
-                openClient(device, newPid, getNextDebuggerPort(), monitorThread);
-                changed = true;
-            }
-
-            if (changed) {
-                mServer.deviceChanged(device, Device.CHANGE_CLIENT_LIST);
-            }
-        }
-    }
-
-    /**
-     * Opens and creates a new client.
-     * @return
-     */
-    private void openClient(Device device, int pid, int port, MonitorThread monitorThread) {
-
-        SocketChannel clientSocket;
-        try {
-            clientSocket = AdbHelper.createPassThroughConnection(
-                    AndroidDebugBridge.sSocketAddr, device, pid);
-
-            // required for Selector
-            clientSocket.configureBlocking(false);
-        } catch (UnknownHostException uhe) {
-            Log.d("DeviceMonitor", "Unknown Jdwp pid: " + pid);
-            return;
-        } catch (IOException ioe) {
-            Log.w("DeviceMonitor",
-                    "Failed to connect to client '" + pid + "': " + ioe.getMessage());
-            return ;
-        }
-
-        createClient(device, pid, clientSocket, port, monitorThread);
-    }
-
-    /**
-     * Creates a client and register it to the monitor thread
-     * @param device
-     * @param pid
-     * @param socket
-     * @param debuggerPort the debugger port.
-     * @param monitorThread the {@link MonitorThread} object.
-     */
-    private void createClient(Device device, int pid, SocketChannel socket, int debuggerPort,
-            MonitorThread monitorThread) {
-
-        /*
-         * Successfully connected to something. Create a Client object, add
-         * it to the list, and initiate the JDWP handshake.
-         */
-
-        Client client = new Client(device, socket, pid);
-
-        if (client.sendHandshake()) {
-            try {
-                if (AndroidDebugBridge.getClientSupport()) {
-                    client.listenForDebugger(debuggerPort);
-                }
-            } catch (IOException ioe) {
-                client.getClientData().setDebuggerConnectionStatus(DebuggerStatus.ERROR);
-                Log.e("ddms", "Can't bind to local " + debuggerPort + " for debugger");
-                // oh well
-            }
-
-            client.requestAllocationStatus();
-        } else {
-            Log.e("ddms", "Handshake with " + client + " failed!");
-            /*
-             * The handshake send failed. We could remove it now, but if the
-             * failure is "permanent" we'll just keep banging on it and
-             * getting the same result. Keep it in the list with its "error"
-             * state so we don't try to reopen it.
-             */
-        }
-
-        if (client.isValid()) {
-            device.addClient(client);
-            monitorThread.addClient(client);
-        } else {
-            client = null;
-        }
-    }
-
-    private int getNextDebuggerPort() {
-        // get the first port and remove it
-        synchronized (mDebuggerPorts) {
-            if (mDebuggerPorts.size() > 0) {
-                int port = mDebuggerPorts.get(0);
-
-                // remove it.
-                mDebuggerPorts.remove(0);
-
-                // if there's nothing left, add the next port to the list
-                if (mDebuggerPorts.size() == 0) {
-                    mDebuggerPorts.add(port+1);
-                }
-
-                return port;
-            }
-        }
-
-        return -1;
-    }
-
-    void addPortToAvailableList(int port) {
-        if (port > 0) {
-            synchronized (mDebuggerPorts) {
-                // because there could be case where clients are closed twice, we have to make
-                // sure the port number is not already in the list.
-                if (mDebuggerPorts.indexOf(port) == -1) {
-                    // add the port to the list while keeping it sorted. It's not like there's
-                    // going to be tons of objects so we do it linearly.
-                    int count = mDebuggerPorts.size();
-                    for (int i = 0 ; i < count ; i++) {
-                        if (port < mDebuggerPorts.get(i)) {
-                            mDebuggerPorts.add(i, port);
-                            break;
-                        }
-                    }
-                    // TODO: check if we can compact the end of the list.
-                }
-            }
-        }
-    }
-
-    /**
-     * Reads the length of the next message from a socket.
-     * @param socket The {@link SocketChannel} to read from.
-     * @return the length, or 0 (zero) if no data is available from the socket.
-     * @throws IOException if the connection failed.
-     */
-    private int readLength(SocketChannel socket, byte[] buffer) throws IOException {
-        String msg = read(socket, buffer);
-
-        if (msg != null) {
-            try {
-                return Integer.parseInt(msg, 16);
-            } catch (NumberFormatException nfe) {
-                // we'll throw an exception below.
-            }
-       }
-
-        // we receive something we can't read. It's better to reset the connection at this point.
-        throw new IOException("Unable to read length");
-    }
-
-    /**
-     * Fills a buffer from a socket.
-     * @param socket
-     * @param buffer
-     * @return the content of the buffer as a string, or null if it failed to convert the buffer.
-     * @throws IOException
-     */
-    private String read(SocketChannel socket, byte[] buffer) throws IOException {
-        ByteBuffer buf = ByteBuffer.wrap(buffer, 0, buffer.length);
-
-        while (buf.position() != buf.limit()) {
-            int count;
-
-            count = socket.read(buf);
-            if (count < 0) {
-                throw new IOException("EOF");
-            }
-        }
-
-        try {
-            return new String(buffer, 0, buf.position(), AdbHelper.DEFAULT_ENCODING);
-        } catch (UnsupportedEncodingException e) {
-            // we'll return null below.
-        }
-
-        return null;
-    }
-
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java
deleted file mode 100644
index 6ac019d..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.security.InvalidParameterException;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Provides control over emulated hardware of the Android emulator.
- * <p/>This is basically a wrapper around the command line console normally used with telnet.
- *<p/>
- * Regarding line termination handling:<br>
- * One of the issues is that the telnet protocol <b>requires</b> usage of <code>\r\n</code>. Most
- * implementations don't enforce it (the dos one does). In this particular case, this is mostly
- * irrelevant since we don't use telnet in Java, but that means we want to make
- * sure we use the same line termination than what the console expects. The console
- * code removes <code>\r</code> and waits for <code>\n</code>.
- * <p/>However this means you <i>may</i> receive <code>\r\n</code> when reading from the console.
- * <p/>
- * <b>This API will change in the near future.</b>
- */
-public final class EmulatorConsole {
-
-    private final static String DEFAULT_ENCODING = "ISO-8859-1"; //$NON-NLS-1$
-
-    private final static int WAIT_TIME = 5; // spin-wait sleep, in ms
-
-    private final static int STD_TIMEOUT = 5000; // standard delay, in ms
-
-    private final static String HOST = "127.0.0.1";  //$NON-NLS-1$
-
-    private final static String COMMAND_PING = "help\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_AVD_NAME = "avd name\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_KILL = "kill\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_GSM_STATUS = "gsm status\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_GSM_CALL = "gsm call %1$s\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_GSM_CANCEL_CALL = "gsm cancel %1$s\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_GSM_DATA = "gsm data %1$s\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_GSM_VOICE = "gsm voice %1$s\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_SMS_SEND = "sms send %1$s %2$s\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_NETWORK_STATUS = "network status\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_NETWORK_SPEED = "network speed %1$s\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_NETWORK_LATENCY = "network delay %1$s\r\n"; //$NON-NLS-1$
-    private final static String COMMAND_GPS =
-        "geo nmea $GPGGA,%1$02d%2$02d%3$02d.%4$03d," + //$NON-NLS-1$
-        "%5$03d%6$09.6f,%7$c,%8$03d%9$09.6f,%10$c," + //$NON-NLS-1$
-        "1,10,0.0,0.0,0,0.0,0,0.0,0000\r\n"; //$NON-NLS-1$
-
-    private final static Pattern RE_KO = Pattern.compile("KO:\\s+(.*)"); //$NON-NLS-1$
-
-    /**
-     * Array of delay values: no delay, gprs, edge/egprs, umts/3d
-     */
-    public final static int[] MIN_LATENCIES = new int[] {
-        0,      // No delay
-        150,    // gprs
-        80,     // edge/egprs
-        35      // umts/3g
-    };
-
-    /**
-     * Array of download speeds: full speed, gsm, hscsd, gprs, edge/egprs, umts/3g, hsdpa.
-     */
-    public final int[] DOWNLOAD_SPEEDS = new int[] {
-        0,          // full speed
-        14400,      // gsm
-        43200,      // hscsd
-        80000,      // gprs
-        236800,     // edge/egprs
-        1920000,    // umts/3g
-        14400000    // hsdpa
-    };
-
-    /** Arrays of valid network speeds */
-    public final static String[] NETWORK_SPEEDS = new String[] {
-        "full", //$NON-NLS-1$
-        "gsm", //$NON-NLS-1$
-        "hscsd", //$NON-NLS-1$
-        "gprs", //$NON-NLS-1$
-        "edge", //$NON-NLS-1$
-        "umts", //$NON-NLS-1$
-        "hsdpa", //$NON-NLS-1$
-    };
-
-    /** Arrays of valid network latencies */
-    public final static String[] NETWORK_LATENCIES = new String[] {
-        "none", //$NON-NLS-1$
-        "gprs", //$NON-NLS-1$
-        "edge", //$NON-NLS-1$
-        "umts", //$NON-NLS-1$
-    };
-
-    /** Gsm Mode enum. */
-    public static enum GsmMode {
-        UNKNOWN((String)null),
-        UNREGISTERED(new String[] { "unregistered", "off" }),
-        HOME(new String[] { "home", "on" }),
-        ROAMING("roaming"),
-        SEARCHING("searching"),
-        DENIED("denied");
-
-        private final String[] tags;
-
-        GsmMode(String tag) {
-            if (tag != null) {
-                this.tags = new String[] { tag };
-            } else {
-                this.tags = new String[0];
-            }
-        }
-
-        GsmMode(String[] tags) {
-            this.tags = tags;
-        }
-
-        public static GsmMode getEnum(String tag) {
-            for (GsmMode mode : values()) {
-                for (String t : mode.tags) {
-                    if (t.equals(tag)) {
-                        return mode;
-                    }
-                }
-            }
-            return UNKNOWN;
-        }
-
-        /**
-         * Returns the first tag of the enum.
-         */
-        public String getTag() {
-            if (tags.length > 0) {
-                return tags[0];
-            }
-            return null;
-        }
-    }
-
-    public final static String RESULT_OK = null;
-
-    private final static Pattern sEmulatorRegexp = Pattern.compile(Device.RE_EMULATOR_SN);
-    private final static Pattern sVoiceStatusRegexp = Pattern.compile(
-            "gsm\\s+voice\\s+state:\\s*([a-z]+)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-    private final static Pattern sDataStatusRegexp = Pattern.compile(
-            "gsm\\s+data\\s+state:\\s*([a-z]+)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-    private final static Pattern sDownloadSpeedRegexp = Pattern.compile(
-            "\\s+download\\s+speed:\\s+(\\d+)\\s+bits.*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-    private final static Pattern sMinLatencyRegexp = Pattern.compile(
-            "\\s+minimum\\s+latency:\\s+(\\d+)\\s+ms", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-
-    private final static HashMap<Integer, EmulatorConsole> sEmulators =
-        new HashMap<Integer, EmulatorConsole>();
-
-    /** Gsm Status class */
-    public static class GsmStatus {
-        /** Voice status. */
-        public GsmMode voice = GsmMode.UNKNOWN;
-        /** Data status. */
-        public GsmMode data = GsmMode.UNKNOWN;
-    }
-
-    /** Network Status class */
-    public static class NetworkStatus {
-        /** network speed status. This is an index in the {@link #DOWNLOAD_SPEEDS} array. */
-        public int speed = -1;
-        /** network latency status.  This is an index in the {@link #MIN_LATENCIES} array. */
-        public int latency = -1;
-    }
-
-    private int mPort;
-
-    private SocketChannel mSocketChannel;
-
-    private byte[] mBuffer = new byte[1024];
-
-    /**
-     * Returns an {@link EmulatorConsole} object for the given {@link Device}. This can
-     * be an already existing console, or a new one if it hadn't been created yet.
-     * @param d The device that the console links to.
-     * @return an <code>EmulatorConsole</code> object or <code>null</code> if the connection failed.
-     */
-    public static synchronized EmulatorConsole getConsole(IDevice d) {
-        // we need to make sure that the device is an emulator
-        Matcher m = sEmulatorRegexp.matcher(d.getSerialNumber());
-        if (m.matches()) {
-            // get the port number. This is the console port.
-            int port;
-            try {
-                port = Integer.parseInt(m.group(1));
-                if (port <= 0) {
-                    return null;
-                }
-            } catch (NumberFormatException e) {
-                // looks like we failed to get the port number. This is a bit strange since
-                // it's coming from a regexp that only accept digit, but we handle the case
-                // and return null.
-                return null;
-            }
-
-            EmulatorConsole console = sEmulators.get(port);
-
-            if (console != null) {
-                // if the console exist, we ping the emulator to check the connection.
-                if (console.ping() == false) {
-                    RemoveConsole(console.mPort);
-                    console = null;
-                }
-            }
-
-            if (console == null) {
-                // no console object exists for this port so we create one, and start
-                // the connection.
-                console = new EmulatorConsole(port);
-                if (console.start()) {
-                    sEmulators.put(port, console);
-                } else {
-                    console = null;
-                }
-            }
-
-            return console;
-        }
-
-        return null;
-    }
-
-    /**
-     * Removes the console object associated with a port from the map.
-     * @param port The port of the console to remove.
-     */
-    private static synchronized void RemoveConsole(int port) {
-        sEmulators.remove(port);
-    }
-
-    private EmulatorConsole(int port) {
-        super();
-        mPort = port;
-    }
-
-    /**
-     * Starts the connection of the console.
-     * @return true if success.
-     */
-    private boolean start() {
-
-        InetSocketAddress socketAddr;
-        try {
-            InetAddress hostAddr = InetAddress.getByName(HOST);
-            socketAddr = new InetSocketAddress(hostAddr, mPort);
-        } catch (UnknownHostException e) {
-            return false;
-        }
-
-        try {
-            mSocketChannel = SocketChannel.open(socketAddr);
-        } catch (IOException e1) {
-            return false;
-        }
-
-        // read some stuff from it
-        readLines();
-
-        return true;
-    }
-
-    /**
-     * Ping the emulator to check if the connection is still alive.
-     * @return true if the connection is alive.
-     */
-    private synchronized boolean ping() {
-        // it looks like we can send stuff, even when the emulator quit, but we can't read
-        // from the socket. So we check the return of readLines()
-        if (sendCommand(COMMAND_PING)) {
-            return readLines() != null;
-        }
-
-        return false;
-    }
-
-    /**
-     * Sends a KILL command to the emulator.
-     */
-    public synchronized void kill() {
-        if (sendCommand(COMMAND_KILL)) {
-            RemoveConsole(mPort);
-        }
-    }
-
-    public synchronized String getAvdName() {
-        if (sendCommand(COMMAND_AVD_NAME)) {
-            String[] result = readLines();
-            if (result != null && result.length == 2) { // this should be the name on first line,
-                                                        // and ok on 2nd line
-                return result[0];
-            } else {
-                // try to see if there's a message after KO
-                Matcher m = RE_KO.matcher(result[result.length-1]);
-                if (m.matches()) {
-                    return m.group(1);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the network status of the emulator.
-     * @return a {@link NetworkStatus} object containing the {@link GsmStatus}, or
-     * <code>null</code> if the query failed.
-     */
-    public synchronized NetworkStatus getNetworkStatus() {
-        if (sendCommand(COMMAND_NETWORK_STATUS)) {
-            /* Result is in the format
-                Current network status:
-                download speed:      14400 bits/s (1.8 KB/s)
-                upload speed:        14400 bits/s (1.8 KB/s)
-                minimum latency:  0 ms
-                maximum latency:  0 ms
-             */
-            String[] result = readLines();
-
-            if (isValid(result)) {
-                // we only compare agains the min latency and the download speed
-                // let's not rely on the order of the output, and simply loop through
-                // the line testing the regexp.
-                NetworkStatus status = new NetworkStatus();
-                for (String line : result) {
-                    Matcher m = sDownloadSpeedRegexp.matcher(line);
-                    if (m.matches()) {
-                        // get the string value
-                        String value = m.group(1);
-
-                        // get the index from the list
-                        status.speed = getSpeedIndex(value);
-
-                        // move on to next line.
-                        continue;
-                    }
-
-                    m = sMinLatencyRegexp.matcher(line);
-                    if (m.matches()) {
-                        // get the string value
-                        String value = m.group(1);
-
-                        // get the index from the list
-                        status.latency = getLatencyIndex(value);
-
-                        // move on to next line.
-                        continue;
-                    }
-                }
-
-                return status;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the current gsm status of the emulator
-     * @return a {@link GsmStatus} object containing the gms status, or <code>null</code>
-     * if the query failed.
-     */
-    public synchronized GsmStatus getGsmStatus() {
-        if (sendCommand(COMMAND_GSM_STATUS)) {
-            /*
-             * result is in the format:
-             * gsm status
-             * gsm voice state: home
-             * gsm data state:  home
-             */
-
-            String[] result = readLines();
-            if (isValid(result)) {
-
-                GsmStatus status = new GsmStatus();
-
-                // let's not rely on the order of the output, and simply loop through
-                // the line testing the regexp.
-                for (String line : result) {
-                    Matcher m = sVoiceStatusRegexp.matcher(line);
-                    if (m.matches()) {
-                        // get the string value
-                        String value = m.group(1);
-
-                        // get the index from the list
-                        status.voice = GsmMode.getEnum(value.toLowerCase());
-
-                        // move on to next line.
-                        continue;
-                    }
-
-                    m = sDataStatusRegexp.matcher(line);
-                    if (m.matches()) {
-                        // get the string value
-                        String value = m.group(1);
-
-                        // get the index from the list
-                        status.data = GsmMode.getEnum(value.toLowerCase());
-
-                        // move on to next line.
-                        continue;
-                    }
-                }
-
-                return status;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets the GSM voice mode.
-     * @param mode the {@link GsmMode} value.
-     * @return RESULT_OK if success, an error String otherwise.
-     * @throws InvalidParameterException if mode is an invalid value.
-     */
-    public synchronized String setGsmVoiceMode(GsmMode mode) throws InvalidParameterException {
-        if (mode == GsmMode.UNKNOWN) {
-            throw new InvalidParameterException();
-        }
-
-        String command = String.format(COMMAND_GSM_VOICE, mode.getTag());
-        return processCommand(command);
-    }
-
-    /**
-     * Sets the GSM data mode.
-     * @param mode the {@link GsmMode} value
-     * @return {@link #RESULT_OK} if success, an error String otherwise.
-     * @throws InvalidParameterException if mode is an invalid value.
-     */
-    public synchronized String setGsmDataMode(GsmMode mode) throws InvalidParameterException {
-        if (mode == GsmMode.UNKNOWN) {
-            throw new InvalidParameterException();
-        }
-
-        String command = String.format(COMMAND_GSM_DATA, mode.getTag());
-        return processCommand(command);
-    }
-
-    /**
-     * Initiate an incoming call on the emulator.
-     * @param number a string representing the calling number.
-     * @return {@link #RESULT_OK} if success, an error String otherwise.
-     */
-    public synchronized String call(String number) {
-        String command = String.format(COMMAND_GSM_CALL, number);
-        return processCommand(command);
-    }
-
-    /**
-     * Cancels a current call.
-     * @param number the number of the call to cancel
-     * @return {@link #RESULT_OK} if success, an error String otherwise.
-     */
-    public synchronized String cancelCall(String number) {
-        String command = String.format(COMMAND_GSM_CANCEL_CALL, number);
-        return processCommand(command);
-    }
-
-    /**
-     * Sends an SMS to the emulator
-     * @param number The sender phone number
-     * @param message The SMS message. \ characters must be escaped. The carriage return is
-     * the 2 character sequence  {'\', 'n' }
-     *
-     * @return {@link #RESULT_OK} if success, an error String otherwise.
-     */
-    public synchronized String sendSms(String number, String message) {
-        String command = String.format(COMMAND_SMS_SEND, number, message);
-        return processCommand(command);
-    }
-
-    /**
-     * Sets the network speed.
-     * @param selectionIndex The index in the {@link #NETWORK_SPEEDS} table.
-     * @return {@link #RESULT_OK} if success, an error String otherwise.
-     */
-    public synchronized String setNetworkSpeed(int selectionIndex) {
-        String command = String.format(COMMAND_NETWORK_SPEED, NETWORK_SPEEDS[selectionIndex]);
-        return processCommand(command);
-    }
-
-    /**
-     * Sets the network latency.
-     * @param selectionIndex The index in the {@link #NETWORK_LATENCIES} table.
-     * @return {@link #RESULT_OK} if success, an error String otherwise.
-     */
-    public synchronized String setNetworkLatency(int selectionIndex) {
-        String command = String.format(COMMAND_NETWORK_LATENCY, NETWORK_LATENCIES[selectionIndex]);
-        return processCommand(command);
-    }
-
-    public synchronized String sendLocation(double longitude, double latitude, double elevation) {
-
-        Calendar c = Calendar.getInstance();
-
-        double absLong = Math.abs(longitude);
-        int longDegree = (int)Math.floor(absLong);
-        char longDirection = 'E';
-        if (longitude < 0) {
-            longDirection = 'W';
-        }
-
-        double longMinute = (absLong - Math.floor(absLong)) * 60;
-
-        double absLat = Math.abs(latitude);
-        int latDegree = (int)Math.floor(absLat);
-        char latDirection = 'N';
-        if (latitude < 0) {
-            latDirection = 'S';
-        }
-
-        double latMinute = (absLat - Math.floor(absLat)) * 60;
-
-        String command = String.format(COMMAND_GPS,
-                c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
-                c.get(Calendar.SECOND), c.get(Calendar.MILLISECOND),
-                latDegree, latMinute, latDirection,
-                longDegree, longMinute, longDirection);
-
-        return processCommand(command);
-    }
-
-    /**
-     * Sends a command to the emulator console.
-     * @param command The command string. <b>MUST BE TERMINATED BY \n</b>.
-     * @return true if success
-     */
-    private boolean sendCommand(String command) {
-        boolean result = false;
-        try {
-            byte[] bCommand;
-            try {
-                bCommand = command.getBytes(DEFAULT_ENCODING);
-            } catch (UnsupportedEncodingException e) {
-                // wrong encoding...
-                return result;
-            }
-
-            // write the command
-            AdbHelper.write(mSocketChannel, bCommand, bCommand.length, DdmPreferences.getTimeOut());
-
-            result = true;
-        } catch (IOException e) {
-            return false;
-        } finally {
-            if (result == false) {
-                // FIXME connection failed somehow, we need to disconnect the console.
-                RemoveConsole(mPort);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Sends a command to the emulator and parses its answer.
-     * @param command the command to send.
-     * @return {@link #RESULT_OK} if success, an error message otherwise.
-     */
-    private String processCommand(String command) {
-        if (sendCommand(command)) {
-            String[] result = readLines();
-
-            if (result != null && result.length > 0) {
-                Matcher m = RE_KO.matcher(result[result.length-1]);
-                if (m.matches()) {
-                    return m.group(1);
-                }
-                return RESULT_OK;
-            }
-
-            return "Unable to communicate with the emulator";
-        }
-
-        return "Unable to send command to the emulator";
-    }
-
-    /**
-     * Reads line from the console socket. This call is blocking until we read the lines:
-     * <ul>
-     * <li>OK\r\n</li>
-     * <li>KO<msg>\r\n</li>
-     * </ul>
-     * @return the array of strings read from the emulator.
-     */
-    private String[] readLines() {
-        try {
-            ByteBuffer buf = ByteBuffer.wrap(mBuffer, 0, mBuffer.length);
-            int numWaits = 0;
-            boolean stop = false;
-
-            while (buf.position() != buf.limit() && stop == false) {
-                int count;
-
-                count = mSocketChannel.read(buf);
-                if (count < 0) {
-                    return null;
-                } else if (count == 0) {
-                    if (numWaits * WAIT_TIME > STD_TIMEOUT) {
-                        return null;
-                    }
-                    // non-blocking spin
-                    try {
-                        Thread.sleep(WAIT_TIME);
-                    } catch (InterruptedException ie) {
-                    }
-                    numWaits++;
-                } else {
-                    numWaits = 0;
-                }
-
-                // check the last few char aren't OK. For a valid message to test
-                // we need at least 4 bytes (OK/KO + \r\n)
-                if (buf.position() >= 4) {
-                    int pos = buf.position();
-                    if (endsWithOK(pos) || lastLineIsKO(pos)) {
-                        stop = true;
-                    }
-                }
-            }
-
-            String msg = new String(mBuffer, 0, buf.position(), DEFAULT_ENCODING);
-            return msg.split("\r\n"); //$NON-NLS-1$
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Returns true if the 4 characters *before* the current position are "OK\r\n"
-     * @param currentPosition The current position
-     */
-    private boolean endsWithOK(int currentPosition) {
-        if (mBuffer[currentPosition-1] == '\n' &&
-                mBuffer[currentPosition-2] == '\r' &&
-                mBuffer[currentPosition-3] == 'K' &&
-                mBuffer[currentPosition-4] == 'O') {
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns true if the last line starts with KO and is also terminated by \r\n
-     * @param currentPosition the current position
-     */
-    private boolean lastLineIsKO(int currentPosition) {
-        // first check that the last 2 characters are CRLF
-        if (mBuffer[currentPosition-1] != '\n' ||
-                mBuffer[currentPosition-2] != '\r') {
-            return false;
-        }
-
-        // now loop backward looking for the previous CRLF, or the beginning of the buffer
-        int i = 0;
-        for (i = currentPosition-3 ; i >= 0; i--) {
-            if (mBuffer[i] == '\n') {
-                // found \n!
-                if (i > 0 && mBuffer[i-1] == '\r') {
-                    // found \r!
-                    break;
-                }
-            }
-        }
-
-        // here it is either -1 if we reached the start of the buffer without finding
-        // a CRLF, or the position of \n. So in both case we look at the characters at i+1 and i+2
-        if (mBuffer[i+1] == 'K' && mBuffer[i+2] == 'O') {
-            // found error!
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns true if the last line of the result does not start with KO
-     */
-    private boolean isValid(String[] result) {
-        if (result != null && result.length > 0) {
-            return !(RE_KO.matcher(result[result.length-1]).matches());
-        }
-        return false;
-    }
-
-    private int getLatencyIndex(String value) {
-        try {
-            // get the int value
-            int latency = Integer.parseInt(value);
-
-            // check for the speed from the index
-            for (int i = 0 ; i < MIN_LATENCIES.length; i++) {
-                if (MIN_LATENCIES[i] == latency) {
-                    return i;
-                }
-            }
-        } catch (NumberFormatException e) {
-            // Do nothing, we'll just return -1.
-        }
-
-        return -1;
-    }
-
-    private int getSpeedIndex(String value) {
-        try {
-            // get the int value
-            int speed = Integer.parseInt(value);
-
-            // check for the speed from the index
-            for (int i = 0 ; i < DOWNLOAD_SPEEDS.length; i++) {
-                if (DOWNLOAD_SPEEDS[i] == speed) {
-                    return i;
-                }
-            }
-        } catch (NumberFormatException e) {
-            // Do nothing, we'll just return -1.
-        }
-
-        return -1;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/FileListingService.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/FileListingService.java
deleted file mode 100644
index b50cf79..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/FileListingService.java
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Provides {@link Device} side file listing service.
- * <p/>To get an instance for a known {@link Device}, call {@link Device#getFileListingService()}.
- */
-public final class FileListingService {
-
-    /** Pattern to find filenames that match "*.apk" */
-    private final static Pattern sApkPattern =
-        Pattern.compile(".*\\.apk", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-
-    private final static String PM_FULL_LISTING = "pm list packages -f"; //$NON-NLS-1$
-
-    /** Pattern to parse the output of the 'pm -lf' command.<br>
-     * The output format looks like:<br>
-     * /data/app/myapp.apk=com.mypackage.myapp */
-    private final static Pattern sPmPattern = Pattern.compile("^package:(.+?)=(.+)$"); //$NON-NLS-1$
-
-    /** Top level data folder. */
-    public final static String DIRECTORY_DATA = "data"; //$NON-NLS-1$
-    /** Top level sdcard folder. */
-    public final static String DIRECTORY_SDCARD = "sdcard"; //$NON-NLS-1$
-    /** Top level system folder. */
-    public final static String DIRECTORY_SYSTEM = "system"; //$NON-NLS-1$
-    /** Top level temp folder. */
-    public final static String DIRECTORY_TEMP = "tmp"; //$NON-NLS-1$
-    /** Application folder. */
-    public final static String DIRECTORY_APP = "app"; //$NON-NLS-1$
-
-    private final static String[] sRootLevelApprovedItems = {
-        DIRECTORY_DATA,
-        DIRECTORY_SDCARD,
-        DIRECTORY_SYSTEM,
-        DIRECTORY_TEMP
-    };
-
-    public static final long REFRESH_RATE = 5000L;
-    /**
-     * Refresh test has to be slightly lower for precision issue.
-     */
-    static final long REFRESH_TEST = (long)(REFRESH_RATE * .8);
-
-    /** Entry type: File */
-    public static final int TYPE_FILE = 0;
-    /** Entry type: Directory */
-    public static final int TYPE_DIRECTORY = 1;
-    /** Entry type: Directory Link */
-    public static final int TYPE_DIRECTORY_LINK = 2;
-    /** Entry type: Block */
-    public static final int TYPE_BLOCK = 3;
-    /** Entry type: Character */
-    public static final int TYPE_CHARACTER = 4;
-    /** Entry type: Link */
-    public static final int TYPE_LINK = 5;
-    /** Entry type: Socket */
-    public static final int TYPE_SOCKET = 6;
-    /** Entry type: FIFO */
-    public static final int TYPE_FIFO = 7;
-    /** Entry type: Other */
-    public static final int TYPE_OTHER = 8;
-
-    /** Device side file separator. */
-    public static final String FILE_SEPARATOR = "/"; //$NON-NLS-1$
-
-    private static final String FILE_ROOT = "/"; //$NON-NLS-1$
-
-
-    /**
-     * Regexp pattern to parse the result from ls.
-     */
-    private static Pattern sLsPattern = Pattern.compile(
-        "^([bcdlsp-][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xstST])\\s+(\\S+)\\s+(\\S+)\\s+([\\d\\s,]*)\\s+(\\d{4}-\\d\\d-\\d\\d)\\s+(\\d\\d:\\d\\d)\\s+(.*)$"); //$NON-NLS-1$
-
-    private Device mDevice;
-    private FileEntry mRoot;
-
-    private ArrayList<Thread> mThreadList = new ArrayList<Thread>();
-
-    /**
-     * Represents an entry in a directory. This can be a file or a directory.
-     */
-    public final static class FileEntry {
-        /** Pattern to escape filenames for shell command consumption. */
-        private final static Pattern sEscapePattern = Pattern.compile(
-                "([\\\\()*+?\"'#/\\s])"); //$NON-NLS-1$
-
-        /**
-         * Comparator object for FileEntry
-         */
-        private static Comparator<FileEntry> sEntryComparator = new Comparator<FileEntry>() {
-            public int compare(FileEntry o1, FileEntry o2) {
-                if (o1 instanceof FileEntry && o2 instanceof FileEntry) {
-                    FileEntry fe1 = (FileEntry)o1;
-                    FileEntry fe2 = (FileEntry)o2;
-                    return fe1.name.compareTo(fe2.name);
-                }
-                return 0;
-            }
-        };
-
-        FileEntry parent;
-        String name;
-        String info;
-        String permissions;
-        String size;
-        String date;
-        String time;
-        String owner;
-        String group;
-        int type;
-        boolean isAppPackage;
-
-        boolean isRoot;
-
-        /**
-         * Indicates whether the entry content has been fetched yet, or not.
-         */
-        long fetchTime = 0;
-
-        final ArrayList<FileEntry> mChildren = new ArrayList<FileEntry>();
-
-        /**
-         * Creates a new file entry.
-         * @param parent parent entry or null if entry is root
-         * @param name name of the entry.
-         * @param type entry type. Can be one of the following: {@link FileListingService#TYPE_FILE},
-         * {@link FileListingService#TYPE_DIRECTORY}, {@link FileListingService#TYPE_OTHER}.
-         */
-        private FileEntry(FileEntry parent, String name, int type, boolean isRoot) {
-            this.parent = parent;
-            this.name = name;
-            this.type = type;
-            this.isRoot = isRoot;
-
-            checkAppPackageStatus();
-        }
-
-        /**
-         * Returns the name of the entry
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Returns the size string of the entry, as returned by <code>ls</code>.
-         */
-        public String getSize() {
-            return size;
-        }
-
-        /**
-         * Returns the size of the entry.
-         */
-        public int getSizeValue() {
-            return Integer.parseInt(size);
-        }
-
-        /**
-         * Returns the date string of the entry, as returned by <code>ls</code>.
-         */
-        public String getDate() {
-            return date;
-        }
-
-        /**
-         * Returns the time string of the entry, as returned by <code>ls</code>.
-         */
-        public String getTime() {
-            return time;
-        }
-
-        /**
-         * Returns the permission string of the entry, as returned by <code>ls</code>.
-         */
-        public String getPermissions() {
-            return permissions;
-        }
-
-        /**
-         * Returns the extra info for the entry.
-         * <p/>For a link, it will be a description of the link.
-         * <p/>For an application apk file it will be the application package as returned
-         * by the Package Manager.  
-         */
-        public String getInfo() {
-            return info;
-        }
-
-        /**
-         * Return the full path of the entry.
-         * @return a path string using {@link FileListingService#FILE_SEPARATOR} as separator.
-         */
-        public String getFullPath() {
-            if (isRoot) {
-                return FILE_ROOT;
-            }
-            StringBuilder pathBuilder = new StringBuilder();
-            fillPathBuilder(pathBuilder, false);
-
-            return pathBuilder.toString();
-        }
-
-        /**
-         * Return the fully escaped path of the entry. This path is safe to use in a
-         * shell command line.
-         * @return a path string using {@link FileListingService#FILE_SEPARATOR} as separator
-         */
-        public String getFullEscapedPath() {
-            StringBuilder pathBuilder = new StringBuilder();
-            fillPathBuilder(pathBuilder, true);
-
-            return pathBuilder.toString();
-        }
-
-        /**
-         * Returns the path as a list of segments.
-         */
-        public String[] getPathSegments() {
-            ArrayList<String> list = new ArrayList<String>();
-            fillPathSegments(list);
-
-            return list.toArray(new String[list.size()]);
-        }
-
-        /**
-         * Returns true if the entry is a directory, false otherwise;
-         */
-        public int getType() {
-            return type;
-        }
-
-        /**
-         * Returns if the entry is a folder or a link to a folder.
-         */
-        public boolean isDirectory() {
-            return type == TYPE_DIRECTORY || type == TYPE_DIRECTORY_LINK;
-        }
-
-        /**
-         * Returns the parent entry.
-         */
-        public FileEntry getParent() {
-            return parent;
-        }
-
-        /**
-         * Returns the cached children of the entry. This returns the cache created from calling
-         * <code>FileListingService.getChildren()</code>.
-         */
-        public FileEntry[] getCachedChildren() {
-            return mChildren.toArray(new FileEntry[mChildren.size()]);
-        }
-
-        /**
-         * Returns the child {@link FileEntry} matching the name.
-         * This uses the cached children list.
-         * @param name the name of the child to return.
-         * @return the FileEntry matching the name or null.
-         */
-        public FileEntry findChild(String name) {
-            for (FileEntry entry : mChildren) {
-                if (entry.name.equals(name)) {
-                    return entry;
-                }
-            }
-            return null;
-        }
-
-        /**
-         * Returns whether the entry is the root.
-         */
-        public boolean isRoot() {
-            return isRoot;
-        }
-
-        void addChild(FileEntry child) {
-            mChildren.add(child);
-        }
-
-        void setChildren(ArrayList<FileEntry> newChildren) {
-            mChildren.clear();
-            mChildren.addAll(newChildren);
-        }
-
-        boolean needFetch() {
-            if (fetchTime == 0) {
-                return true;
-            }
-            long current = System.currentTimeMillis();
-            if (current-fetchTime > REFRESH_TEST) {
-                return true;
-            }
-
-            return false;
-        }
-
-        /**
-         * Returns if the entry is a valid application package.
-         */
-        public boolean isApplicationPackage() {
-            return isAppPackage;
-        }
-
-        /**
-         * Returns if the file name is an application package name.
-         */
-        public boolean isAppFileName() {
-            Matcher m = sApkPattern.matcher(name);
-            return m.matches();
-        }
-
-        /**
-         * Recursively fills the pathBuilder with the full path
-         * @param pathBuilder a StringBuilder used to create the path.
-         * @param escapePath Whether the path need to be escaped for consumption by
-         * a shell command line.
-         */
-        protected void fillPathBuilder(StringBuilder pathBuilder, boolean escapePath) {
-            if (isRoot) {
-                return;
-            }
-
-            if (parent != null) {
-                parent.fillPathBuilder(pathBuilder, escapePath);
-            }
-            pathBuilder.append(FILE_SEPARATOR);
-            pathBuilder.append(escapePath ? escape(name) : name);
-        }
-
-        /**
-         * Recursively fills the segment list with the full path.
-         * @param list The list of segments to fill.
-         */
-        protected void fillPathSegments(ArrayList<String> list) {
-            if (isRoot) {
-                return;
-            }
-
-            if (parent != null) {
-                parent.fillPathSegments(list);
-            }
-
-            list.add(name);
-        }
-
-        /**
-         * Sets the internal app package status flag. This checks whether the entry is in an app
-         * directory like /data/app or /system/app
-         */
-        private void checkAppPackageStatus() {
-            isAppPackage = false;
-
-            String[] segments = getPathSegments();
-            if (type == TYPE_FILE && segments.length == 3 && isAppFileName()) {
-                isAppPackage = DIRECTORY_APP.equals(segments[1]) &&
-                    (DIRECTORY_SYSTEM.equals(segments[0]) || DIRECTORY_DATA.equals(segments[0]));
-            }
-        }
-
-        /**
-         * Returns an escaped version of the entry name.
-         * @param entryName
-         */
-        private String escape(String entryName) {
-            return sEscapePattern.matcher(entryName).replaceAll("\\\\$1"); //$NON-NLS-1$
-        }
-    }
-
-    private class LsReceiver extends MultiLineReceiver {
-
-        private ArrayList<FileEntry> mEntryList;
-        private ArrayList<String> mLinkList;
-        private FileEntry[] mCurrentChildren;
-        private FileEntry mParentEntry;
-
-        /**
-         * Create an ls receiver/parser.
-         * @param currentChildren The list of current children. To prevent
-         *      collapse during update, reusing the same FileEntry objects for
-         *      files that were already there is paramount.
-         * @param entryList the list of new children to be filled by the
-         *      receiver.
-         * @param linkList the list of link path to compute post ls, to figure
-         *      out if the link pointed to a file or to a directory.
-         */
-        public LsReceiver(FileEntry parentEntry, ArrayList<FileEntry> entryList,
-                ArrayList<String> linkList) {
-            mParentEntry = parentEntry;
-            mCurrentChildren = parentEntry.getCachedChildren();
-            mEntryList = entryList;
-            mLinkList = linkList;
-        }
-
-        @Override
-        public void processNewLines(String[] lines) {
-            for (String line : lines) {
-                // no need to handle empty lines.
-                if (line.length() == 0) {
-                    continue;
-                }
-
-                // run the line through the regexp
-                Matcher m = sLsPattern.matcher(line);
-                if (m.matches() == false) {
-                    continue;
-                }
-
-                // get the name
-                String name = m.group(7);
-
-                // if the parent is root, we only accept selected items
-                if (mParentEntry.isRoot()) {
-                    boolean found = false;
-                    for (String approved : sRootLevelApprovedItems) {
-                        if (approved.equals(name)) {
-                            found = true;
-                            break;
-                        }
-                    }
-
-                    // if it's not in the approved list we skip this entry.
-                    if (found == false) {
-                        continue;
-                    }
-                }
-
-                // get the rest of the groups
-                String permissions = m.group(1);
-                String owner = m.group(2);
-                String group = m.group(3);
-                String size = m.group(4);
-                String date = m.group(5);
-                String time = m.group(6);
-                String info = null;
-
-                // and the type
-                int objectType = TYPE_OTHER;
-                switch (permissions.charAt(0)) {
-                    case '-' :
-                        objectType = TYPE_FILE;
-                        break;
-                    case 'b' :
-                        objectType = TYPE_BLOCK;
-                        break;
-                    case 'c' :
-                        objectType = TYPE_CHARACTER;
-                        break;
-                    case 'd' :
-                        objectType = TYPE_DIRECTORY;
-                        break;
-                    case 'l' :
-                        objectType = TYPE_LINK;
-                        break;
-                    case 's' :
-                        objectType = TYPE_SOCKET;
-                        break;
-                    case 'p' :
-                        objectType = TYPE_FIFO;
-                        break;
-                }
-
-
-                // now check what we may be linking to
-                if (objectType == TYPE_LINK) {
-                    String[] segments = name.split("\\s->\\s"); //$NON-NLS-1$
-
-                    // we should have 2 segments
-                    if (segments.length == 2) {
-                        // update the entry name to not contain the link
-                        name = segments[0];
-
-                        // and the link name
-                        info = segments[1];
-
-                        // now get the path to the link
-                        String[] pathSegments = info.split(FILE_SEPARATOR);
-                        if (pathSegments.length == 1) {
-                            // the link is to something in the same directory,
-                            // unless the link is ..
-                            if ("..".equals(pathSegments[0])) { //$NON-NLS-1$
-                                // set the type and we're done.
-                                objectType = TYPE_DIRECTORY_LINK;
-                            } else {
-                                // either we found the object already
-                                // or we'll find it later.
-                            }
-                        }
-                    }
-
-                    // add an arrow in front to specify it's a link.
-                    info = "-> " + info; //$NON-NLS-1$;
-                }
-
-                // get the entry, either from an existing one, or a new one
-                FileEntry entry = getExistingEntry(name);
-                if (entry == null) {
-                    entry = new FileEntry(mParentEntry, name, objectType, false /* isRoot */);
-                }
-
-                // add some misc info
-                entry.permissions = permissions;
-                entry.size = size;
-                entry.date = date;
-                entry.time = time;
-                entry.owner = owner;
-                entry.group = group;
-                if (objectType == TYPE_LINK) {
-                    entry.info = info;
-                }
-
-                mEntryList.add(entry);
-            }
-        }
-
-        /**
-         * Queries for an already existing Entry per name
-         * @param name the name of the entry
-         * @return the existing FileEntry or null if no entry with a matching
-         * name exists.
-         */
-        private FileEntry getExistingEntry(String name) {
-            for (int i = 0 ; i < mCurrentChildren.length; i++) {
-                FileEntry e = mCurrentChildren[i];
-
-                // since we're going to "erase" the one we use, we need to
-                // check that the item is not null.
-                if (e != null) {
-                    // compare per name, case-sensitive.
-                    if (name.equals(e.name)) {
-                        // erase from the list
-                        mCurrentChildren[i] = null;
-
-                        // and return the object
-                        return e;
-                    }
-                }
-            }
-
-            // couldn't find any matching object, return null
-            return null;
-        }
-
-        public boolean isCancelled() {
-            return false;
-        }
-
-        public void finishLinks() {
-            // TODO Handle links in the listing service
-        }
-    }
-
-    /**
-     * Classes which implement this interface provide a method that deals with asynchronous
-     * result from <code>ls</code> command on the device.
-     *
-     * @see FileListingService#getChildren(com.android.ddmlib.FileListingService.FileEntry, boolean, com.android.ddmlib.FileListingService.IListingReceiver)
-     */
-    public interface IListingReceiver {
-        public void setChildren(FileEntry entry, FileEntry[] children);
-
-        public void refreshEntry(FileEntry entry);
-    }
-
-    /**
-     * Creates a File Listing Service for a specified {@link Device}.
-     * @param device The Device the service is connected to.
-     */
-    FileListingService(Device device) {
-        mDevice = device;
-    }
-
-    /**
-     * Returns the root element.
-     * @return the {@link FileEntry} object representing the root element or
-     * <code>null</code> if the device is invalid.
-     */
-    public FileEntry getRoot() {
-        if (mDevice != null) {
-            if (mRoot == null) {
-                mRoot = new FileEntry(null /* parent */, "" /* name */, TYPE_DIRECTORY,
-                        true /* isRoot */);
-            }
-
-            return mRoot;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the children of a {@link FileEntry}.
-     * <p/>
-     * This method supports a cache mechanism and synchronous and asynchronous modes.
-     * <p/>
-     * If <var>receiver</var> is <code>null</code>, the device side <code>ls</code>
-     * command is done synchronously, and the method will return upon completion of the command.<br>
-     * If <var>receiver</var> is non <code>null</code>, the command is launched is a separate
-     * thread and upon completion, the receiver will be notified of the result.
-     * <p/>
-     * The result for each <code>ls</code> command is cached in the parent
-     * <code>FileEntry</code>. <var>useCache</var> allows usage of this cache, but only if the
-     * cache is valid. The cache is valid only for {@link FileListingService#REFRESH_RATE} ms.
-     * After that a new <code>ls</code> command is always executed.
-     * <p/>
-     * If the cache is valid and <code>useCache == true</code>, the method will always simply
-     * return the value of the cache, whether a {@link IListingReceiver} has been provided or not.
-     *
-     * @param entry The parent entry.
-     * @param useCache A flag to use the cache or to force a new ls command.
-     * @param receiver A receiver for asynchronous calls.
-     * @return The list of children or <code>null</code> for asynchronous calls.
-     *
-     * @see FileEntry#getCachedChildren()
-     */
-    public FileEntry[] getChildren(final FileEntry entry, boolean useCache,
-            final IListingReceiver receiver) {
-        // first thing we do is check the cache, and if we already have a recent
-        // enough children list, we just return that.
-        if (useCache && entry.needFetch() == false) {
-            return entry.getCachedChildren();
-        }
-
-        // if there's no receiver, then this is a synchronous call, and we
-        // return the result of ls
-        if (receiver == null) {
-            doLs(entry);
-            return entry.getCachedChildren();
-        }
-
-        // this is a asynchronous call.
-        // we launch a thread that will do ls and give the listing
-        // to the receiver
-        Thread t = new Thread("ls " + entry.getFullPath()) { //$NON-NLS-1$
-            @Override
-            public void run() {
-                doLs(entry);
-
-                receiver.setChildren(entry, entry.getCachedChildren());
-
-                final FileEntry[] children = entry.getCachedChildren();
-                if (children.length > 0 && children[0].isApplicationPackage()) {
-                    final HashMap<String, FileEntry> map = new HashMap<String, FileEntry>();
-
-                    for (FileEntry child : children) {
-                        String path = child.getFullPath();
-                        map.put(path, child);
-                    }
-
-                    // call pm.
-                    String command = PM_FULL_LISTING;
-                    try {
-                        mDevice.executeShellCommand(command, new MultiLineReceiver() {
-                            @Override
-                            public void processNewLines(String[] lines) {
-                                for (String line : lines) {
-                                    if (line.length() > 0) {
-                                        // get the filepath and package from the line
-                                        Matcher m = sPmPattern.matcher(line);
-                                        if (m.matches()) {
-                                            // get the children with that path
-                                            FileEntry entry = map.get(m.group(1));
-                                            if (entry != null) {
-                                                entry.info = m.group(2);
-                                                receiver.refreshEntry(entry);
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                            public boolean isCancelled() {
-                                return false;
-                            }
-                        });
-                    } catch (IOException e) {
-                        // adb failed somehow, we do nothing.
-                    }
-                }
-
-
-                // if another thread is pending, launch it
-                synchronized (mThreadList) {
-                    // first remove ourselves from the list
-                    mThreadList.remove(this);
-
-                    // then launch the next one if applicable.
-                    if (mThreadList.size() > 0) {
-                        Thread t = mThreadList.get(0);
-                        t.start();
-                    }
-                }
-            }
-        };
-
-        // we don't want to run multiple ls on the device at the same time, so we
-        // store the thread in a list and launch it only if there's no other thread running.
-        // the thread will launch the next one once it's done.
-        synchronized (mThreadList) {
-            // add to the list
-            mThreadList.add(t);
-
-            // if it's the only one, launch it.
-            if (mThreadList.size() == 1) {
-                t.start();
-            }
-        }
-
-        // and we return null.
-        return null;
-    }
-
-    private void doLs(FileEntry entry) {
-        // create a list that will receive the list of the entries
-        ArrayList<FileEntry> entryList = new ArrayList<FileEntry>();
-
-        // create a list that will receive the link to compute post ls;
-        ArrayList<String> linkList = new ArrayList<String>();
-
-        try {
-            // create the command
-            String command = "ls -l " + entry.getFullPath(); //$NON-NLS-1$
-
-            // create the receiver object that will parse the result from ls
-            LsReceiver receiver = new LsReceiver(entry, entryList, linkList);
-
-            // call ls.
-            mDevice.executeShellCommand(command, receiver);
-
-            // finish the process of the receiver to handle links
-            receiver.finishLinks();
-        } catch (IOException e) {
-        }
-
-
-        // at this point we need to refresh the viewer
-        entry.fetchTime = System.currentTimeMillis();
-
-        // sort the children and set them as the new children
-        Collections.sort(entryList, FileEntry.sEntryComparator);
-        entry.setChildren(entryList);
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/GetPropReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/GetPropReceiver.java
deleted file mode 100644
index 9293379..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/GetPropReceiver.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A receiver able to parse the result of the execution of 
- * {@link #GETPROP_COMMAND} on a device.
- */
-final class GetPropReceiver extends MultiLineReceiver {
-    final static String GETPROP_COMMAND = "getprop"; //$NON-NLS-1$
-    
-    private final static Pattern GETPROP_PATTERN = Pattern.compile("^\\[([^]]+)\\]\\:\\s*\\[(.*)\\]$"); //$NON-NLS-1$
-
-    /** indicates if we need to read the first */
-    private Device mDevice = null;
-
-    /**
-     * Creates the receiver with the device the receiver will modify.
-     * @param device The device to modify
-     */
-    public GetPropReceiver(Device device) {
-        mDevice = device;
-    }
-
-    @Override
-    public void processNewLines(String[] lines) {
-        // We receive an array of lines. We're expecting
-        // to have the build info in the first line, and the build
-        // date in the 2nd line. There seems to be an empty line
-        // after all that.
-
-        for (String line : lines) {
-            if (line.length() == 0 || line.startsWith("#")) {
-                continue;
-            }
-            
-            Matcher m = GETPROP_PATTERN.matcher(line);
-            if (m.matches()) {
-                String label = m.group(1);
-                String value = m.group(2);
-                
-                if (label.length() > 0) {
-                    mDevice.addProperty(label, value);
-                }
-            }
-        }
-    }
-    
-    public boolean isCancelled() {
-        return false;
-    }
-    
-    @Override
-    public void done() {
-        mDevice.update(Device.CHANGE_BUILD_INFO);
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleAppName.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleAppName.java
deleted file mode 100644
index c821dfc..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleAppName.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Handle the "app name" chunk (APNM).
- */
-final class HandleAppName extends ChunkHandler {
-
-    public static final int CHUNK_APNM = ChunkHandler.type("APNM");
-
-    private static final HandleAppName mInst = new HandleAppName();
-
-
-    private HandleAppName() {}
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_APNM, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {}
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data,
-            boolean isReply, int msgId) {
-
-        Log.d("ddm-appname", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_APNM) {
-            assert !isReply;
-            handleAPNM(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-    }
-
-    /*
-     * Handle a reply to our APNM message.
-     */
-    private static void handleAPNM(Client client, ByteBuffer data) {
-        int appNameLen;
-        String appName;
-
-        appNameLen = data.getInt();
-        appName = getString(data, appNameLen);
-
-        Log.d("ddm-appname", "APNM: app='" + appName + "'");
-
-        ClientData cd = client.getClientData();
-        synchronized (cd) {
-            cd.setClientDescription(appName);
-        }
-
-        client = checkDebuggerPortForAppName(client, appName);
-
-        if (client != null) {
-            client.update(Client.CHANGE_NAME);
-        }
-    }
- }
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleExit.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleExit.java
deleted file mode 100644
index adeedbb..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleExit.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Submit an exit request.
- */
-final class HandleExit extends ChunkHandler {
-
-    public static final int CHUNK_EXIT = type("EXIT");
-
-    private static final HandleExit mInst = new HandleExit();
-
-
-    private HandleExit() {}
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {}
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {}
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
-        handleUnknownChunk(client, type, data, isReply, msgId);
-    }
-
-    /**
-     * Send an EXIT request to the client.
-     */
-    public static void sendEXIT(Client client, int status)
-        throws IOException
-    {
-        ByteBuffer rawBuf = allocBuffer(4);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.putInt(status);
-
-        finishChunkPacket(packet, CHUNK_EXIT, buf.position());
-        Log.d("ddm-exit", "Sending " + name(CHUNK_EXIT) + ": " + status);
-        client.sendAndConsume(packet, mInst);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
deleted file mode 100644
index 23050af..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.ClientData.AllocationTrackingStatus;
-import com.android.ddmlib.ClientData.IHprofDumpHandler;
-
-import java.io.IOException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Handle heap status updates.
- */
-final class HandleHeap extends ChunkHandler {
-
-    public static final int CHUNK_HPIF = type("HPIF");
-    public static final int CHUNK_HPST = type("HPST");
-    public static final int CHUNK_HPEN = type("HPEN");
-    public static final int CHUNK_HPSG = type("HPSG");
-    public static final int CHUNK_HPGC = type("HPGC");
-    public static final int CHUNK_HPDU = type("HPDU");
-    public static final int CHUNK_REAE = type("REAE");
-    public static final int CHUNK_REAQ = type("REAQ");
-    public static final int CHUNK_REAL = type("REAL");
-
-    // args to sendHPSG
-    public static final int WHEN_DISABLE = 0;
-    public static final int WHEN_GC = 1;
-    public static final int WHAT_MERGE = 0; // merge adjacent objects
-    public static final int WHAT_OBJ = 1;   // keep objects distinct
-
-    // args to sendHPIF
-    public static final int HPIF_WHEN_NEVER = 0;
-    public static final int HPIF_WHEN_NOW = 1;
-    public static final int HPIF_WHEN_NEXT_GC = 2;
-    public static final int HPIF_WHEN_EVERY_GC = 3;
-
-    private static final HandleHeap mInst = new HandleHeap();
-
-    private HandleHeap() {}
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_HPIF, mInst);
-        mt.registerChunkHandler(CHUNK_HPST, mInst);
-        mt.registerChunkHandler(CHUNK_HPEN, mInst);
-        mt.registerChunkHandler(CHUNK_HPSG, mInst);
-        mt.registerChunkHandler(CHUNK_REAQ, mInst);
-        mt.registerChunkHandler(CHUNK_REAL, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {
-        if (client.isHeapUpdateEnabled()) {
-            //sendHPSG(client, WHEN_GC, WHAT_MERGE);
-            sendHPIF(client, HPIF_WHEN_EVERY_GC);
-        }
-    }
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
-        Log.d("ddm-heap", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_HPIF) {
-            handleHPIF(client, data);
-        } else if (type == CHUNK_HPST) {
-            handleHPST(client, data);
-        } else if (type == CHUNK_HPEN) {
-            handleHPEN(client, data);
-        } else if (type == CHUNK_HPSG) {
-            handleHPSG(client, data);
-        } else if (type == CHUNK_HPDU) {
-            handleHPDU(client, data);
-        } else if (type == CHUNK_REAQ) {
-            handleREAQ(client, data);
-        } else if (type == CHUNK_REAL) {
-            handleREAL(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-    }
-
-    /*
-     * Handle a heap info message.
-     */
-    private void handleHPIF(Client client, ByteBuffer data) {
-        Log.d("ddm-heap", "HPIF!");
-        try {
-            int numHeaps = data.getInt();
-
-            for (int i = 0; i < numHeaps; i++) {
-                int heapId = data.getInt();
-                @SuppressWarnings("unused")
-                long timeStamp = data.getLong();
-                @SuppressWarnings("unused")
-                byte reason = data.get();
-                long maxHeapSize = (long)data.getInt() & 0x00ffffffff;
-                long heapSize = (long)data.getInt() & 0x00ffffffff;
-                long bytesAllocated = (long)data.getInt() & 0x00ffffffff;
-                long objectsAllocated = (long)data.getInt() & 0x00ffffffff;
-
-                client.getClientData().setHeapInfo(heapId, maxHeapSize,
-                        heapSize, bytesAllocated, objectsAllocated);
-                client.update(Client.CHANGE_HEAP_DATA);
-            }
-        } catch (BufferUnderflowException ex) {
-            Log.w("ddm-heap", "malformed HPIF chunk from client");
-        }
-    }
-
-    /**
-     * Send an HPIF (HeaP InFo) request to the client.
-     */
-    public static void sendHPIF(Client client, int when) throws IOException {
-        ByteBuffer rawBuf = allocBuffer(1);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.put((byte)when);
-
-        finishChunkPacket(packet, CHUNK_HPIF, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_HPIF) + ": when=" + when);
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /*
-     * Handle a heap segment series start message.
-     */
-    private void handleHPST(Client client, ByteBuffer data) {
-        /* Clear out any data that's sitting around to
-         * get ready for the chunks that are about to come.
-         */
-//xxx todo: only clear data that belongs to the heap mentioned in <data>.
-        client.getClientData().getVmHeapData().clearHeapData();
-    }
-
-    /*
-     * Handle a heap segment series end message.
-     */
-    private void handleHPEN(Client client, ByteBuffer data) {
-        /* Let the UI know that we've received all of the
-         * data for this heap.
-         */
-//xxx todo: only seal data that belongs to the heap mentioned in <data>.
-        client.getClientData().getVmHeapData().sealHeapData();
-        client.update(Client.CHANGE_HEAP_DATA);
-    }
-
-    /*
-     * Handle a heap segment message.
-     */
-    private void handleHPSG(Client client, ByteBuffer data) {
-        byte dataCopy[] = new byte[data.limit()];
-        data.rewind();
-        data.get(dataCopy);
-        data = ByteBuffer.wrap(dataCopy);
-        client.getClientData().getVmHeapData().addHeapData(data);
-//xxx todo: add to the heap mentioned in <data>
-    }
-
-    /**
-     * Sends an HPSG (HeaP SeGment) request to the client.
-     */
-    public static void sendHPSG(Client client, int when, int what)
-        throws IOException {
-
-        ByteBuffer rawBuf = allocBuffer(2);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.put((byte)when);
-        buf.put((byte)what);
-
-        finishChunkPacket(packet, CHUNK_HPSG, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_HPSG) + ": when="
-            + when + ", what=" + what);
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /**
-     * Sends an HPGC request to the client.
-     */
-    public static void sendHPGC(Client client)
-        throws IOException {
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // no data
-
-        finishChunkPacket(packet, CHUNK_HPGC, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_HPGC));
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /**
-     * Sends an HPDU request to the client.
-     *
-     * We will get an HPDU response when the heap dump has completed.  On
-     * failure we get a generic failure response.
-     *
-     * @param fileName name of output file (on device)
-     */
-    public static void sendHPDU(Client client, String fileName)
-        throws IOException {
-        ByteBuffer rawBuf = allocBuffer(4 + fileName.length() * 2);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.putInt(fileName.length());
-        putString(buf, fileName);
-
-        finishChunkPacket(packet, CHUNK_HPDU, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_HPDU) + " '" + fileName +"'");
-        client.sendAndConsume(packet, mInst);
-        client.getClientData().setPendingHprofDump(fileName);
-    }
-
-    /*
-     * Handle notification of completion of a HeaP DUmp.
-     */
-    private void handleHPDU(Client client, ByteBuffer data) {
-        byte result;
-
-        // get the filename and make the client not have pending HPROF dump anymore.
-        String filename = client.getClientData().getPendingHprofDump();
-        client.getClientData().setPendingHprofDump(null);
-
-        // get the dump result
-        result = data.get();
-
-        // get the app-level handler for HPROF dump
-        IHprofDumpHandler handler = ClientData.getHprofDumpHandler();
-        if (handler != null) {
-            if (result == 0) {
-                handler.onSuccess(filename, client);
-
-                Log.d("ddm-heap", "Heap dump request has finished");
-            } else {
-                handler.onFailure(client);
-                Log.w("ddm-heap", "Heap dump request failed (check device log)");
-            }
-        }
-    }
-
-    /**
-     * Sends a REAE (REcent Allocation Enable) request to the client.
-     */
-    public static void sendREAE(Client client, boolean enable)
-        throws IOException {
-        ByteBuffer rawBuf = allocBuffer(1);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.put((byte) (enable ? 1 : 0));
-
-        finishChunkPacket(packet, CHUNK_REAE, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_REAE) + ": " + enable);
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /**
-     * Sends a REAQ (REcent Allocation Query) request to the client.
-     */
-    public static void sendREAQ(Client client)
-        throws IOException {
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // no data
-
-        finishChunkPacket(packet, CHUNK_REAQ, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_REAQ));
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /**
-     * Sends a REAL (REcent ALlocation) request to the client.
-     */
-    public static void sendREAL(Client client)
-        throws IOException {
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // no data
-
-        finishChunkPacket(packet, CHUNK_REAL, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_REAL));
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /*
-     * Handle the response from our REcent Allocation Query message.
-     */
-    private void handleREAQ(Client client, ByteBuffer data) {
-        boolean enabled;
-
-        enabled = (data.get() != 0);
-        Log.d("ddm-heap", "REAQ says: enabled=" + enabled);
-
-        client.getClientData().setAllocationStatus(enabled ?
-                AllocationTrackingStatus.ON : AllocationTrackingStatus.OFF);
-        client.update(Client.CHANGE_HEAP_ALLOCATION_STATUS);
-    }
-
-    /**
-     * Converts a VM class descriptor string ("Landroid/os/Debug;") to
-     * a dot-notation class name ("android.os.Debug").
-     */
-    private String descriptorToDot(String str) {
-        // count the number of arrays.
-        int array = 0;
-        while (str.startsWith("[")) {
-            str = str.substring(1);
-            array++;
-        }
-
-        int len = str.length();
-
-        /* strip off leading 'L' and trailing ';' if appropriate */
-        if (len >= 2 && str.charAt(0) == 'L' && str.charAt(len - 1) == ';') {
-            str = str.substring(1, len-1);
-            str = str.replace('/', '.');
-        } else {
-            // convert the basic types
-            if ("C".equals(str)) {
-                str = "char";
-            } else if ("B".equals(str)) {
-                str = "byte";
-            } else if ("Z".equals(str)) {
-                str = "boolean";
-            } else if ("S".equals(str)) {
-                str = "short";
-            } else if ("I".equals(str)) {
-                str = "int";
-            } else if ("J".equals(str)) {
-                str = "long";
-            } else if ("F".equals(str)) {
-                str = "float";
-            } else if ("D".equals(str)) {
-                str = "double";
-            }
-        }
-
-        // now add the array part
-        for (int a = 0 ; a < array; a++) {
-            str = str + "[]";
-        }
-
-        return str;
-    }
-
-    /**
-     * Reads a string table out of "data".
-     *
-     * This is just a serial collection of strings, each of which is a
-     * four-byte length followed by UTF-16 data.
-     */
-    private void readStringTable(ByteBuffer data, String[] strings) {
-        int count = strings.length;
-        int i;
-
-        for (i = 0; i < count; i++) {
-            int nameLen = data.getInt();
-            String descriptor = getString(data, nameLen);
-            strings[i] = descriptorToDot(descriptor);
-        }
-    }
-
-    /*
-     * Handle a REcent ALlocation response.
-     *
-     * Message header (all values big-endian):
-     *   (1b) message header len (to allow future expansion); includes itself
-     *   (1b) entry header len
-     *   (1b) stack frame len
-     *   (2b) number of entries
-     *   (4b) offset to string table from start of message
-     *   (2b) number of class name strings
-     *   (2b) number of method name strings
-     *   (2b) number of source file name strings
-     *   For each entry:
-     *     (4b) total allocation size
-     *     (2b) threadId
-     *     (2b) allocated object's class name index
-     *     (1b) stack depth
-     *     For each stack frame:
-     *       (2b) method's class name
-     *       (2b) method name
-     *       (2b) method source file
-     *       (2b) line number, clipped to 32767; -2 if native; -1 if no source
-     *   (xb) class name strings
-     *   (xb) method name strings
-     *   (xb) source file strings
-     *
-     *   As with other DDM traffic, strings are sent as a 4-byte length
-     *   followed by UTF-16 data.
-     */
-    private void handleREAL(Client client, ByteBuffer data) {
-        Log.e("ddm-heap", "*** Received " + name(CHUNK_REAL));
-        int messageHdrLen, entryHdrLen, stackFrameLen;
-        int numEntries, offsetToStrings;
-        int numClassNames, numMethodNames, numFileNames;
-
-        /*
-         * Read the header.
-         */
-        messageHdrLen = (data.get() & 0xff);
-        entryHdrLen = (data.get() & 0xff);
-        stackFrameLen = (data.get() & 0xff);
-        numEntries = (data.getShort() & 0xffff);
-        offsetToStrings = data.getInt();
-        numClassNames = (data.getShort() & 0xffff);
-        numMethodNames = (data.getShort() & 0xffff);
-        numFileNames = (data.getShort() & 0xffff);
-
-
-        /*
-         * Skip forward to the strings and read them.
-         */
-        data.position(offsetToStrings);
-
-        String[] classNames = new String[numClassNames];
-        String[] methodNames = new String[numMethodNames];
-        String[] fileNames = new String[numFileNames];
-
-        readStringTable(data, classNames);
-        readStringTable(data, methodNames);
-        //System.out.println("METHODS: "
-        //    + java.util.Arrays.deepToString(methodNames));
-        readStringTable(data, fileNames);
-
-        /*
-         * Skip back to a point just past the header and start reading
-         * entries.
-         */
-        data.position(messageHdrLen);
-
-        ArrayList<AllocationInfo> list = new ArrayList<AllocationInfo>(numEntries);
-        for (int i = 0; i < numEntries; i++) {
-            int totalSize;
-            int threadId, classNameIndex, stackDepth;
-
-            totalSize = data.getInt();
-            threadId = (data.getShort() & 0xffff);
-            classNameIndex = (data.getShort() & 0xffff);
-            stackDepth = (data.get() & 0xff);
-            /* we've consumed 9 bytes; gobble up any extra */
-            for (int skip = 9; skip < entryHdrLen; skip++)
-                data.get();
-
-            StackTraceElement[] steArray = new StackTraceElement[stackDepth];
-
-            /*
-             * Pull out the stack trace.
-             */
-            for (int sti = 0; sti < stackDepth; sti++) {
-                int methodClassNameIndex, methodNameIndex;
-                int methodSourceFileIndex;
-                short lineNumber;
-                String methodClassName, methodName, methodSourceFile;
-
-                methodClassNameIndex = (data.getShort() & 0xffff);
-                methodNameIndex = (data.getShort() & 0xffff);
-                methodSourceFileIndex = (data.getShort() & 0xffff);
-                lineNumber = data.getShort();
-
-                methodClassName = classNames[methodClassNameIndex];
-                methodName = methodNames[methodNameIndex];
-                methodSourceFile = fileNames[methodSourceFileIndex];
-
-                steArray[sti] = new StackTraceElement(methodClassName,
-                    methodName, methodSourceFile, lineNumber);
-
-                /* we've consumed 8 bytes; gobble up any extra */
-                for (int skip = 9; skip < stackFrameLen; skip++)
-                    data.get();
-            }
-
-            list.add(new AllocationInfo(classNames[classNameIndex],
-                totalSize, (short) threadId, steArray));
-        }
-
-        // sort biggest allocations first.
-        Collections.sort(list);
-
-        client.getClientData().setAllocations(list.toArray(new AllocationInfo[numEntries]));
-        client.update(Client.CHANGE_HEAP_ALLOCATIONS);
-    }
-
-    /*
-     * For debugging: dump the contents of an AllocRecord array.
-     *
-     * The array starts with the oldest known allocation and ends with
-     * the most recent allocation.
-     */
-    @SuppressWarnings("unused")
-    private static void dumpRecords(AllocationInfo[] records) {
-        System.out.println("Found " + records.length + " records:");
-
-        for (AllocationInfo rec: records) {
-            System.out.println("tid=" + rec.getThreadId() + " "
-                + rec.getAllocatedClass() + " (" + rec.getSize() + " bytes)");
-
-            for (StackTraceElement ste: rec.getStackTrace()) {
-                if (ste.isNativeMethod()) {
-                    System.out.println("    " + ste.getClassName()
-                        + "." + ste.getMethodName()
-                        + " (Native method)");
-                } else {
-                    System.out.println("    " + ste.getClassName()
-                        + "." + ste.getMethodName()
-                        + " (" + ste.getFileName()
-                        + ":" + ste.getLineNumber() + ")");
-                }
-            }
-        }
-    }
-
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
deleted file mode 100644
index 4e62bca..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Handle the "hello" chunk (HELO) and feature discovery.
- */
-final class HandleHello extends ChunkHandler {
-
-    public static final int CHUNK_HELO = ChunkHandler.type("HELO");
-    public static final int CHUNK_FEAT = ChunkHandler.type("FEAT");
-
-    private static final HandleHello mInst = new HandleHello();
-
-    private HandleHello() {}
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_HELO, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {
-        Log.d("ddm-hello", "Now ready: " + client);
-    }
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {
-        Log.d("ddm-hello", "Now disconnected: " + client);
-    }
-
-    /**
-     * Sends HELLO-type commands to the VM after a good handshake.
-     * @param client
-     * @param serverProtocolVersion
-     * @throws IOException
-     */
-    public static void sendHelloCommands(Client client, int serverProtocolVersion)
-            throws IOException {
-        sendHELO(client, serverProtocolVersion);
-        sendFEAT(client);
-        HandleProfiling.sendMPRQ(client);
-    }
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
-
-        Log.d("ddm-hello", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_HELO) {
-            assert isReply;
-            handleHELO(client, data);
-        } else if (type == CHUNK_FEAT) {
-            handleFEAT(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-    }
-
-    /*
-     * Handle a reply to our HELO message.
-     */
-    private static void handleHELO(Client client, ByteBuffer data) {
-        int version, pid, vmIdentLen, appNameLen;
-        String vmIdent, appName;
-
-        version = data.getInt();
-        pid = data.getInt();
-        vmIdentLen = data.getInt();
-        appNameLen = data.getInt();
-
-        vmIdent = getString(data, vmIdentLen);
-        appName = getString(data, appNameLen);
-
-        Log.d("ddm-hello", "HELO: v=" + version + ", pid=" + pid
-            + ", vm='" + vmIdent + "', app='" + appName + "'");
-
-        ClientData cd = client.getClientData();
-
-        synchronized (cd) {
-            if (cd.getPid() == pid) {
-                cd.setVmIdentifier(vmIdent);
-                cd.setClientDescription(appName);
-                cd.isDdmAware(true);
-            } else {
-                Log.e("ddm-hello", "Received pid (" + pid + ") does not match client pid ("
-                        + cd.getPid() + ")");
-            }
-        }
-
-        client = checkDebuggerPortForAppName(client, appName);
-
-        if (client != null) {
-            client.update(Client.CHANGE_NAME);
-        }
-    }
-
-
-    /**
-     * Send a HELO request to the client.
-     */
-    public static void sendHELO(Client client, int serverProtocolVersion)
-        throws IOException
-    {
-        ByteBuffer rawBuf = allocBuffer(4);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.putInt(serverProtocolVersion);
-
-        finishChunkPacket(packet, CHUNK_HELO, buf.position());
-        Log.d("ddm-hello", "Sending " + name(CHUNK_HELO)
-            + " ID=0x" + Integer.toHexString(packet.getId()));
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /**
-     * Handle a reply to our FEAT request.
-     */
-    private static void handleFEAT(Client client, ByteBuffer data) {
-        int featureCount;
-        int i;
-
-        featureCount = data.getInt();
-        for (i = 0; i < featureCount; i++) {
-            int len = data.getInt();
-            String feature = getString(data, len);
-            client.getClientData().addFeature(feature);
-
-            Log.d("ddm-hello", "Feature: " + feature);
-        }
-    }
-
-    /**
-     * Send a FEAT request to the client.
-     */
-    public static void sendFEAT(Client client) throws IOException {
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // no data
-
-        finishChunkPacket(packet, CHUNK_FEAT, buf.position());
-        Log.d("ddm-heap", "Sending " + name(CHUNK_FEAT));
-        client.sendAndConsume(packet, mInst);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java
deleted file mode 100644
index ca26590..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Handle thread status updates.
- */
-final class HandleNativeHeap extends ChunkHandler {
-
-    public static final int CHUNK_NHGT = type("NHGT"); // $NON-NLS-1$
-    public static final int CHUNK_NHSG = type("NHSG"); // $NON-NLS-1$
-    public static final int CHUNK_NHST = type("NHST"); // $NON-NLS-1$
-    public static final int CHUNK_NHEN = type("NHEN"); // $NON-NLS-1$
-
-    private static final HandleNativeHeap mInst = new HandleNativeHeap();
-
-    private HandleNativeHeap() {
-    }
-
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_NHGT, mInst);
-        mt.registerChunkHandler(CHUNK_NHSG, mInst);
-        mt.registerChunkHandler(CHUNK_NHST, mInst);
-        mt.registerChunkHandler(CHUNK_NHEN, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {}
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
-
-        Log.d("ddm-nativeheap", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_NHGT) {
-            handleNHGT(client, data);
-        } else if (type == CHUNK_NHST) {
-            // start chunk before any NHSG chunk(s)
-            client.getClientData().getNativeHeapData().clearHeapData();
-        } else if (type == CHUNK_NHEN) {
-            // end chunk after NHSG chunk(s)
-            client.getClientData().getNativeHeapData().sealHeapData();
-        } else if (type == CHUNK_NHSG) {
-            handleNHSG(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-
-        client.update(Client.CHANGE_NATIVE_HEAP_DATA);
-    }
-
-    /**
-     * Send an NHGT (Native Thread GeT) request to the client.
-     */
-    public static void sendNHGT(Client client) throws IOException {
-
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // no data in request message
-
-        finishChunkPacket(packet, CHUNK_NHGT, buf.position());
-        Log.d("ddm-nativeheap", "Sending " + name(CHUNK_NHGT));
-        client.sendAndConsume(packet, mInst);
-
-        rawBuf = allocBuffer(2);
-        packet = new JdwpPacket(rawBuf);
-        buf = getChunkDataBuf(rawBuf);
-
-        buf.put((byte)HandleHeap.WHEN_GC);
-        buf.put((byte)HandleHeap.WHAT_OBJ);
-
-        finishChunkPacket(packet, CHUNK_NHSG, buf.position());
-        Log.d("ddm-nativeheap", "Sending " + name(CHUNK_NHSG));
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /*
-     * Handle our native heap data.
-     */
-    private void handleNHGT(Client client, ByteBuffer data) {
-        ClientData cd = client.getClientData();
-
-        Log.d("ddm-nativeheap", "NHGT: " + data.limit() + " bytes");
-
-        // TODO - process incoming data and save in "cd"
-        byte[] copy = new byte[data.limit()];
-        data.get(copy);
-
-        // clear the previous run
-        cd.clearNativeAllocationInfo();
-
-        ByteBuffer buffer = ByteBuffer.wrap(copy);
-        buffer.order(ByteOrder.LITTLE_ENDIAN);
-
-//        read the header
-//        typedef struct Header {
-//            uint32_t mapSize;
-//            uint32_t allocSize;
-//            uint32_t allocInfoSize;
-//            uint32_t totalMemory;
-//              uint32_t backtraceSize;
-//        };
-
-        int mapSize = buffer.getInt();
-        int allocSize = buffer.getInt();
-        int allocInfoSize = buffer.getInt();
-        int totalMemory = buffer.getInt();
-        int backtraceSize = buffer.getInt();
-
-        Log.d("ddms", "mapSize: " + mapSize);
-        Log.d("ddms", "allocSize: " + allocSize);
-        Log.d("ddms", "allocInfoSize: " + allocInfoSize);
-        Log.d("ddms", "totalMemory: " + totalMemory);
-
-        cd.setTotalNativeMemory(totalMemory);
-
-        // this means that updates aren't turned on.
-        if (allocInfoSize == 0)
-          return;
-
-        if (mapSize > 0) {
-            byte[] maps = new byte[mapSize];
-            buffer.get(maps, 0, mapSize);
-            parseMaps(cd, maps);
-        }
-
-        int iterations = allocSize / allocInfoSize;
-
-        for (int i = 0 ; i < iterations ; i++) {
-            NativeAllocationInfo info = new NativeAllocationInfo(
-                    buffer.getInt() /* size */,
-                    buffer.getInt() /* allocations */);
-
-            for (int j = 0 ; j < backtraceSize ; j++) {
-                long addr = ((long)buffer.getInt()) & 0x00000000ffffffffL;
-
-                info.addStackCallAddress(addr);;
-            }
-
-            cd.addNativeAllocation(info);
-        }
-    }
-
-    private void handleNHSG(Client client, ByteBuffer data) {
-        byte dataCopy[] = new byte[data.limit()];
-        data.rewind();
-        data.get(dataCopy);
-        data = ByteBuffer.wrap(dataCopy);
-        client.getClientData().getNativeHeapData().addHeapData(data);
-
-        if (true) {
-            return;
-        }
-
-        // WORK IN PROGRESS
-
-//        Log.e("ddm-nativeheap", "NHSG: ----------------------------------");
-//        Log.e("ddm-nativeheap", "NHSG: " + data.limit() + " bytes");
-
-        byte[] copy = new byte[data.limit()];
-        data.get(copy);
-
-        ByteBuffer buffer = ByteBuffer.wrap(copy);
-        buffer.order(ByteOrder.BIG_ENDIAN);
-
-        int id = buffer.getInt();
-        int unitsize = (int) buffer.get();
-        long startAddress = (long) buffer.getInt() & 0x00000000ffffffffL;
-        int offset = buffer.getInt();
-        int allocationUnitCount = buffer.getInt();
-
-//        Log.e("ddm-nativeheap", "id: " + id);
-//        Log.e("ddm-nativeheap", "unitsize: " + unitsize);
-//        Log.e("ddm-nativeheap", "startAddress: 0x" + Long.toHexString(startAddress));
-//        Log.e("ddm-nativeheap", "offset: " + offset);
-//        Log.e("ddm-nativeheap", "allocationUnitCount: " + allocationUnitCount);
-//        Log.e("ddm-nativeheap", "end: 0x" +
-//                Long.toHexString(startAddress + unitsize * allocationUnitCount));
-
-        // read the usage
-        while (buffer.position() < buffer.limit()) {
-            int eState = (int)buffer.get() & 0x000000ff;
-            int eLen = ((int)buffer.get() & 0x000000ff) + 1;
-            //Log.e("ddm-nativeheap", "solidity: " + (eState & 0x7) + " - kind: "
-            //        + ((eState >> 3) & 0x7) + " - len: " + eLen);
-        }
-
-
-//        count += unitsize * allocationUnitCount;
-//        Log.e("ddm-nativeheap", "count = " + count);
-
-    }
-
-    private void parseMaps(ClientData cd, byte[] maps) {
-        InputStreamReader input = new InputStreamReader(new ByteArrayInputStream(maps));
-        BufferedReader reader = new BufferedReader(input);
-
-        String line;
-
-        try {
-
-            // most libraries are defined on several lines, so we need to make sure we parse
-            // all the library lines and only add the library at the end
-            long startAddr = 0;
-            long endAddr = 0;
-            String library = null;
-
-            while ((line = reader.readLine()) != null) {
-                Log.d("ddms", "line: " + line);
-                if (line.length() < 16) {
-                    continue;
-                }
-
-                try {
-                    long tmpStart = Long.parseLong(line.substring(0, 8), 16);
-                    long tmpEnd = Long.parseLong(line.substring(9, 17), 16);
-
-                     /*
-                      * only check for library addresses as defined in
-                      * //device/config/prelink-linux-arm.map
-                      */
-                    if (tmpStart >= 0x0000000080000000L && tmpStart <= 0x00000000BFFFFFFFL) {
-
-                        int index = line.indexOf('/');
-
-                        if (index == -1)
-                            continue;
-
-                        String tmpLib = line.substring(index);
-
-                        if (library == null ||
-                                (library != null && tmpLib.equals(library) == false)) {
-
-                            if (library != null) {
-                                cd.addNativeLibraryMapInfo(startAddr, endAddr, library);
-                                Log.d("ddms", library + "(" + Long.toHexString(startAddr) +
-                                        " - " + Long.toHexString(endAddr) + ")");
-                            }
-
-                            // now init the new library
-                            library = tmpLib;
-                            startAddr = tmpStart;
-                            endAddr = tmpEnd;
-                        } else {
-                            // add the new end
-                            endAddr = tmpEnd;
-                        }
-                    }
-                } catch (NumberFormatException e) {
-                    e.printStackTrace();
-                }
-            }
-
-            if (library != null) {
-                cd.addNativeLibraryMapInfo(startAddr, endAddr, library);
-                Log.d("ddms", library + "(" + Long.toHexString(startAddr) +
-                        " - " + Long.toHexString(endAddr) + ")");
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java
deleted file mode 100644
index 3b69973..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmlib;
-
-import com.android.ddmlib.ClientData.IMethodProfilingHandler;
-import com.android.ddmlib.ClientData.MethodProfilingStatus;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Handle heap status updates.
- */
-final class HandleProfiling extends ChunkHandler {
-
-    public static final int CHUNK_MPRS = type("MPRS");
-    public static final int CHUNK_MPRE = type("MPRE");
-    public static final int CHUNK_MPRQ = type("MPRQ");
-    public static final int CHUNK_FAIL = type("FAIL");
-
-    private static final HandleProfiling mInst = new HandleProfiling();
-
-    private HandleProfiling() {}
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_MPRE, mInst);
-        mt.registerChunkHandler(CHUNK_MPRQ, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {}
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data,
-        boolean isReply, int msgId) {
-
-        Log.d("ddm-prof", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_MPRE) {
-            handleMPRE(client, data);
-        } else if (type == CHUNK_MPRQ) {
-            handleMPRQ(client, data);
-        } else if (type == CHUNK_FAIL) {
-            handleFAIL(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-    }
-
-    /**
-     * Send a MPRS (Method PRofiling Start) request to the client.
-     *
-     * The arguments to this method will eventually be passed to
-     * android.os.Debug.startMethodTracing() on the device.
-     *
-     * @param fileName is the name of the file to which profiling data
-     *          will be written (on the device); it will have ".trace"
-     *          appended if necessary
-     * @param bufferSize is the desired buffer size in bytes (8MB is good)
-     * @param flags see startMethodTracing() docs; use 0 for default behavior
-     */
-    public static void sendMPRS(Client client, String fileName, int bufferSize,
-        int flags) throws IOException {
-
-        ByteBuffer rawBuf = allocBuffer(3*4 + fileName.length() * 2);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.putInt(bufferSize);
-        buf.putInt(flags);
-        buf.putInt(fileName.length());
-        putString(buf, fileName);
-
-        finishChunkPacket(packet, CHUNK_MPRS, buf.position());
-        Log.d("ddm-prof", "Sending " + name(CHUNK_MPRS) + " '" + fileName
-            + "', size=" + bufferSize + ", flags=" + flags);
-        client.sendAndConsume(packet, mInst);
-
-        // record the filename we asked for.
-        client.getClientData().setPendingMethodProfiling(fileName);
-
-        // send a status query. this ensure that the status is properly updated if for some
-        // reason starting the tracing failed.
-        sendMPRQ(client);
-    }
-
-    /**
-     * Send a MPRE (Method PRofiling End) request to the client.
-     */
-    public static void sendMPRE(Client client) throws IOException {
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // no data
-
-        finishChunkPacket(packet, CHUNK_MPRE, buf.position());
-        Log.d("ddm-prof", "Sending " + name(CHUNK_MPRE));
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /**
-     * Handle notification that method profiling has finished writing
-     * data to disk.
-     */
-    private void handleMPRE(Client client, ByteBuffer data) {
-        byte result;
-
-        // get the filename and make the client not have pending HPROF dump anymore.
-        String filename = client.getClientData().getPendingMethodProfiling();
-        client.getClientData().setPendingMethodProfiling(null);
-
-        result = data.get();
-
-        // get the app-level handler for method tracing dump
-        IMethodProfilingHandler handler = ClientData.getMethodProfilingHandler();
-        if (handler != null) {
-            if (result == 0) {
-                handler.onSuccess(filename, client);
-
-                Log.d("ddm-prof", "Method profiling has finished");
-            } else {
-                handler.onFailure(client);
-
-                Log.w("ddm-prof", "Method profiling has failed (check device log)");
-            }
-        }
-
-        client.getClientData().setMethodProfilingStatus(MethodProfilingStatus.OFF);
-        client.update(Client.CHANGE_METHOD_PROFILING_STATUS);
-    }
-
-    /**
-     * Send a MPRQ (Method PRofiling Query) request to the client.
-     */
-    public static void sendMPRQ(Client client) throws IOException {
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // no data
-
-        finishChunkPacket(packet, CHUNK_MPRQ, buf.position());
-        Log.d("ddm-prof", "Sending " + name(CHUNK_MPRQ));
-        client.sendAndConsume(packet, mInst);
-    }
-
-    /**
-     * Receive response to query.
-     */
-    private void handleMPRQ(Client client, ByteBuffer data) {
-        byte result;
-
-        result = data.get();
-
-        if (result == 0) {
-            client.getClientData().setMethodProfilingStatus(MethodProfilingStatus.OFF);
-            Log.d("ddm-prof", "Method profiling is not running");
-        } else {
-            client.getClientData().setMethodProfilingStatus(MethodProfilingStatus.ON);
-            Log.d("ddm-prof", "Method profiling is running");
-        }
-        client.update(Client.CHANGE_METHOD_PROFILING_STATUS);
-    }
-
-    private void handleFAIL(Client client, ByteBuffer data) {
-        // this can be sent if MPRS failed (like wrong permission)
-
-        String filename = client.getClientData().getPendingMethodProfiling();
-        if (filename != null) {
-            // reset the pending file.
-            client.getClientData().setPendingMethodProfiling(null);
-
-            // and notify of failure
-            IMethodProfilingHandler handler = ClientData.getMethodProfilingHandler();
-            if (handler != null) {
-                handler.onFailure(client);
-            }
-
-        }
-
-        // send a query to know the current status
-        try {
-            sendMPRQ(client);
-        } catch (IOException e) {
-            Log.e("HandleProfiling", e);
-        }
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleTest.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleTest.java
deleted file mode 100644
index b9f3a74..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.Log.LogLevel;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Handle thread status updates.
- */
-final class HandleTest extends ChunkHandler {
-
-    public static final int CHUNK_TEST = type("TEST");
-
-    private static final HandleTest mInst = new HandleTest();
-
-
-    private HandleTest() {}
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_TEST, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {}
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
-
-        Log.d("ddm-test", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_TEST) {
-            handleTEST(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-    }
-
-    /*
-     * Handle a thread creation message.
-     */
-    private void handleTEST(Client client, ByteBuffer data)
-    {
-        /*
-         * Can't call data.array() on a read-only ByteBuffer, so we make
-         * a copy.
-         */
-        byte[] copy = new byte[data.limit()];
-        data.get(copy);
-
-        Log.d("ddm-test", "Received:");
-        Log.hexDump("ddm-test", LogLevel.DEBUG, copy, 0, copy.length);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleThread.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleThread.java
deleted file mode 100644
index 8430c95..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleThread.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Handle thread status updates.
- */
-final class HandleThread extends ChunkHandler {
-
-    public static final int CHUNK_THEN = type("THEN");
-    public static final int CHUNK_THCR = type("THCR");
-    public static final int CHUNK_THDE = type("THDE");
-    public static final int CHUNK_THST = type("THST");
-    public static final int CHUNK_THNM = type("THNM");
-    public static final int CHUNK_STKL = type("STKL");
-
-    private static final HandleThread mInst = new HandleThread();
-
-    // only read/written by requestThreadUpdates()
-    private static volatile boolean mThreadStatusReqRunning = false;
-    private static volatile boolean mThreadStackTraceReqRunning = false;
-
-    private HandleThread() {}
-
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_THCR, mInst);
-        mt.registerChunkHandler(CHUNK_THDE, mInst);
-        mt.registerChunkHandler(CHUNK_THST, mInst);
-        mt.registerChunkHandler(CHUNK_THNM, mInst);
-        mt.registerChunkHandler(CHUNK_STKL, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {
-        Log.d("ddm-thread", "Now ready: " + client);
-        if (client.isThreadUpdateEnabled())
-            sendTHEN(client, true);
-    }
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
-
-        Log.d("ddm-thread", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_THCR) {
-            handleTHCR(client, data);
-        } else if (type == CHUNK_THDE) {
-            handleTHDE(client, data);
-        } else if (type == CHUNK_THST) {
-            handleTHST(client, data);
-        } else if (type == CHUNK_THNM) {
-            handleTHNM(client, data);
-        } else if (type == CHUNK_STKL) {
-            handleSTKL(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-    }
-
-    /*
-     * Handle a thread creation message.
-     *
-     * We should be tolerant of receiving a duplicate create message.  (It
-     * shouldn't happen with the current implementation.)
-     */
-    private void handleTHCR(Client client, ByteBuffer data) {
-        int threadId, nameLen;
-        String name;
-
-        threadId = data.getInt();
-        nameLen = data.getInt();
-        name = getString(data, nameLen);
-
-        Log.v("ddm-thread", "THCR: " + threadId + " '" + name + "'");
-
-        client.getClientData().addThread(threadId, name);
-        client.update(Client.CHANGE_THREAD_DATA);
-    }
-
-    /*
-     * Handle a thread death message.
-     */
-    private void handleTHDE(Client client, ByteBuffer data) {
-        int threadId;
-
-        threadId = data.getInt();
-        Log.v("ddm-thread", "THDE: " + threadId);
-
-        client.getClientData().removeThread(threadId);
-        client.update(Client.CHANGE_THREAD_DATA);
-    }
-
-    /*
-     * Handle a thread status update message.
-     *
-     * Response has:
-     *  (1b) header len
-     *  (1b) bytes per entry
-     *  (2b) thread count
-     * Then, for each thread:
-     *  (4b) threadId (matches value from THCR)
-     *  (1b) thread status
-     *  (4b) tid
-     *  (4b) utime
-     *  (4b) stime
-     */
-    private void handleTHST(Client client, ByteBuffer data) {
-        int headerLen, bytesPerEntry, extraPerEntry;
-        int threadCount;
-
-        headerLen = (data.get() & 0xff);
-        bytesPerEntry = (data.get() & 0xff);
-        threadCount = data.getShort();
-
-        headerLen -= 4;     // we've read 4 bytes
-        while (headerLen-- > 0)
-            data.get();
-
-        extraPerEntry = bytesPerEntry - 18;     // we want 18 bytes
-
-        Log.v("ddm-thread", "THST: threadCount=" + threadCount);
-
-        /*
-         * For each thread, extract the data, find the appropriate
-         * client, and add it to the ClientData.
-         */
-        for (int i = 0; i < threadCount; i++) {
-            int threadId, status, tid, utime, stime;
-            boolean isDaemon = false;
-
-            threadId = data.getInt();
-            status = data.get();
-            tid = data.getInt();
-            utime = data.getInt();
-            stime = data.getInt();
-            if (bytesPerEntry >= 18)
-                isDaemon = (data.get() != 0);
-
-            Log.v("ddm-thread", "  id=" + threadId
-                + ", status=" + status + ", tid=" + tid
-                + ", utime=" + utime + ", stime=" + stime);
-
-            ClientData cd = client.getClientData();
-            ThreadInfo threadInfo = cd.getThread(threadId);
-            if (threadInfo != null)
-                threadInfo.updateThread(status, tid, utime, stime, isDaemon);
-            else
-                Log.d("ddms", "Thread with id=" + threadId + " not found");
-
-            // slurp up any extra
-            for (int slurp = extraPerEntry; slurp > 0; slurp--)
-                data.get();
-        }
-
-        client.update(Client.CHANGE_THREAD_DATA);
-    }
-
-    /*
-     * Handle a THNM (THread NaMe) message.  We get one of these after
-     * somebody calls Thread.setName() on a running thread.
-     */
-    private void handleTHNM(Client client, ByteBuffer data) {
-        int threadId, nameLen;
-        String name;
-
-        threadId = data.getInt();
-        nameLen = data.getInt();
-        name = getString(data, nameLen);
-
-        Log.v("ddm-thread", "THNM: " + threadId + " '" + name + "'");
-
-        ThreadInfo threadInfo = client.getClientData().getThread(threadId);
-        if (threadInfo != null) {
-            threadInfo.setThreadName(name);
-            client.update(Client.CHANGE_THREAD_DATA);
-        } else {
-            Log.d("ddms", "Thread with id=" + threadId + " not found");
-        }
-    }
-
-
-    /**
-     * Parse an incoming STKL.
-     */
-    private void handleSTKL(Client client, ByteBuffer data) {
-        StackTraceElement[] trace;
-        int i, threadId, stackDepth;
-        @SuppressWarnings("unused")
-        int future;
-
-        future = data.getInt();
-        threadId = data.getInt();
-
-        Log.v("ddms", "STKL: " + threadId);
-
-        /* un-serialize the StackTraceElement[] */
-        stackDepth = data.getInt();
-        trace = new StackTraceElement[stackDepth];
-        for (i = 0; i < stackDepth; i++) {
-            String className, methodName, fileName;
-            int len, lineNumber;
-
-            len = data.getInt();
-            className = getString(data, len);
-            len = data.getInt();
-            methodName = getString(data, len);
-            len = data.getInt();
-            if (len == 0) {
-                fileName = null;
-            } else {
-                fileName = getString(data, len);
-            }
-            lineNumber = data.getInt();
-
-            trace[i] = new StackTraceElement(className, methodName, fileName,
-                        lineNumber);
-        }
-
-        ThreadInfo threadInfo = client.getClientData().getThread(threadId);
-        if (threadInfo != null) {
-            threadInfo.setStackCall(trace);
-            client.update(Client.CHANGE_THREAD_STACKTRACE);
-        } else {
-            Log.d("STKL", String.format(
-                    "Got stackcall for thread %1$d, which does not exists (anymore?).", //$NON-NLS-1$
-                    threadId));
-        }
-    }
-
-
-    /**
-     * Send a THEN (THread notification ENable) request to the client.
-     */
-    public static void sendTHEN(Client client, boolean enable)
-        throws IOException {
-
-        ByteBuffer rawBuf = allocBuffer(1);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        if (enable)
-            buf.put((byte)1);
-        else
-            buf.put((byte)0);
-
-        finishChunkPacket(packet, CHUNK_THEN, buf.position());
-        Log.d("ddm-thread", "Sending " + name(CHUNK_THEN) + ": " + enable);
-        client.sendAndConsume(packet, mInst);
-    }
-
-
-    /**
-     * Send a STKL (STacK List) request to the client.  The VM will suspend
-     * the target thread, obtain its stack, and return it.  If the thread
-     * is no longer running, a failure result will be returned.
-     */
-    public static void sendSTKL(Client client, int threadId)
-        throws IOException {
-
-        if (false) {
-            Log.d("ddm-thread", "would send STKL " + threadId);
-            return;
-        }
-
-        ByteBuffer rawBuf = allocBuffer(4);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        buf.putInt(threadId);
-
-        finishChunkPacket(packet, CHUNK_STKL, buf.position());
-        Log.d("ddm-thread", "Sending " + name(CHUNK_STKL) + ": " + threadId);
-        client.sendAndConsume(packet, mInst);
-    }
-
-
-    /**
-     * This is called periodically from the UI thread.  To avoid locking
-     * the UI while we request the updates, we create a new thread.
-     *
-     */
-    static void requestThreadUpdate(final Client client) {
-        if (client.isDdmAware() && client.isThreadUpdateEnabled()) {
-            if (mThreadStatusReqRunning) {
-                Log.w("ddms", "Waiting for previous thread update req to finish");
-                return;
-            }
-
-            new Thread("Thread Status Req") {
-                @Override
-                public void run() {
-                    mThreadStatusReqRunning = true;
-                    try {
-                        sendTHST(client);
-                    } catch (IOException ioe) {
-                        Log.d("ddms", "Unable to request thread updates from "
-                                + client + ": " + ioe.getMessage());
-                    } finally {
-                        mThreadStatusReqRunning = false;
-                    }
-                }
-            }.start();
-        }
-    }
-
-    static void requestThreadStackCallRefresh(final Client client, final int threadId) {
-        if (client.isDdmAware() && client.isThreadUpdateEnabled()) {
-            if (mThreadStackTraceReqRunning ) {
-                Log.w("ddms", "Waiting for previous thread stack call req to finish");
-                return;
-            }
-
-            new Thread("Thread Status Req") {
-                @Override
-                public void run() {
-                    mThreadStackTraceReqRunning = true;
-                    try {
-                        sendSTKL(client, threadId);
-                    } catch (IOException ioe) {
-                        Log.d("ddms", "Unable to request thread stack call updates from "
-                                + client + ": " + ioe.getMessage());
-                    } finally {
-                        mThreadStackTraceReqRunning = false;
-                    }
-                }
-            }.start();
-        }
-
-    }
-
-    /*
-     * Send a THST request to the specified client.
-     */
-    private static void sendTHST(Client client) throws IOException {
-        ByteBuffer rawBuf = allocBuffer(0);
-        JdwpPacket packet = new JdwpPacket(rawBuf);
-        ByteBuffer buf = getChunkDataBuf(rawBuf);
-
-        // nothing much to say
-
-        finishChunkPacket(packet, CHUNK_THST, buf.position());
-        Log.d("ddm-thread", "Sending " + name(CHUNK_THST));
-        client.sendAndConsume(packet, mInst);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleWait.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleWait.java
deleted file mode 100644
index 934cbea..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleWait.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.ClientData.DebuggerStatus;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Handle the "wait" chunk (WAIT).  These are sent up when the client is
- * waiting for something, e.g. for a debugger to attach.
- */
-final class HandleWait extends ChunkHandler {
-
-    public static final int CHUNK_WAIT = ChunkHandler.type("WAIT");
-
-    private static final HandleWait mInst = new HandleWait();
-
-
-    private HandleWait() {}
-
-    /**
-     * Register for the packets we expect to get from the client.
-     */
-    public static void register(MonitorThread mt) {
-        mt.registerChunkHandler(CHUNK_WAIT, mInst);
-    }
-
-    /**
-     * Client is ready.
-     */
-    @Override
-    public void clientReady(Client client) throws IOException {}
-
-    /**
-     * Client went away.
-     */
-    @Override
-    public void clientDisconnected(Client client) {}
-
-    /**
-     * Chunk handler entry point.
-     */
-    @Override
-    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
-
-        Log.d("ddm-wait", "handling " + ChunkHandler.name(type));
-
-        if (type == CHUNK_WAIT) {
-            assert !isReply;
-            handleWAIT(client, data);
-        } else {
-            handleUnknownChunk(client, type, data, isReply, msgId);
-        }
-    }
-
-    /*
-     * Handle a reply to our WAIT message.
-     */
-    private static void handleWAIT(Client client, ByteBuffer data) {
-        byte reason;
-
-        reason = data.get();
-
-        Log.d("ddm-wait", "WAIT: reason=" + reason);
-
-
-        ClientData cd = client.getClientData();
-        synchronized (cd) {
-            cd.setDebuggerConnectionStatus(DebuggerStatus.WAITING);
-        }
-
-        client.update(Client.CHANGE_DEBUGGER_STATUS);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HeapSegment.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HeapSegment.java
deleted file mode 100644
index 6a62e60..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HeapSegment.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.text.ParseException;
-
-/**
- * Describes the types and locations of objects in a segment of a heap.
- */
-public final class HeapSegment implements Comparable<HeapSegment> {
-
-    /**
-     * Describes an object/region encoded in the HPSG data.
-     */
-    public static class HeapSegmentElement implements Comparable<HeapSegmentElement> {
-
-        /*
-         * Solidity values, which must match the values in
-         * the HPSG data.
-         */
-
-        /** The element describes a free block. */
-        public static int SOLIDITY_FREE = 0;
-
-        /** The element is strongly-reachable. */
-        public static int SOLIDITY_HARD = 1;
-
-        /** The element is softly-reachable. */
-        public static int SOLIDITY_SOFT = 2;
-
-        /** The element is weakly-reachable. */
-        public static int SOLIDITY_WEAK = 3;
-
-        /** The element is phantom-reachable. */
-        public static int SOLIDITY_PHANTOM = 4;
-
-        /** The element is pending finalization. */
-        public static int SOLIDITY_FINALIZABLE = 5;
-
-        /** The element is not reachable, and is about to be swept/freed. */
-        public static int SOLIDITY_SWEEP = 6;
-
-        /** The reachability of the object is unknown. */
-        public static int SOLIDITY_INVALID = -1;
-
-
-        /*
-         * Kind values, which must match the values in
-         * the HPSG data.
-         */
-
-        /** The element describes a data object. */
-        public static int KIND_OBJECT = 0;
-
-        /** The element describes a class object. */
-        public static int KIND_CLASS_OBJECT = 1;
-
-        /** The element describes an array of 1-byte elements. */
-        public static int KIND_ARRAY_1 = 2;
-
-        /** The element describes an array of 2-byte elements. */
-        public static int KIND_ARRAY_2 = 3;
-
-        /** The element describes an array of 4-byte elements. */
-        public static int KIND_ARRAY_4 = 4;
-
-        /** The element describes an array of 8-byte elements. */
-        public static int KIND_ARRAY_8 = 5;
-
-        /** The element describes an unknown type of object. */
-        public static int KIND_UNKNOWN = 6;
-
-        /** The element describes a native object. */
-        public static int KIND_NATIVE = 7;
-
-        /** The object kind is unknown or unspecified. */
-        public static int KIND_INVALID = -1;
-
-
-        /**
-         * A bit in the HPSG data that indicates that an element should
-         * be combined with the element that follows, typically because
-         * an element is too large to be described by a single element.
-         */
-        private static int PARTIAL_MASK = 1 << 7;
-
-
-        /**
-         * Describes the reachability/solidity of the element.  Must
-         * be set to one of the SOLIDITY_* values.
-         */
-        private int mSolidity;
-
-        /**
-         * Describes the type/kind of the element.  Must be set to one
-         * of the KIND_* values.
-         */
-        private int mKind;
-
-        /**
-         * Describes the length of the element, in bytes.
-         */
-        private int mLength;
-
-
-        /**
-         * Creates an uninitialized element.
-         */
-        public HeapSegmentElement() {
-            setSolidity(SOLIDITY_INVALID);
-            setKind(KIND_INVALID);
-            setLength(-1);
-        }
-
-        /**
-         * Create an element describing the entry at the current
-         * position of hpsgData.
-         *
-         * @param hs The heap segment to pull the entry from.
-         * @throws BufferUnderflowException if there is not a whole entry
-         *                                  following the current position
-         *                                  of hpsgData.
-         * @throws ParseException           if the provided data is malformed.
-         */
-        public HeapSegmentElement(HeapSegment hs)
-                throws BufferUnderflowException, ParseException {
-            set(hs);
-        }
-
-        /**
-         * Replace the element with the entry at the current position of
-         * hpsgData.
-         *
-         * @param hs The heap segment to pull the entry from.
-         * @return this object.
-         * @throws BufferUnderflowException if there is not a whole entry
-         *                                  following the current position of
-         *                                  hpsgData.
-         * @throws ParseException           if the provided data is malformed.
-         */
-        public HeapSegmentElement set(HeapSegment hs)
-                throws BufferUnderflowException, ParseException {
-
-            /* TODO: Maybe keep track of the virtual address of each element
-             *       so that they can be examined independently.
-             */
-            ByteBuffer data = hs.mUsageData;
-            int eState = (int)data.get() & 0x000000ff;
-            int eLen = ((int)data.get() & 0x000000ff) + 1;
-
-            while ((eState & PARTIAL_MASK) != 0) {
-
-                /* If the partial bit was set, the next byte should describe
-                 * the same object as the current one.
-                 */
-                int nextState = (int)data.get() & 0x000000ff;
-                if ((nextState & ~PARTIAL_MASK) != (eState & ~PARTIAL_MASK)) {
-                    throw new ParseException("State mismatch", data.position());
-                }
-                eState = nextState;
-                eLen += ((int)data.get() & 0x000000ff) + 1;
-            }
-
-            setSolidity(eState & 0x7);
-            setKind((eState >> 3) & 0x7);
-            setLength(eLen * hs.mAllocationUnitSize);
-
-            return this;
-        }
-
-        public int getSolidity() {
-            return mSolidity;
-        }
-
-        public void setSolidity(int solidity) {
-            this.mSolidity = solidity;
-        }
-
-        public int getKind() {
-            return mKind;
-        }
-
-        public void setKind(int kind) {
-            this.mKind = kind;
-        }
-
-        public int getLength() {
-            return mLength;
-        }
-
-        public void setLength(int length) {
-            this.mLength = length;
-        }
-
-        public int compareTo(HeapSegmentElement other) {
-            if (mLength != other.mLength) {
-                return mLength < other.mLength ? -1 : 1;
-            }
-            return 0;
-        }
-    }
-
-    //* The ID of the heap that this segment belongs to.
-    protected int mHeapId;
-
-    //* The size of an allocation unit, in bytes. (e.g., 8 bytes)
-    protected int mAllocationUnitSize;
-
-    //* The virtual address of the start of this segment.
-    protected long mStartAddress;
-
-    //* The offset of this pices from mStartAddress, in bytes.
-    protected int mOffset;
-
-    //* The number of allocation units described in this segment.
-    protected int mAllocationUnitCount;
-
-    //* The raw data that describes the contents of this segment.
-    protected ByteBuffer mUsageData;
-
-    //* mStartAddress is set to this value when the segment becomes invalid.
-    private final static long INVALID_START_ADDRESS = -1;
-
-    /**
-     * Create a new HeapSegment based on the raw contents
-     * of an HPSG chunk.
-     *
-     * @param hpsgData The raw data from an HPSG chunk.
-     * @throws BufferUnderflowException if hpsgData is too small
-     *                                  to hold the HPSG chunk header data.
-     */
-    public HeapSegment(ByteBuffer hpsgData) throws BufferUnderflowException {
-        /* Read the HPSG chunk header.
-         * These get*() calls may throw a BufferUnderflowException
-         * if the underlying data isn't big enough.
-         */
-        hpsgData.order(ByteOrder.BIG_ENDIAN);
-        mHeapId = hpsgData.getInt();
-        mAllocationUnitSize = (int) hpsgData.get();
-        mStartAddress = (long) hpsgData.getInt() & 0x00000000ffffffffL;
-        mOffset = hpsgData.getInt();
-        mAllocationUnitCount = hpsgData.getInt();
-
-        // Hold onto the remainder of the data.
-        mUsageData = hpsgData.slice();
-        mUsageData.order(ByteOrder.BIG_ENDIAN);   // doesn't actually matter
-
-        // Validate the data.
-//xxx do it
-//xxx make sure the number of elements matches mAllocationUnitCount.
-//xxx make sure the last element doesn't have P set
-    }
-
-    /**
-     * See if this segment still contains data, and has not been
-     * appended to another segment.
-     *
-     * @return true if this segment has not been appended to
-     *         another segment.
-     */
-    public boolean isValid() {
-        return mStartAddress != INVALID_START_ADDRESS;
-    }
-
-    /**
-     * See if <code>other</code> comes immediately after this segment.
-     *
-     * @param other The HeapSegment to check.
-     * @return true if <code>other</code> comes immediately after this
-     *         segment.
-     */
-    public boolean canAppend(HeapSegment other) {
-        return isValid() && other.isValid() && mHeapId == other.mHeapId &&
-                mAllocationUnitSize == other.mAllocationUnitSize &&
-                getEndAddress() == other.getStartAddress();
-    }
-
-    /**
-     * Append the contents of <code>other</code> to this segment
-     * if it describes the segment immediately after this one.
-     *
-     * @param other The segment to append to this segment, if possible.
-     *              If appended, <code>other</code> will be invalid
-     *              when this method returns.
-     * @return true if <code>other</code> was successfully appended to
-     *         this segment.
-     */
-    public boolean append(HeapSegment other) {
-        if (canAppend(other)) {
-            /* Preserve the position.  The mark is not preserved,
-             * but we don't use it anyway.
-             */
-            int pos = mUsageData.position();
-
-            // Guarantee that we have enough room for the new data.
-            if (mUsageData.capacity() - mUsageData.limit() <
-                    other.mUsageData.limit()) {
-                /* Grow more than necessary in case another append()
-                 * is about to happen.
-                 */
-                int newSize = mUsageData.limit() + other.mUsageData.limit();
-                ByteBuffer newData = ByteBuffer.allocate(newSize * 2);
-
-                mUsageData.rewind();
-                newData.put(mUsageData);
-                mUsageData = newData;
-            }
-
-            // Copy the data from the other segment and restore the position.
-            other.mUsageData.rewind();
-            mUsageData.put(other.mUsageData);
-            mUsageData.position(pos);
-
-            // Fix this segment's header to cover the new data.
-            mAllocationUnitCount += other.mAllocationUnitCount;
-
-            // Mark the other segment as invalid.
-            other.mStartAddress = INVALID_START_ADDRESS;
-            other.mUsageData = null;
-
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public long getStartAddress() {
-        return mStartAddress + mOffset;
-    }
-
-    public int getLength() {
-        return mAllocationUnitSize * mAllocationUnitCount;
-    }
-
-    public long getEndAddress() {
-        return getStartAddress() + getLength();
-    }
-
-    public void rewindElements() {
-        if (mUsageData != null) {
-            mUsageData.rewind();
-        }
-    }
-
-    public HeapSegmentElement getNextElement(HeapSegmentElement reuse) {
-        try {
-            if (reuse != null) {
-                return reuse.set(this);
-            } else {
-                return new HeapSegmentElement(this);
-            }
-        } catch (BufferUnderflowException ex) {
-            /* Normal "end of buffer" situation.
-             */
-        } catch (ParseException ex) {
-            /* Malformed data.
-             */
-//TODO: we should catch this in the constructor
-        }
-        return null;
-    }
-
-    /*
-     * Method overrides for Comparable
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof HeapSegment) {
-            return compareTo((HeapSegment) o) == 0;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mHeapId * 31 +
-                mAllocationUnitSize * 31 +
-                (int) mStartAddress * 31 +
-                mOffset * 31 +
-                mAllocationUnitCount * 31 +
-                mUsageData.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder str = new StringBuilder();
-
-        str.append("HeapSegment { heap ").append(mHeapId)
-                .append(", start 0x")
-                .append(Integer.toHexString((int) getStartAddress()))
-                .append(", length ").append(getLength())
-                .append(" }");
-
-        return str.toString();
-    }
-
-    public int compareTo(HeapSegment other) {
-        if (mHeapId != other.mHeapId) {
-            return mHeapId < other.mHeapId ? -1 : 1;
-        }
-        if (getStartAddress() != other.getStartAddress()) {
-            return getStartAddress() < other.getStartAddress() ? -1 : 1;
-        }
-
-        /* If two segments have the same start address, the rest of
-         * the fields should be equal.  Go through the motions, though.
-         * Note that we re-check the components of getStartAddress()
-         * (mStartAddress and mOffset) to make sure that all fields in
-         * an equal segment are equal.
-         */
-
-        if (mAllocationUnitSize != other.mAllocationUnitSize) {
-            return mAllocationUnitSize < other.mAllocationUnitSize ? -1 : 1;
-        }
-        if (mStartAddress != other.mStartAddress) {
-            return mStartAddress < other.mStartAddress ? -1 : 1;
-        }
-        if (mOffset != other.mOffset) {
-            return mOffset < other.mOffset ? -1 : 1;
-        }
-        if (mAllocationUnitCount != other.mAllocationUnitCount) {
-            return mAllocationUnitCount < other.mAllocationUnitCount ? -1 : 1;
-        }
-        if (mUsageData != other.mUsageData) {
-            return mUsageData.compareTo(other.mUsageData);
-        }
-        return 0;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
deleted file mode 100755
index 8096abd..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.log.LogReceiver;
-
-import java.io.IOException;
-import java.util.Map;
-
-
-/**
- *  A Device. It can be a physical device or an emulator.
- */
-public interface IDevice {
-
-    public final static String PROP_BUILD_VERSION = "ro.build.version.release";
-    public final static String PROP_BUILD_API_LEVEL = "ro.build.version.sdk";
-    public final static String PROP_BUILD_CODENAME = "ro.build.version.codename";
-
-    public final static String PROP_DEBUGGABLE = "ro.debuggable";
-
-    /** Serial number of the first connected emulator. */
-    public final static String FIRST_EMULATOR_SN = "emulator-5554"; //$NON-NLS-1$
-    /** Device change bit mask: {@link DeviceState} change. */
-    public static final int CHANGE_STATE = 0x0001;
-    /** Device change bit mask: {@link Client} list change. */
-    public static final int CHANGE_CLIENT_LIST = 0x0002;
-    /** Device change bit mask: build info change. */
-    public static final int CHANGE_BUILD_INFO = 0x0004;
-
-    /** @deprecated Use {@link #PROP_BUILD_API_LEVEL}. */
-    public final static String PROP_BUILD_VERSION_NUMBER = PROP_BUILD_API_LEVEL;
-
-    /**
-     * The state of a device.
-     */
-    public static enum DeviceState {
-        BOOTLOADER("bootloader"), //$NON-NLS-1$
-        OFFLINE("offline"), //$NON-NLS-1$
-        ONLINE("device"); //$NON-NLS-1$
-
-        private String mState;
-
-        DeviceState(String state) {
-            mState = state;
-        }
-
-        /**
-         * Returns a {@link DeviceState} from the string returned by <code>adb devices</code>.
-         * @param state the device state.
-         * @return a {@link DeviceState} object or <code>null</code> if the state is unknown.
-         */
-        public static DeviceState getState(String state) {
-            for (DeviceState deviceState : values()) {
-                if (deviceState.mState.equals(state)) {
-                    return deviceState;
-                }
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Returns the serial number of the device.
-     */
-    public String getSerialNumber();
-
-    /**
-     * Returns the name of the AVD the emulator is running.
-     * <p/>This is only valid if {@link #isEmulator()} returns true.
-     * <p/>If the emulator is not running any AVD (for instance it's running from an Android source
-     * tree build), this method will return "<code>&lt;build&gt;</code>".
-     * @return the name of the AVD or <code>null</code> if there isn't any.
-     */
-    public String getAvdName();
-
-    /**
-     * Returns the state of the device.
-     */
-    public DeviceState getState();
-
-    /**
-     * Returns the device properties. It contains the whole output of 'getprop'
-     */
-    public Map<String, String> getProperties();
-
-    /**
-     * Returns the number of property for this device.
-     */
-    public int getPropertyCount();
-
-    /**
-     * Returns a property value.
-     * @param name the name of the value to return.
-     * @return the value or <code>null</code> if the property does not exist.
-     */
-    public String getProperty(String name);
-
-    /**
-     * Returns if the device is ready.
-     * @return <code>true</code> if {@link #getState()} returns {@link DeviceState#ONLINE}.
-     */
-    public boolean isOnline();
-
-    /**
-     * Returns <code>true</code> if the device is an emulator.
-     */
-    public boolean isEmulator();
-
-    /**
-     * Returns if the device is offline.
-     * @return <code>true</code> if {@link #getState()} returns {@link DeviceState#OFFLINE}.
-     */
-    public boolean isOffline();
-
-    /**
-     * Returns if the device is in bootloader mode.
-     * @return <code>true</code> if {@link #getState()} returns {@link DeviceState#BOOTLOADER}.
-     */
-    public boolean isBootLoader();
-
-    /**
-     * Returns whether the {@link Device} has {@link Client}s.
-     */
-    public boolean hasClients();
-
-    /**
-     * Returns the array of clients.
-     */
-    public Client[] getClients();
-
-    /**
-     * Returns a {@link Client} by its application name.
-     * @param applicationName the name of the application
-     * @return the <code>Client</code> object or <code>null</code> if no match was found.
-     */
-    public Client getClient(String applicationName);
-
-    /**
-     * Returns a {@link SyncService} object to push / pull files to and from the device.
-     * @return <code>null</code> if the SyncService couldn't be created. This can happen if adb
-     * refuse to open the connection because the {@link IDevice} is invalid (or got disconnected).
-     * @throws IOException if the connection with adb failed.
-     */
-    public SyncService getSyncService() throws IOException;
-
-    /**
-     * Returns a {@link FileListingService} for this device.
-     */
-    public FileListingService getFileListingService();
-
-    /**
-     * Takes a screen shot of the device and returns it as a {@link RawImage}.
-     * @return the screenshot as a <code>RawImage</code> or <code>null</code> if
-     * something went wrong.
-     * @throws IOException
-     */
-    public RawImage getScreenshot() throws IOException;
-
-    /**
-     * Executes a shell command on the device, and sends the result to a receiver.
-     * @param command The command to execute
-     * @param receiver The receiver object getting the result from the command.
-     * @throws IOException
-     */
-    public void executeShellCommand(String command,
-            IShellOutputReceiver receiver) throws IOException;
-
-    /**
-     * Runs the event log service and outputs the event log to the {@link LogReceiver}.
-     * @param receiver the receiver to receive the event log entries.
-     * @throws IOException
-     */
-    public void runEventLogService(LogReceiver receiver) throws IOException;
-
-    /**
-     * Runs the log service for the given log and outputs the log to the {@link LogReceiver}.
-     * @param logname the logname of the log to read from.
-     * @param receiver the receiver to receive the event log entries.
-     * @throws IOException
-     */
-    public void runLogService(String logname, LogReceiver receiver) throws IOException;
-
-    /**
-     * Creates a port forwarding between a local and a remote port.
-     * @param localPort the local port to forward
-     * @param remotePort the remote port.
-     * @return <code>true</code> if success.
-     */
-    public boolean createForward(int localPort, int remotePort);
-
-    /**
-     * Removes a port forwarding between a local and a remote port.
-     * @param localPort the local port to forward
-     * @param remotePort the remote port.
-     * @return <code>true</code> if success.
-     */
-    public boolean removeForward(int localPort, int remotePort);
-
-    /**
-     * Returns the name of the client by pid or <code>null</code> if pid is unknown
-     * @param pid the pid of the client.
-     */
-    public String getClientName(int pid);
-
-    /**
-     * Installs an Android application on device.
-     * This is a helper method that combines the syncPackageToDevice, installRemotePackage,
-     * and removePackage steps
-     * @param packageFilePath the absolute file system path to file on local host to install
-     * @param reinstall set to <code>true</code> if re-install of app should be performed
-     * @return a {@link String} with an error code, or <code>null</code> if success.
-     * @throws IOException
-     */
-    public String installPackage(String packageFilePath, boolean reinstall)  throws IOException;
-
-    /**
-     * Pushes a file to device
-     * @param localFilePath the absolute path to file on local host
-     * @return {@link String} destination path on device for file
-     * @throws IOException if fatal error occurred when pushing file
-     */
-    public String syncPackageToDevice(String localFilePath)
-            throws IOException;
-
-    /**
-     * Installs the application package that was pushed to a temporary location on the device.
-     * @param remoteFilePath absolute file path to package file on device
-     * @param reinstall set to <code>true</code> if re-install of app should be performed
-     * @throws InstallException if installation failed
-     */
-    public String installRemotePackage(String remoteFilePath, boolean reinstall)
-            throws IOException;
-
-    /**
-     * Remove a file from device
-     * @param remoteFilePath path on device of file to remove
-     * @throws IOException if file removal failed
-     */
-    public void removeRemotePackage(String remoteFilePath) throws IOException;
-
-    /**
-     * Uninstall an package from the device.
-     * @param packageName the Android application package name to uninstall
-     * @return a {@link String} with an error code, or <code>null</code> if success.
-     * @throws IOException
-     */
-    public String uninstallPackage(String packageName) throws IOException;
-
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IShellOutputReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IShellOutputReceiver.java
deleted file mode 100644
index fb671bb..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IShellOutputReceiver.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-/**
- * Classes which implement this interface provide methods that deal with out from a remote shell
- * command on a device/emulator.
- */
-public interface IShellOutputReceiver {
-    /**
-     * Called every time some new data is available.
-     * @param data The new data.
-     * @param offset The offset at which the new data starts.
-     * @param length The length of the new data.
-     */
-    public void addOutput(byte[] data, int offset, int length);
-
-    /**
-     * Called at the end of the process execution (unless the process was
-     * canceled). This allows the receiver to terminate and flush whatever
-     * data was not yet processed.
-     */
-    public void flush();
-
-    /**
-     * Cancel method to stop the execution of the remote shell command.
-     * @return true to cancel the execution of the command.
-     */
-    public boolean isCancelled();
-};
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IStackTraceInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IStackTraceInfo.java
deleted file mode 100644
index 3b9d730..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IStackTraceInfo.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-/**
- * Classes which implement this interface provide a method that returns a stack trace.
- */
-public interface IStackTraceInfo {
-
-    /**
-     * Returns the stack trace. This can be <code>null</code>.
-     */
-    public StackTraceElement[] getStackTrace();
-
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java
deleted file mode 100644
index 92bbb82..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/* //device/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.ddmlib;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.SocketChannel;
-
-/**
- * A JDWP packet, sitting at the start of a ByteBuffer somewhere.
- *
- * This allows us to wrap a "pointer" to the data with the results of
- * decoding the packet.
- *
- * None of the operations here are synchronized.  If multiple threads will
- * be accessing the same ByteBuffers, external sync will be required.
- *
- * Use the constructor to create an empty packet, or "findPacket()" to
- * wrap a JdwpPacket around existing data.
- */
-final class JdwpPacket {
-    // header len
-    public static final int JDWP_HEADER_LEN = 11;
-
-    // results from findHandshake
-    public static final int HANDSHAKE_GOOD = 1;
-    public static final int HANDSHAKE_NOTYET = 2;
-    public static final int HANDSHAKE_BAD = 3;
-
-    // our cmdSet/cmd
-    private static final int DDMS_CMD_SET = 0xc7;       // 'G' + 128
-    private static final int DDMS_CMD = 0x01;
-
-    // "flags" field
-    private static final int REPLY_PACKET = 0x80;
-
-    // this is sent and expected at the start of a JDWP connection
-    private static final byte[] mHandshake = {
-        'J', 'D', 'W', 'P', '-', 'H', 'a', 'n', 'd', 's', 'h', 'a', 'k', 'e'
-    };
-
-    public static final int HANDSHAKE_LEN = mHandshake.length;
-
-    private ByteBuffer mBuffer;
-    private int mLength, mId, mFlags, mCmdSet, mCmd, mErrCode;
-    private boolean mIsNew;
-
-    private static int mSerialId = 0x40000000;
-
-
-    /**
-     * Create a new, empty packet, in "buf".
-     */
-    JdwpPacket(ByteBuffer buf) {
-        mBuffer = buf;
-        mIsNew = true;
-    }
-
-    /**
-     * Finish a packet created with newPacket().
-     *
-     * This always creates a command packet, with the next serial number
-     * in sequence.
-     *
-     * We have to take "payloadLength" as an argument because we can't
-     * see the position in the "slice" returned by getPayload().  We could
-     * fish it out of the chunk header, but it's legal for there to be
-     * more than one chunk in a JDWP packet.
-     *
-     * On exit, "position" points to the end of the data.
-     */
-    void finishPacket(int payloadLength) {
-        assert mIsNew;
-
-        ByteOrder oldOrder = mBuffer.order();
-        mBuffer.order(ChunkHandler.CHUNK_ORDER);
-
-        mLength = JDWP_HEADER_LEN + payloadLength;
-        mId = getNextSerial();
-        mFlags = 0;
-        mCmdSet = DDMS_CMD_SET;
-        mCmd = DDMS_CMD;
-
-        mBuffer.putInt(0x00, mLength);
-        mBuffer.putInt(0x04, mId);
-        mBuffer.put(0x08, (byte) mFlags);
-        mBuffer.put(0x09, (byte) mCmdSet);
-        mBuffer.put(0x0a, (byte) mCmd);
-
-        mBuffer.order(oldOrder);
-        mBuffer.position(mLength);
-    }
-
-    /**
-     * Get the next serial number.  This creates a unique serial number
-     * across all connections, not just for the current connection.  This
-     * is a useful property when debugging, but isn't necessary.
-     *
-     * We can't synchronize on an int, so we use a sync method.
-     */
-    private static synchronized int getNextSerial() {
-        return mSerialId++;
-    }
-
-    /**
-     * Return a slice of the byte buffer, positioned past the JDWP header
-     * to the start of the chunk header.  The buffer's limit will be set
-     * to the size of the payload if the size is known; if this is a
-     * packet under construction the limit will be set to the end of the
-     * buffer.
-     *
-     * Doesn't examine the packet at all -- works on empty buffers.
-     */
-    ByteBuffer getPayload() {
-        ByteBuffer buf;
-        int oldPosn = mBuffer.position();
-
-        mBuffer.position(JDWP_HEADER_LEN);
-        buf = mBuffer.slice();     // goes from position to limit
-        mBuffer.position(oldPosn);
-
-        if (mLength > 0)
-            buf.limit(mLength - JDWP_HEADER_LEN);
-        else
-            assert mIsNew;
-        buf.order(ChunkHandler.CHUNK_ORDER);
-        return buf;
-    }
-
-    /**
-     * Returns "true" if this JDWP packet has a JDWP command type.
-     *
-     * This never returns "true" for reply packets.
-     */
-    boolean isDdmPacket() {
-        return (mFlags & REPLY_PACKET) == 0 &&
-               mCmdSet == DDMS_CMD_SET &&
-               mCmd == DDMS_CMD;
-    }
-
-    /**
-     * Returns "true" if this JDWP packet is tagged as a reply.
-     */
-    boolean isReply() {
-        return (mFlags & REPLY_PACKET) != 0;
-    }
-
-    /**
-     * Returns "true" if this JDWP packet is a reply with a nonzero
-     * error code.
-     */
-    boolean isError() {
-        return isReply() && mErrCode != 0;
-    }
-
-    /**
-     * Returns "true" if this JDWP packet has no data.
-     */
-    boolean isEmpty() {
-        return (mLength == JDWP_HEADER_LEN);
-    }
-
-    /**
-     * Return the packet's ID.  For a reply packet, this allows us to
-     * match the reply with the original request.
-     */
-    int getId() {
-        return mId;
-    }
-
-    /**
-     * Return the length of a packet.  This includes the header, so an
-     * empty packet is 11 bytes long.
-     */
-    int getLength() {
-        return mLength;
-    }
-
-    /**
-     * Write our packet to "chan".  Consumes the packet as part of the
-     * write.
-     *
-     * The JDWP packet starts at offset 0 and ends at mBuffer.position().
-     */
-    void writeAndConsume(SocketChannel chan) throws IOException {
-        int oldLimit;
-
-        //Log.i("ddms", "writeAndConsume: pos=" + mBuffer.position()
-        //    + ", limit=" + mBuffer.limit());
-
-        assert mLength > 0;
-
-        mBuffer.flip();         // limit<-posn, posn<-0
-        oldLimit = mBuffer.limit();
-        mBuffer.limit(mLength);
-        while (mBuffer.position() != mBuffer.limit()) {
-            chan.write(mBuffer);
-        }
-        // position should now be at end of packet
-        assert mBuffer.position() == mLength;
-
-        mBuffer.limit(oldLimit);
-        mBuffer.compact();      // shift posn...limit, posn<-pending data
-
-        //Log.i("ddms", "               : pos=" + mBuffer.position()
-        //    + ", limit=" + mBuffer.limit());
-    }
-
-    /**
-     * "Move" the packet data out of the buffer we're sitting on and into
-     * buf at the current position.
-     */
-    void movePacket(ByteBuffer buf) {
-        Log.v("ddms", "moving " + mLength + " bytes");
-        int oldPosn = mBuffer.position();
-
-        mBuffer.position(0);
-        mBuffer.limit(mLength);
-        buf.put(mBuffer);
-        mBuffer.position(mLength);
-        mBuffer.limit(oldPosn);
-        mBuffer.compact();      // shift posn...limit, posn<-pending data
-    }
-
-    /**
-     * Consume the JDWP packet.
-     *
-     * On entry and exit, "position" is the #of bytes in the buffer.
-     */
-    void consume()
-    {
-        //Log.d("ddms", "consuming " + mLength + " bytes");
-        //Log.d("ddms", "  posn=" + mBuffer.position()
-        //    + ", limit=" + mBuffer.limit());
-
-        /*
-         * The "flip" call sets "limit" equal to the position (usually the
-         * end of data) and "position" equal to zero.
-         *
-         * compact() copies everything from "position" and "limit" to the
-         * start of the buffer, sets "position" to the end of data, and
-         * sets "limit" to the capacity.
-         *
-         * On entry, "position" is set to the amount of data in the buffer
-         * and "limit" is set to the capacity.  We want to call flip()
-         * so that position..limit spans our data, advance "position" past
-         * the current packet, then compact.
-         */
-        mBuffer.flip();         // limit<-posn, posn<-0
-        mBuffer.position(mLength);
-        mBuffer.compact();      // shift posn...limit, posn<-pending data
-        mLength = 0;
-        //Log.d("ddms", "  after compact, posn=" + mBuffer.position()
-        //    + ", limit=" + mBuffer.limit());
-    }
-
-    /**
-     * Find the JDWP packet at the start of "buf".  The start is known,
-     * but the length has to be parsed out.
-     *
-     * On entry, the packet data in "buf" must start at offset 0 and end
-     * at "position".  "limit" should be set to the buffer capacity.  This
-     * method does not alter "buf"s attributes.
-     *
-     * Returns a new JdwpPacket if a full one is found in the buffer.  If
-     * not, returns null.  Throws an exception if the data doesn't look like
-     * a valid JDWP packet.
-     */
-    static JdwpPacket findPacket(ByteBuffer buf) {
-        int count = buf.position();
-        int length, id, flags, cmdSet, cmd;
-
-        if (count < JDWP_HEADER_LEN)
-            return null;
-
-        ByteOrder oldOrder = buf.order();
-        buf.order(ChunkHandler.CHUNK_ORDER);
-
-        length = buf.getInt(0x00);
-        id = buf.getInt(0x04);
-        flags = buf.get(0x08) & 0xff;
-        cmdSet = buf.get(0x09) & 0xff;
-        cmd = buf.get(0x0a) & 0xff;
-
-        buf.order(oldOrder);
-
-        if (length < JDWP_HEADER_LEN)
-            throw new BadPacketException();
-        if (count < length)
-            return null;
-
-        JdwpPacket pkt = new JdwpPacket(buf);
-        //pkt.mBuffer = buf;
-        pkt.mLength = length;
-        pkt.mId = id;
-        pkt.mFlags = flags;
-
-        if ((flags & REPLY_PACKET) == 0) {
-            pkt.mCmdSet = cmdSet;
-            pkt.mCmd = cmd;
-            pkt.mErrCode = -1;
-        } else {
-            pkt.mCmdSet = -1;
-            pkt.mCmd = -1;
-            pkt.mErrCode = cmdSet | (cmd << 8);
-        }
-
-        return pkt;
-    }
-
-    /**
-     * Like findPacket(), but when we're expecting the JDWP handshake.
-     *
-     * Returns one of:
-     *   HANDSHAKE_GOOD   - found handshake, looks good
-     *   HANDSHAKE_BAD    - found enough data, but it's wrong
-     *   HANDSHAKE_NOTYET - not enough data has been read yet
-     */
-    static int findHandshake(ByteBuffer buf) {
-        int count = buf.position();
-        int i;
-
-        if (count < mHandshake.length)
-            return HANDSHAKE_NOTYET;
-
-        for (i = mHandshake.length -1; i >= 0; --i) {
-            if (buf.get(i) != mHandshake[i])
-                return HANDSHAKE_BAD;
-        }
-
-        return HANDSHAKE_GOOD;
-    }
-
-    /**
-     * Remove the handshake string from the buffer.
-     *
-     * On entry and exit, "position" is the #of bytes in the buffer.
-     */
-    static void consumeHandshake(ByteBuffer buf) {
-        // in theory, nothing else can have arrived, so this is overkill
-        buf.flip();         // limit<-posn, posn<-0
-        buf.position(mHandshake.length);
-        buf.compact();      // shift posn...limit, posn<-pending data
-    }
-
-    /**
-     * Copy the handshake string into the output buffer.
-     *
-     * On exit, "buf"s position will be advanced.
-     */
-    static void putHandshake(ByteBuffer buf) {
-        buf.put(mHandshake);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Log.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Log.java
deleted file mode 100644
index ce95b04..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Log.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-/**
- * Log class that mirrors the API in main Android sources.
- * <p/>Default behavior outputs the log to {@link System#out}. Use
- * {@link #setLogOutput(com.android.ddmlib.Log.ILogOutput)} to redirect the log somewhere else.
- */
-public final class Log {
-
-    /**
-     * Log Level enum.
-     */
-    public enum LogLevel {
-        VERBOSE(2, "verbose", 'V'), //$NON-NLS-1$
-        DEBUG(3, "debug", 'D'), //$NON-NLS-1$
-        INFO(4, "info", 'I'), //$NON-NLS-1$
-        WARN(5, "warn", 'W'), //$NON-NLS-1$
-        ERROR(6, "error", 'E'), //$NON-NLS-1$
-        ASSERT(7, "assert", 'A'); //$NON-NLS-1$
-
-        private int mPriorityLevel;
-        private String mStringValue;
-        private char mPriorityLetter;
-
-        LogLevel(int intPriority, String stringValue, char priorityChar) {
-            mPriorityLevel = intPriority;
-            mStringValue = stringValue;
-            mPriorityLetter = priorityChar;
-        }
-
-        public static LogLevel getByString(String value) {
-            for (LogLevel mode : values()) {
-                if (mode.mStringValue.equals(value)) {
-                    return mode;
-                }
-            }
-
-            return null;
-        }
-        
-        /**
-         * Returns the {@link LogLevel} enum matching the specified letter.
-         * @param letter the letter matching a <code>LogLevel</code> enum
-         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
-         */
-        public static LogLevel getByLetter(char letter) {
-            for (LogLevel mode : values()) {
-                if (mode.mPriorityLetter == letter) {
-                    return mode;
-                }
-            }
-
-            return null;
-        }
-
-        /**
-         * Returns the {@link LogLevel} enum matching the specified letter.
-         * <p/>
-         * The letter is passed as a {@link String} argument, but only the first character
-         * is used. 
-         * @param letter the letter matching a <code>LogLevel</code> enum
-         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
-         */
-        public static LogLevel getByLetterString(String letter) {
-            if (letter.length() > 0) {
-                return getByLetter(letter.charAt(0));
-            }
-
-            return null;
-        }
-
-        /**
-         * Returns the letter identifying the priority of the {@link LogLevel}.
-         */
-        public char getPriorityLetter() {
-            return mPriorityLetter;
-        }
-
-        /**
-         * Returns the numerical value of the priority.
-         */
-        public int getPriority() {
-            return mPriorityLevel;
-        }
-
-        /**
-         * Returns a non translated string representing the LogLevel.
-         */
-        public String getStringValue() {
-            return mStringValue;
-        }
-    }
-    
-    /**
-     * Classes which implement this interface provides methods that deal with outputting log
-     * messages.
-     */
-    public interface ILogOutput {
-        /**
-         * Sent when a log message needs to be printed.
-         * @param logLevel The {@link LogLevel} enum representing the priority of the message.
-         * @param tag The tag associated with the message.
-         * @param message The message to display.
-         */
-        public void printLog(LogLevel logLevel, String tag, String message);
-
-        /**
-         * Sent when a log message needs to be printed, and, if possible, displayed to the user
-         * in a dialog box.
-         * @param logLevel The {@link LogLevel} enum representing the priority of the message.
-         * @param tag The tag associated with the message.
-         * @param message The message to display.
-         */
-        public void printAndPromptLog(LogLevel logLevel, String tag, String message);
-    }
-
-    private static LogLevel mLevel = DdmPreferences.getLogLevel();
-
-    private static ILogOutput sLogOutput;
-
-    private static final char[] mSpaceLine = new char[72];
-    private static final char[] mHexDigit = new char[]
-        { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
-    static {
-        /* prep for hex dump */
-        int i = mSpaceLine.length-1;
-        while (i >= 0)
-            mSpaceLine[i--] = ' ';
-        mSpaceLine[0] = mSpaceLine[1] = mSpaceLine[2] = mSpaceLine[3] = '0';
-        mSpaceLine[4] = '-';
-    }
-
-    static final class Config {
-        static final boolean LOGV = true;
-        static final boolean LOGD = true;
-    };
-
-    private Log() {}
-
-    /**
-     * Outputs a {@link LogLevel#VERBOSE} level message.
-     * @param tag The tag associated with the message.
-     * @param message The message to output.
-     */
-    public static void v(String tag, String message) {
-        println(LogLevel.VERBOSE, tag, message);
-    }
-
-    /**
-     * Outputs a {@link LogLevel#DEBUG} level message.
-     * @param tag The tag associated with the message.
-     * @param message The message to output.
-     */
-    public static void d(String tag, String message) {
-        println(LogLevel.DEBUG, tag, message);
-    }
-
-    /**
-     * Outputs a {@link LogLevel#INFO} level message.
-     * @param tag The tag associated with the message.
-     * @param message The message to output.
-     */
-    public static void i(String tag, String message) {
-        println(LogLevel.INFO, tag, message);
-    }
-
-    /**
-     * Outputs a {@link LogLevel#WARN} level message.
-     * @param tag The tag associated with the message.
-     * @param message The message to output.
-     */
-    public static void w(String tag, String message) {
-        println(LogLevel.WARN, tag, message);
-    }
-
-    /**
-     * Outputs a {@link LogLevel#ERROR} level message.
-     * @param tag The tag associated with the message.
-     * @param message The message to output.
-     */
-    public static void e(String tag, String message) {
-        println(LogLevel.ERROR, tag, message);
-    }
-
-    /**
-     * Outputs a log message and attempts to display it in a dialog.
-     * @param tag The tag associated with the message.
-     * @param message The message to output.
-     */
-    public static void logAndDisplay(LogLevel logLevel, String tag, String message) {
-        if (sLogOutput != null) {
-            sLogOutput.printAndPromptLog(logLevel, tag, message);
-        } else {
-            println(logLevel, tag, message);
-        }
-    }
-
-    /**
-     * Outputs a {@link LogLevel#ERROR} level {@link Throwable} information.
-     * @param tag The tag associated with the message.
-     * @param throwable The {@link Throwable} to output.
-     */
-    public static void e(String tag, Throwable throwable) {
-        if (throwable != null) {
-            StringWriter sw = new StringWriter();
-            PrintWriter pw = new PrintWriter(sw);
-
-            throwable.printStackTrace(pw);
-            println(LogLevel.ERROR, tag, throwable.getMessage() + '\n' + sw.toString());
-        }
-    }
-
-    static void setLevel(LogLevel logLevel) {
-        mLevel = logLevel;
-    }
-
-    /**
-     * Sets the {@link ILogOutput} to use to print the logs. If not set, {@link System#out}
-     * will be used.
-     * @param logOutput The {@link ILogOutput} to use to print the log.
-     */
-    public static void setLogOutput(ILogOutput logOutput) {
-        sLogOutput = logOutput;
-    }
-
-    /**
-     * Show hex dump.
-     * <p/>
-     * Local addition.  Output looks like:
-     * 1230- 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
-     * <p/>
-     * Uses no string concatenation; creates one String object per line.
-     */
-    static void hexDump(String tag, LogLevel level, byte[] data, int offset, int length) {
-
-        int kHexOffset = 6;
-        int kAscOffset = 55;
-        char[] line = new char[mSpaceLine.length];
-        int addr, baseAddr, count;
-        int i, ch;
-        boolean needErase = true;
-
-        //Log.w(tag, "HEX DUMP: off=" + offset + ", length=" + length);
-
-        baseAddr = 0;
-        while (length != 0) {
-            if (length > 16) {
-                // full line
-                count = 16;
-            } else {
-                // partial line; re-copy blanks to clear end
-                count = length;
-                needErase = true;
-            }
-
-            if (needErase) {
-                System.arraycopy(mSpaceLine, 0, line, 0, mSpaceLine.length);
-                needErase = false;
-            }
-
-            // output the address (currently limited to 4 hex digits)
-            addr = baseAddr;
-            addr &= 0xffff;
-            ch = 3;
-            while (addr != 0) {
-                line[ch] = mHexDigit[addr & 0x0f];
-                ch--;
-                addr >>>= 4;
-            }
-
-            // output hex digits and ASCII chars
-            ch = kHexOffset;
-            for (i = 0; i < count; i++) {
-                byte val = data[offset + i];
-
-                line[ch++] = mHexDigit[(val >>> 4) & 0x0f];
-                line[ch++] = mHexDigit[val & 0x0f];
-                ch++;
-
-                if (val >= 0x20 && val < 0x7f)
-                    line[kAscOffset + i] = (char) val;
-                else
-                    line[kAscOffset + i] = '.';
-            }
-
-            println(level, tag, new String(line));
-
-            // advance to next chunk of data
-            length -= count;
-            offset += count;
-            baseAddr += count;
-        }
-
-    }
-
-    /**
-     * Dump the entire contents of a byte array with DEBUG priority.
-     */
-    static void hexDump(byte[] data) {
-        hexDump("ddms", LogLevel.DEBUG, data, 0, data.length);
-    }
-
-    /* currently prints to stdout; could write to a log window */
-    private static void println(LogLevel logLevel, String tag, String message) {
-        if (logLevel.getPriority() >= mLevel.getPriority()) {
-            if (sLogOutput != null) {
-                sLogOutput.printLog(logLevel, tag, message);
-            } else {
-                printLog(logLevel, tag, message);
-            }
-        }
-    }
-    
-    /**
-     * Prints a log message.
-     * @param logLevel
-     * @param tag
-     * @param message
-     */
-    public static void printLog(LogLevel logLevel, String tag, String message) {
-        long msec;
-        
-        msec = System.currentTimeMillis();
-        String outMessage = String.format("%02d:%02d %c/%s: %s\n",
-                (msec / 60000) % 60, (msec / 1000) % 60,
-                logLevel.getPriorityLetter(), tag, message);
-        System.out.print(outMessage);
-    }
-
-}
-
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java
deleted file mode 100644
index a514945..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-
-import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
-import com.android.ddmlib.Log.LogLevel;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.channels.CancelledKeyException;
-import java.nio.channels.NotYetBoundException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * Monitor open connections.
- */
-final class MonitorThread extends Thread {
-
-    // For broadcasts to message handlers
-    //private static final int CLIENT_CONNECTED = 1;
-
-    private static final int CLIENT_READY = 2;
-
-    private static final int CLIENT_DISCONNECTED = 3;
-
-    private volatile boolean mQuit = false;
-
-    // List of clients we're paying attention to
-    private ArrayList<Client> mClientList;
-
-    // The almighty mux
-    private Selector mSelector;
-
-    // Map chunk types to handlers
-    private HashMap<Integer, ChunkHandler> mHandlerMap;
-
-    // port for "debug selected"
-    private ServerSocketChannel mDebugSelectedChan;
-
-    private int mNewDebugSelectedPort;
-
-    private int mDebugSelectedPort = -1;
-
-    /**
-     * "Selected" client setup to answer debugging connection to the mNewDebugSelectedPort port.
-     */
-    private Client mSelectedClient = null;
-
-    // singleton
-    private static MonitorThread mInstance;
-
-    /**
-     * Generic constructor.
-     */
-    private MonitorThread() {
-        super("Monitor");
-        mClientList = new ArrayList<Client>();
-        mHandlerMap = new HashMap<Integer, ChunkHandler>();
-
-        mNewDebugSelectedPort = DdmPreferences.getSelectedDebugPort();
-    }
-
-    /**
-     * Creates and return the singleton instance of the client monitor thread.
-     */
-    static MonitorThread createInstance() {
-        return mInstance = new MonitorThread();
-    }
-
-    /**
-     * Get singleton instance of the client monitor thread.
-     */
-    static MonitorThread getInstance() {
-        return mInstance;
-    }
-
-
-    /**
-     * Sets or changes the port number for "debug selected".
-     */
-    synchronized void setDebugSelectedPort(int port) throws IllegalStateException {
-        if (mInstance == null) {
-            return;
-        }
-
-        if (AndroidDebugBridge.getClientSupport() == false) {
-            return;
-        }
-
-        if (mDebugSelectedChan != null) {
-            Log.d("ddms", "Changing debug-selected port to " + port);
-            mNewDebugSelectedPort = port;
-            wakeup();
-        } else {
-            // we set mNewDebugSelectedPort instead of mDebugSelectedPort so that it's automatically
-            // opened on the first run loop.
-            mNewDebugSelectedPort = port;
-        }
-    }
-
-    /**
-     * Sets the client to accept debugger connection on the custom "Selected debug port".
-     * @param selectedClient the client. Can be null.
-     */
-    synchronized void setSelectedClient(Client selectedClient) {
-        if (mInstance == null) {
-            return;
-        }
-
-        if (mSelectedClient != selectedClient) {
-            Client oldClient = mSelectedClient;
-            mSelectedClient = selectedClient;
-
-            if (oldClient != null) {
-                oldClient.update(Client.CHANGE_PORT);
-            }
-
-            if (mSelectedClient != null) {
-                mSelectedClient.update(Client.CHANGE_PORT);
-            }
-        }
-    }
-
-    /**
-     * Returns the client accepting debugger connection on the custom "Selected debug port".
-     */
-    Client getSelectedClient() {
-        return mSelectedClient;
-    }
-
-
-    /**
-     * Returns "true" if we want to retry connections to clients if we get a bad
-     * JDWP handshake back, "false" if we want to just mark them as bad and
-     * leave them alone.
-     */
-    boolean getRetryOnBadHandshake() {
-        return true; // TODO? make configurable
-    }
-
-    /**
-     * Get an array of known clients.
-     */
-    Client[] getClients() {
-        synchronized (mClientList) {
-            return mClientList.toArray(new Client[0]);
-        }
-    }
-
-    /**
-     * Register "handler" as the handler for type "type".
-     */
-    synchronized void registerChunkHandler(int type, ChunkHandler handler) {
-        if (mInstance == null) {
-            return;
-        }
-
-        synchronized (mHandlerMap) {
-            if (mHandlerMap.get(type) == null) {
-                mHandlerMap.put(type, handler);
-            }
-        }
-    }
-
-    /**
-     * Watch for activity from clients and debuggers.
-     */
-    @Override
-    public void run() {
-        Log.d("ddms", "Monitor is up");
-
-        // create a selector
-        try {
-            mSelector = Selector.open();
-        } catch (IOException ioe) {
-            Log.logAndDisplay(LogLevel.ERROR, "ddms",
-                    "Failed to initialize Monitor Thread: " + ioe.getMessage());
-            return;
-        }
-
-        while (!mQuit) {
-
-            try {
-                /*
-                 * sync with new registrations: we wait until addClient is done before going through
-                 * and doing mSelector.select() again.
-                 * @see {@link #addClient(Client)}
-                 */
-                synchronized (mClientList) {
-                }
-
-                // (re-)open the "debug selected" port, if it's not opened yet or
-                // if the port changed.
-                try {
-                    if (AndroidDebugBridge.getClientSupport()) {
-                        if ((mDebugSelectedChan == null ||
-                                mNewDebugSelectedPort != mDebugSelectedPort) &&
-                                mNewDebugSelectedPort != -1) {
-                            if (reopenDebugSelectedPort()) {
-                                mDebugSelectedPort = mNewDebugSelectedPort;
-                            }
-                        }
-                    }
-                } catch (IOException ioe) {
-                    Log.e("ddms",
-                            "Failed to reopen debug port for Selected Client to: " + mNewDebugSelectedPort);
-                    Log.e("ddms", ioe);
-                    mNewDebugSelectedPort = mDebugSelectedPort; // no retry
-                }
-
-                int count;
-                try {
-                    count = mSelector.select();
-                } catch (IOException ioe) {
-                    ioe.printStackTrace();
-                    continue;
-                } catch (CancelledKeyException cke) {
-                    continue;
-                }
-
-                if (count == 0) {
-                    // somebody called wakeup() ?
-                    // Log.i("ddms", "selector looping");
-                    continue;
-                }
-
-                Set<SelectionKey> keys = mSelector.selectedKeys();
-                Iterator<SelectionKey> iter = keys.iterator();
-
-                while (iter.hasNext()) {
-                    SelectionKey key = iter.next();
-                    iter.remove();
-
-                    try {
-                        if (key.attachment() instanceof Client) {
-                            processClientActivity(key);
-                        }
-                        else if (key.attachment() instanceof Debugger) {
-                            processDebuggerActivity(key);
-                        }
-                        else if (key.attachment() instanceof MonitorThread) {
-                            processDebugSelectedActivity(key);
-                        }
-                        else {
-                            Log.e("ddms", "unknown activity key");
-                        }
-                    } catch (Exception e) {
-                        // we don't want to have our thread be killed because of any uncaught
-                        // exception, so we intercept all here.
-                        Log.e("ddms", "Exception during activity from Selector.");
-                        Log.e("ddms", e);
-                    }
-                }
-            } catch (Exception e) {
-                // we don't want to have our thread be killed because of any uncaught
-                // exception, so we intercept all here.
-                Log.e("ddms", "Exception MonitorThread.run()");
-                Log.e("ddms", e);
-            }
-        }
-    }
-
-
-    /**
-     * Returns the port on which the selected client listen for debugger
-     */
-    int getDebugSelectedPort() {
-        return mDebugSelectedPort;
-    }
-
-    /*
-     * Something happened. Figure out what.
-     */
-    private void processClientActivity(SelectionKey key) {
-        Client client = (Client)key.attachment();
-
-        try {
-            if (key.isReadable() == false || key.isValid() == false) {
-                Log.d("ddms", "Invalid key from " + client + ". Dropping client.");
-                dropClient(client, true /* notify */);
-                return;
-            }
-
-            client.read();
-
-            /*
-             * See if we have a full packet in the buffer. It's possible we have
-             * more than one packet, so we have to loop.
-             */
-            JdwpPacket packet = client.getJdwpPacket();
-            while (packet != null) {
-                if (packet.isDdmPacket()) {
-                    // unsolicited DDM request - hand it off
-                    assert !packet.isReply();
-                    callHandler(client, packet, null);
-                    packet.consume();
-                } else if (packet.isReply()
-                        && client.isResponseToUs(packet.getId()) != null) {
-                    // reply to earlier DDM request
-                    ChunkHandler handler = client
-                            .isResponseToUs(packet.getId());
-                    if (packet.isError())
-                        client.packetFailed(packet);
-                    else if (packet.isEmpty())
-                        Log.d("ddms", "Got empty reply for 0x"
-                                + Integer.toHexString(packet.getId())
-                                + " from " + client);
-                    else
-                        callHandler(client, packet, handler);
-                    packet.consume();
-                    client.removeRequestId(packet.getId());
-                } else {
-                    Log.v("ddms", "Forwarding client "
-                            + (packet.isReply() ? "reply" : "event") + " 0x"
-                            + Integer.toHexString(packet.getId()) + " to "
-                            + client.getDebugger());
-                    client.forwardPacketToDebugger(packet);
-                }
-
-                // find next
-                packet = client.getJdwpPacket();
-            }
-        } catch (CancelledKeyException e) {
-            // key was canceled probably due to a disconnected client before we could
-            // read stuff coming from the client, so we drop it.
-            dropClient(client, true /* notify */);
-        } catch (IOException ex) {
-            // something closed down, no need to print anything. The client is simply dropped.
-            dropClient(client, true /* notify */);
-        } catch (Exception ex) {
-            Log.e("ddms", ex);
-
-            /* close the client; automatically un-registers from selector */
-            dropClient(client, true /* notify */);
-
-            if (ex instanceof BufferOverflowException) {
-                Log.w("ddms",
-                        "Client data packet exceeded maximum buffer size "
-                                + client);
-            } else {
-                // don't know what this is, display it
-                Log.e("ddms", ex);
-            }
-        }
-    }
-
-    /*
-     * Process an incoming DDM packet. If this is a reply to an earlier request,
-     * "handler" will be set to the handler responsible for the original
-     * request. The spec allows a JDWP message to include multiple DDM chunks.
-     */
-    private void callHandler(Client client, JdwpPacket packet,
-            ChunkHandler handler) {
-
-        // on first DDM packet received, broadcast a "ready" message
-        if (!client.ddmSeen())
-            broadcast(CLIENT_READY, client);
-
-        ByteBuffer buf = packet.getPayload();
-        int type, length;
-        boolean reply = true;
-
-        type = buf.getInt();
-        length = buf.getInt();
-
-        if (handler == null) {
-            // not a reply, figure out who wants it
-            synchronized (mHandlerMap) {
-                handler = mHandlerMap.get(type);
-                reply = false;
-            }
-        }
-
-        if (handler == null) {
-            Log.w("ddms", "Received unsupported chunk type "
-                    + ChunkHandler.name(type) + " (len=" + length + ")");
-        } else {
-            Log.d("ddms", "Calling handler for " + ChunkHandler.name(type)
-                    + " [" + handler + "] (len=" + length + ")");
-            ByteBuffer ibuf = buf.slice();
-            ByteBuffer roBuf = ibuf.asReadOnlyBuffer(); // enforce R/O
-            roBuf.order(ChunkHandler.CHUNK_ORDER);
-            // do the handling of the chunk synchronized on the client list
-            // to be sure there's no concurrency issue when we look for HOME
-            // in hasApp()
-            synchronized (mClientList) {
-                handler.handleChunk(client, type, roBuf, reply, packet.getId());
-            }
-        }
-    }
-
-    /**
-     * Drops a client from the monitor.
-     * <p/>This will lock the {@link Client} list of the {@link Device} running <var>client</var>.
-     * @param client
-     * @param notify
-     */
-    synchronized void dropClient(Client client, boolean notify) {
-        if (mInstance == null) {
-            return;
-        }
-
-        synchronized (mClientList) {
-            if (mClientList.remove(client) == false) {
-                return;
-            }
-        }
-        client.close(notify);
-        broadcast(CLIENT_DISCONNECTED, client);
-
-        /*
-         * http://forum.java.sun.com/thread.jspa?threadID=726715&start=0
-         * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5073504
-         */
-        wakeup();
-    }
-
-    /*
-     * Process activity from one of the debugger sockets. This could be a new
-     * connection or a data packet.
-     */
-    private void processDebuggerActivity(SelectionKey key) {
-        Debugger dbg = (Debugger)key.attachment();
-
-        try {
-            if (key.isAcceptable()) {
-                try {
-                    acceptNewDebugger(dbg, null);
-                } catch (IOException ioe) {
-                    Log.w("ddms", "debugger accept() failed");
-                    ioe.printStackTrace();
-                }
-            } else if (key.isReadable()) {
-                processDebuggerData(key);
-            } else {
-                Log.d("ddm-debugger", "key in unknown state");
-            }
-        } catch (CancelledKeyException cke) {
-            // key has been cancelled we can ignore that.
-        }
-    }
-
-    /*
-     * Accept a new connection from a debugger. If successful, register it with
-     * the Selector.
-     */
-    private void acceptNewDebugger(Debugger dbg, ServerSocketChannel acceptChan)
-            throws IOException {
-
-        synchronized (mClientList) {
-            SocketChannel chan;
-
-            if (acceptChan == null)
-                chan = dbg.accept();
-            else
-                chan = dbg.accept(acceptChan);
-
-            if (chan != null) {
-                chan.socket().setTcpNoDelay(true);
-
-                wakeup();
-
-                try {
-                    chan.register(mSelector, SelectionKey.OP_READ, dbg);
-                } catch (IOException ioe) {
-                    // failed, drop the connection
-                    dbg.closeData();
-                    throw ioe;
-                } catch (RuntimeException re) {
-                    // failed, drop the connection
-                    dbg.closeData();
-                    throw re;
-                }
-            } else {
-                Log.w("ddms", "ignoring duplicate debugger");
-                // new connection already closed
-            }
-        }
-    }
-
-    /*
-     * We have incoming data from the debugger. Forward it to the client.
-     */
-    private void processDebuggerData(SelectionKey key) {
-        Debugger dbg = (Debugger)key.attachment();
-
-        try {
-            /*
-             * Read pending data.
-             */
-            dbg.read();
-
-            /*
-             * See if we have a full packet in the buffer. It's possible we have
-             * more than one packet, so we have to loop.
-             */
-            JdwpPacket packet = dbg.getJdwpPacket();
-            while (packet != null) {
-                Log.v("ddms", "Forwarding dbg req 0x"
-                        + Integer.toHexString(packet.getId()) + " to "
-                        + dbg.getClient());
-
-                dbg.forwardPacketToClient(packet);
-
-                packet = dbg.getJdwpPacket();
-            }
-        } catch (IOException ioe) {
-            /*
-             * Close data connection; automatically un-registers dbg from
-             * selector. The failure could be caused by the debugger going away,
-             * or by the client going away and failing to accept our data.
-             * Either way, the debugger connection does not need to exist any
-             * longer. We also need to recycle the connection to the client, so
-             * that the VM sees the debugger disconnect. For a DDM-aware client
-             * this won't be necessary, and we can just send a "debugger
-             * disconnected" message.
-             */
-            Log.d("ddms", "Closing connection to debugger " + dbg);
-            dbg.closeData();
-            Client client = dbg.getClient();
-            if (client.isDdmAware()) {
-                // TODO: soft-disconnect DDM-aware clients
-                Log.d("ddms", " (recycling client connection as well)");
-
-                // we should drop the client, but also attempt to reopen it.
-                // This is done by the DeviceMonitor.
-                client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
-                        IDebugPortProvider.NO_STATIC_PORT);
-            } else {
-                Log.d("ddms", " (recycling client connection as well)");
-                // we should drop the client, but also attempt to reopen it.
-                // This is done by the DeviceMonitor.
-                client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
-                        IDebugPortProvider.NO_STATIC_PORT);
-            }
-        }
-    }
-
-    /*
-     * Tell the thread that something has changed.
-     */
-    private void wakeup() {
-        mSelector.wakeup();
-    }
-
-    /**
-     * Tell the thread to stop. Called from UI thread.
-     */
-    synchronized void quit() {
-        mQuit = true;
-        wakeup();
-        Log.d("ddms", "Waiting for Monitor thread");
-        try {
-            this.join();
-            // since we're quitting, lets drop all the client and disconnect
-            // the DebugSelectedPort
-            synchronized (mClientList) {
-                for (Client c : mClientList) {
-                    c.close(false /* notify */);
-                    broadcast(CLIENT_DISCONNECTED, c);
-                }
-                mClientList.clear();
-            }
-
-            if (mDebugSelectedChan != null) {
-                mDebugSelectedChan.close();
-                mDebugSelectedChan.socket().close();
-                mDebugSelectedChan = null;
-            }
-            mSelector.close();
-        } catch (InterruptedException ie) {
-            ie.printStackTrace();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-
-        mInstance = null;
-    }
-
-    /**
-     * Add a new Client to the list of things we monitor. Also adds the client's
-     * channel and the client's debugger listener to the selection list. This
-     * should only be called from one thread (the VMWatcherThread) to avoid a
-     * race between "alreadyOpen" and Client creation.
-     */
-    synchronized void addClient(Client client) {
-        if (mInstance == null) {
-            return;
-        }
-
-        Log.d("ddms", "Adding new client " + client);
-
-        synchronized (mClientList) {
-            mClientList.add(client);
-
-            /*
-             * Register the Client's socket channel with the selector. We attach
-             * the Client to the SelectionKey. If you try to register a new
-             * channel with the Selector while it is waiting for I/O, you will
-             * block. The solution is to call wakeup() and then hold a lock to
-             * ensure that the registration happens before the Selector goes
-             * back to sleep.
-             */
-            try {
-                wakeup();
-
-                client.register(mSelector);
-
-                Debugger dbg = client.getDebugger();
-                if (dbg != null) {
-                    dbg.registerListener(mSelector);
-                }
-            } catch (IOException ioe) {
-                // not really expecting this to happen
-                ioe.printStackTrace();
-            }
-        }
-    }
-
-    /*
-     * Broadcast an event to all message handlers.
-     */
-    private void broadcast(int event, Client client) {
-        Log.d("ddms", "broadcast " + event + ": " + client);
-
-        /*
-         * The handler objects appear once in mHandlerMap for each message they
-         * handle. We want to notify them once each, so we convert the HashMap
-         * to a HashSet before we iterate.
-         */
-        HashSet<ChunkHandler> set;
-        synchronized (mHandlerMap) {
-            Collection<ChunkHandler> values = mHandlerMap.values();
-            set = new HashSet<ChunkHandler>(values);
-        }
-
-        Iterator<ChunkHandler> iter = set.iterator();
-        while (iter.hasNext()) {
-            ChunkHandler handler = iter.next();
-            switch (event) {
-                case CLIENT_READY:
-                    try {
-                        handler.clientReady(client);
-                    } catch (IOException ioe) {
-                        // Something failed with the client. It should
-                        // fall out of the list the next time we try to
-                        // do something with it, so we discard the
-                        // exception here and assume cleanup will happen
-                        // later. May need to propagate farther. The
-                        // trouble is that not all values for "event" may
-                        // actually throw an exception.
-                        Log.w("ddms",
-                                "Got exception while broadcasting 'ready'");
-                        return;
-                    }
-                    break;
-                case CLIENT_DISCONNECTED:
-                    handler.clientDisconnected(client);
-                    break;
-                default:
-                    throw new UnsupportedOperationException();
-            }
-        }
-
-    }
-
-    /**
-     * Opens (or reopens) the "debug selected" port and listen for connections.
-     * @return true if the port was opened successfully.
-     * @throws IOException
-     */
-    private boolean reopenDebugSelectedPort() throws IOException {
-
-        Log.d("ddms", "reopen debug-selected port: " + mNewDebugSelectedPort);
-        if (mDebugSelectedChan != null) {
-            mDebugSelectedChan.close();
-        }
-
-        mDebugSelectedChan = ServerSocketChannel.open();
-        mDebugSelectedChan.configureBlocking(false); // required for Selector
-
-        InetSocketAddress addr = new InetSocketAddress(
-                InetAddress.getByName("localhost"), //$NON-NLS-1$
-                mNewDebugSelectedPort);
-        mDebugSelectedChan.socket().setReuseAddress(true); // enable SO_REUSEADDR
-
-        try {
-            mDebugSelectedChan.socket().bind(addr);
-            if (mSelectedClient != null) {
-                mSelectedClient.update(Client.CHANGE_PORT);
-            }
-
-            mDebugSelectedChan.register(mSelector, SelectionKey.OP_ACCEPT, this);
-
-            return true;
-        } catch (java.net.BindException e) {
-            displayDebugSelectedBindError(mNewDebugSelectedPort);
-
-            // do not attempt to reopen it.
-            mDebugSelectedChan = null;
-            mNewDebugSelectedPort = -1;
-
-            return false;
-        }
-    }
-
-    /*
-     * We have some activity on the "debug selected" port. Handle it.
-     */
-    private void processDebugSelectedActivity(SelectionKey key) {
-        assert key.isAcceptable();
-
-        ServerSocketChannel acceptChan = (ServerSocketChannel)key.channel();
-
-        /*
-         * Find the debugger associated with the currently-selected client.
-         */
-        if (mSelectedClient != null) {
-            Debugger dbg = mSelectedClient.getDebugger();
-
-            if (dbg != null) {
-                Log.d("ddms", "Accepting connection on 'debug selected' port");
-                try {
-                    acceptNewDebugger(dbg, acceptChan);
-                } catch (IOException ioe) {
-                    // client should be gone, keep going
-                }
-
-                return;
-            }
-        }
-
-        Log.w("ddms",
-                "Connection on 'debug selected' port, but none selected");
-        try {
-            SocketChannel chan = acceptChan.accept();
-            chan.close();
-        } catch (IOException ioe) {
-            // not expected; client should be gone, keep going
-        } catch (NotYetBoundException e) {
-            displayDebugSelectedBindError(mDebugSelectedPort);
-        }
-    }
-
-    private void displayDebugSelectedBindError(int port) {
-        String message = String.format(
-                "Could not open Selected VM debug port (%1$d). Make sure you do not have another instance of DDMS or of the eclipse plugin running. If it's being used by something else, choose a new port number in the preferences.",
-                port);
-
-        Log.logAndDisplay(LogLevel.ERROR, "ddms", message);
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MultiLineReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MultiLineReceiver.java
deleted file mode 100644
index 24dbb05..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MultiLineReceiver.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-/**
- * Base implementation of {@link IShellOutputReceiver}, that takes the raw data coming from the
- * socket, and convert it into {@link String} objects.
- * <p/>Additionally, it splits the string by lines.
- * <p/>Classes extending it must implement {@link #processNewLines(String[])} which receives
- * new parsed lines as they become available.
- */
-public abstract class MultiLineReceiver implements IShellOutputReceiver {
-
-    private boolean mTrimLines = true;
-
-    /** unfinished message line, stored for next packet */
-    private String mUnfinishedLine = null;
-
-    private final ArrayList<String> mArray = new ArrayList<String>();
-
-    /**
-     * Set the trim lines flag.
-     * @param trim hether the lines are trimmed, or not.
-     */
-    public void setTrimLine(boolean trim) {
-        mTrimLines = trim;
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(
-     *      byte[], int, int)
-     */
-    public final void addOutput(byte[] data, int offset, int length) {
-        if (isCancelled() == false) {
-            String s = null;
-            try {
-                s = new String(data, offset, length, "ISO-8859-1"); //$NON-NLS-1$
-            } catch (UnsupportedEncodingException e) {
-                // normal encoding didn't work, try the default one
-                s = new String(data, offset,length);
-            }
-
-            // ok we've got a string
-            if (s != null) {
-                // if we had an unfinished line we add it.
-                if (mUnfinishedLine != null) {
-                    s = mUnfinishedLine + s;
-                    mUnfinishedLine = null;
-                }
-
-                // now we split the lines
-                mArray.clear();
-                int start = 0;
-                do {
-                    int index = s.indexOf("\r\n", start); //$NON-NLS-1$
-
-                    // if \r\n was not found, this is an unfinished line
-                    // and we store it to be processed for the next packet
-                    if (index == -1) {
-                        mUnfinishedLine = s.substring(start);
-                        break;
-                    }
-
-                    // so we found a \r\n;
-                    // extract the line
-                    String line = s.substring(start, index);
-                    if (mTrimLines) {
-                        line = line.trim();
-                    }
-                    mArray.add(line);
-
-                    // move start to after the \r\n we found
-                    start = index + 2;
-                } while (true);
-
-                if (mArray.size() > 0) {
-                    // at this point we've split all the lines.
-                    // make the array
-                    String[] lines = mArray.toArray(new String[mArray.size()]);
-
-                    // send it for final processing
-                    processNewLines(lines);
-                }
-            }
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.adb.IShellOutputReceiver#flush()
-     */
-    public final void flush() {
-        if (mUnfinishedLine != null) {
-            processNewLines(new String[] { mUnfinishedLine });
-        }
-
-        done();
-    }
-
-    /**
-     * Terminates the process. This is called after the last lines have been through
-     * {@link #processNewLines(String[])}.
-     */
-    public void done() {
-        // do nothing.
-    }
-
-    /**
-     * Called when new lines are being received by the remote process.
-     * <p/>It is guaranteed that the lines are complete when they are given to this method.
-     * @param lines The array containing the new lines.
-     */
-    public abstract void processNewLines(String[] lines);
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java
deleted file mode 100644
index 956b004..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Stores native allocation information.
- * <p/>Contains number of allocations, their size and the stack trace.
- * <p/>Note: the ddmlib does not resolve the stack trace automatically. While this class provides
- * storage for resolved stack trace, this is merely for convenience.
- */
-public final class NativeAllocationInfo {
-    /* constants for flag bits */
-    private static final int FLAG_ZYGOTE_CHILD  = (1<<31);
-    private static final int FLAG_MASK          = (FLAG_ZYGOTE_CHILD);
-
-    /**
-     * list of alloc functions that are filtered out when attempting to display
-     * a relevant method responsible for an allocation
-     */
-    private static ArrayList<String> sAllocFunctionFilter;
-    static {
-        sAllocFunctionFilter = new ArrayList<String>();
-        sAllocFunctionFilter.add("malloc"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("calloc"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("realloc"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("get_backtrace"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("get_hash"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("??"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("internal_free"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("operator new"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("leak_free"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("chk_free"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("chk_memalign"); //$NON-NLS-1$
-        sAllocFunctionFilter.add("Malloc"); //$NON-NLS-1$
-    }
-
-    private final int mSize;
-
-    private final boolean mIsZygoteChild;
-
-    private final int mAllocations;
-
-    private final ArrayList<Long> mStackCallAddresses = new ArrayList<Long>();
-
-    private ArrayList<NativeStackCallInfo> mResolvedStackCall = null;
-
-    private boolean mIsStackCallResolved = false;
-
-    /**
-     * Constructs a new {@link NativeAllocationInfo}.
-     * @param size The size of the allocations.
-     * @param allocations the allocation count
-     */
-    NativeAllocationInfo(int size, int allocations) {
-        this.mSize = size & ~FLAG_MASK;
-        this.mIsZygoteChild = ((size & FLAG_ZYGOTE_CHILD) != 0);
-        this.mAllocations = allocations;
-    }
-    
-    /**
-     * Adds a stack call address for this allocation.
-     * @param address The address to add.
-     */
-    void addStackCallAddress(long address) {
-        mStackCallAddresses.add(address);
-    }
-    
-    /**
-     * Returns the total size of this allocation.
-     */
-    public int getSize() {
-        return mSize;
-    }
-
-    /**
-     * Returns whether the allocation happened in a child of the zygote
-     * process.
-     */
-    public boolean isZygoteChild() {
-        return mIsZygoteChild;
-    }
-
-    /**
-     * Returns the allocation count.
-     */
-    public int getAllocationCount() {
-        return mAllocations;
-    }
-    
-    /**
-     * Returns whether the stack call addresses have been resolved into
-     * {@link NativeStackCallInfo} objects.
-     */
-    public boolean isStackCallResolved() {
-        return mIsStackCallResolved;
-    }
-
-    /**
-     * Returns the stack call of this allocation as raw addresses.
-     * @return the list of addresses where the allocation happened.
-     */
-    public Long[] getStackCallAddresses() {
-        return mStackCallAddresses.toArray(new Long[mStackCallAddresses.size()]);
-    }
-    
-    /**
-     * Sets the resolved stack call for this allocation.
-     * <p/>
-     * If <code>resolvedStackCall</code> is non <code>null</code> then
-     * {@link #isStackCallResolved()} will return <code>true</code> after this call.
-     * @param resolvedStackCall The list of {@link NativeStackCallInfo}.
-     */
-    public synchronized void setResolvedStackCall(List<NativeStackCallInfo> resolvedStackCall) {
-        if (mResolvedStackCall == null) {
-            mResolvedStackCall = new ArrayList<NativeStackCallInfo>();
-        } else {
-            mResolvedStackCall.clear();
-        }
-        mResolvedStackCall.addAll(resolvedStackCall);
-        mIsStackCallResolved = mResolvedStackCall.size() != 0;
-    }
-
-    /**
-     * Returns the resolved stack call.
-     * @return An array of {@link NativeStackCallInfo} or <code>null</code> if the stack call
-     * was not resolved.
-     * @see #setResolvedStackCall(ArrayList)
-     * @see #isStackCallResolved()
-     */
-    public synchronized NativeStackCallInfo[] getResolvedStackCall() {
-        if (mIsStackCallResolved) {
-            return mResolvedStackCall.toArray(new NativeStackCallInfo[mResolvedStackCall.size()]);
-        }
-        
-        return null;
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one.
-     * @param obj the reference object with which to compare.
-     * @return <code>true</code> if this object is equal to the obj argument;
-     * <code>false</code> otherwise.
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this)
-            return true;
-        if (obj instanceof NativeAllocationInfo) {
-            NativeAllocationInfo mi = (NativeAllocationInfo)obj;
-            // quick compare of size, alloc, and stackcall size
-            if (mSize != mi.mSize || mAllocations != mi.mAllocations ||
-                    mStackCallAddresses.size() != mi.mStackCallAddresses.size()) {
-                return false;
-            }
-            // compare the stack addresses
-            int count = mStackCallAddresses.size();
-            for (int i = 0 ; i < count ; i++) {
-                long a = mStackCallAddresses.get(i);
-                long b = mi.mStackCallAddresses.get(i);
-                if (a != b) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns a string representation of the object.
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        StringBuffer buffer = new StringBuffer();
-        buffer.append("Allocations: ");
-        buffer.append(mAllocations);
-        buffer.append("\n"); //$NON-NLS-1$
-
-        buffer.append("Size: ");
-        buffer.append(mSize);
-        buffer.append("\n"); //$NON-NLS-1$
-
-        buffer.append("Total Size: ");
-        buffer.append(mSize * mAllocations);
-        buffer.append("\n"); //$NON-NLS-1$
-
-        Iterator<Long> addrIterator = mStackCallAddresses.iterator();
-        Iterator<NativeStackCallInfo> sourceIterator = mResolvedStackCall.iterator();
-
-        while (sourceIterator.hasNext()) {
-            long addr = addrIterator.next();
-            NativeStackCallInfo source = sourceIterator.next();
-            if (addr == 0)
-                continue;
-
-            if (source.getLineNumber() != -1) {
-                buffer.append(String.format("\t%1$08x\t%2$s --- %3$s --- %4$s:%5$d\n", addr,
-                        source.getLibraryName(), source.getMethodName(),
-                        source.getSourceFile(), source.getLineNumber()));
-            } else {
-                buffer.append(String.format("\t%1$08x\t%2$s --- %3$s --- %4$s\n", addr,
-                        source.getLibraryName(), source.getMethodName(), source.getSourceFile()));
-            }
-        }
-
-        return buffer.toString();
-    }
-
-    /**
-     * Returns the first {@link NativeStackCallInfo} that is relevant.
-     * <p/>
-     * A relevant <code>NativeStackCallInfo</code> is a stack call that is not deep in the
-     * lower level of the libc, but the actual method that performed the allocation. 
-     * @return a <code>NativeStackCallInfo</code> or <code>null</code> if the stack call has not
-     * been processed from the raw addresses.
-     * @see #setResolvedStackCall(ArrayList)
-     * @see #isStackCallResolved()
-     */
-    public synchronized NativeStackCallInfo getRelevantStackCallInfo() {
-        if (mIsStackCallResolved && mResolvedStackCall != null) {
-            Iterator<NativeStackCallInfo> sourceIterator = mResolvedStackCall.iterator();
-            Iterator<Long> addrIterator = mStackCallAddresses.iterator();
-
-            while (sourceIterator.hasNext() && addrIterator.hasNext()) {
-                long addr = addrIterator.next();
-                NativeStackCallInfo info = sourceIterator.next();
-                if (addr != 0 && info != null) {
-                    if (isRelevant(info.getMethodName())) {
-                        return info;
-                    }
-                }
-            }
-
-            // couldnt find a relevant one, so we'll return the first one if it
-            // exists.
-            if (mResolvedStackCall.size() > 0)
-                return mResolvedStackCall.get(0);
-        }
-
-        return null;
-    }
-    
-    /**
-     * Returns true if the method name is relevant.
-     * @param methodName the method name to test.
-     */
-    private boolean isRelevant(String methodName) {
-        for (String filter : sAllocFunctionFilter) {
-            if (methodName.contains(filter)) {
-                return false;
-            }
-        }
-        
-        return true;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeLibraryMapInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeLibraryMapInfo.java
deleted file mode 100644
index 5a26317..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeLibraryMapInfo.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-/**
- * Memory address to library mapping for native libraries.
- * <p/>
- * Each instance represents a single native library and its start and end memory addresses. 
- */
-public final class NativeLibraryMapInfo {
-    private long mStartAddr;
-    private long mEndAddr;
-
-    private String mLibrary;
-
-    /**
-     * Constructs a new native library map info.
-     * @param startAddr The start address of the library.
-     * @param endAddr The end address of the library.
-     * @param library The name of the library.
-     */
-    NativeLibraryMapInfo(long startAddr, long endAddr, String library) {
-        this.mStartAddr = startAddr;
-        this.mEndAddr = endAddr;
-        this.mLibrary = library;
-    }
-    
-    /**
-     * Returns the name of the library.
-     */
-    public String getLibraryName() {
-        return mLibrary;
-    }
-    
-    /**
-     * Returns the start address of the library.
-     */
-    public long getStartAddress() {
-        return mStartAddr;
-    }
-    
-    /**
-     * Returns the end address of the library.
-     */
-    public long getEndAddress() {
-        return mEndAddr;
-    }
-
-    /**
-     * Returns whether the specified address is inside the library.
-     * @param address The address to test.
-     * @return <code>true</code> if the address is between the start and end address of the library.
-     * @see #getStartAddress()
-     * @see #getEndAddress()
-     */
-    public boolean isWithinLibrary(long address) {
-        return address >= mStartAddr && address <= mEndAddr;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java
deleted file mode 100644
index e54818d..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Represents a stack call. This is used to return all of the call
- * information as one object.
- */
-public final class NativeStackCallInfo {
-    private final static Pattern SOURCE_NAME_PATTERN = Pattern.compile("^(.+):(\\d+)$");
-    
-    /** name of the library */
-    private String mLibrary;
-
-    /** name of the method */
-    private String mMethod;
-
-    /**
-     * name of the source file + line number in the format<br>
-     * &lt;sourcefile&gt;:&lt;linenumber&gt;
-     */
-    private String mSourceFile;
-    
-    private int mLineNumber = -1; 
-
-    /**
-     * Basic constructor with library, method, and sourcefile information
-     *
-     * @param lib The name of the library
-     * @param method the name of the method
-     * @param sourceFile the name of the source file and the line number
-     * as "[sourcefile]:[fileNumber]"
-     */
-    public NativeStackCallInfo(String lib, String method, String sourceFile) {
-        mLibrary = lib;
-        mMethod = method;
-        
-        Matcher m = SOURCE_NAME_PATTERN.matcher(sourceFile);
-        if (m.matches()) {
-            mSourceFile = m.group(1);
-            try {
-                mLineNumber = Integer.parseInt(m.group(2));
-            } catch (NumberFormatException e) {
-                // do nothing, the line number will stay at -1
-            }
-        } else {
-            mSourceFile = sourceFile;
-        }
-    }
-    
-    /**
-     * Returns the name of the library name.
-     */
-    public String getLibraryName() {
-        return mLibrary;
-    }
-
-    /** 
-     * Returns the name of the method.
-     */
-    public String getMethodName() {
-        return mMethod;
-    }
-    
-    /**
-     * Returns the name of the source file.
-     */
-    public String getSourceFile() {
-        return mSourceFile;
-    }
-
-    /**
-     * Returns the line number, or -1 if unknown.
-     */
-    public int getLineNumber() {
-        return mLineNumber;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NullOutputReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NullOutputReceiver.java
deleted file mode 100644
index d2b5a1e..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NullOutputReceiver.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-/**
- * Implementation of {@link IShellOutputReceiver} that does nothing.
- * <p/>This can be used to execute a remote shell command when the output is not needed.
- */
-public final class NullOutputReceiver implements IShellOutputReceiver {
-
-    private static NullOutputReceiver sReceiver = new NullOutputReceiver();
-
-    public static IShellOutputReceiver getReceiver() {
-        return sReceiver;
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(byte[], int, int)
-     */
-    public void addOutput(byte[] data, int offset, int length) {
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.adb.IShellOutputReceiver#flush()
-     */
-    public void flush() {
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.adb.IShellOutputReceiver#isCancelled()
-     */
-    public boolean isCancelled() {
-        return false;
-    }
-
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java
deleted file mode 100644
index 3ec6148..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import java.nio.ByteBuffer;
-
-/**
- * Data representing an image taken from a device frame buffer.
- */
-public final class RawImage {
-    public int version;
-    public int bpp;
-    public int size;
-    public int width;
-    public int height;
-    public int red_offset;
-    public int red_length;
-    public int blue_offset;
-    public int blue_length;
-    public int green_offset;
-    public int green_length;
-    public int alpha_offset;
-    public int alpha_length;
-
-    public byte[] data;
-
-    /**
-     * Reads the header of a RawImage from a {@link ByteBuffer}.
-     * <p/>The way the data is sent over adb is defined in system/core/adb/framebuffer_service.c
-     * @param version the version of the protocol.
-     * @param buf the buffer to read from.
-     * @return true if success
-     */
-    public boolean readHeader(int version, ByteBuffer buf) {
-        this.version = version;
-
-        if (version == 16) {
-            // compatibility mode with original protocol
-            this.bpp = 16;
-
-            // read actual values.
-            this.size = buf.getInt();
-            this.width = buf.getInt();
-            this.height = buf.getInt();
-
-            // create default values for the rest. Format is 565
-            this.red_offset = 11;
-            this.red_length = 5;
-            this.green_offset = 5;
-            this.green_length = 6;
-            this.blue_offset = 0;
-            this.blue_length = 5;
-            this.alpha_offset = 0;
-            this.alpha_length = 0;
-        } else if (version == 1) {
-            this.bpp = buf.getInt();
-            this.size = buf.getInt();
-            this.width = buf.getInt();
-            this.height = buf.getInt();
-            this.red_offset = buf.getInt();
-            this.red_length = buf.getInt();
-            this.blue_offset = buf.getInt();
-            this.blue_length = buf.getInt();
-            this.green_offset = buf.getInt();
-            this.green_length = buf.getInt();
-            this.alpha_offset = buf.getInt();
-            this.alpha_length = buf.getInt();
-        } else {
-            // unsupported protocol!
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns the mask value for the red color.
-     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
-     */
-    public int getRedMask() {
-        return getMask(red_length, red_offset);
-    }
-
-    /**
-     * Returns the mask value for the green color.
-     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
-     */
-    public int getGreenMask() {
-        return getMask(green_length, green_offset);
-    }
-
-    /**
-     * Returns the mask value for the blue color.
-     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
-     */
-    public int getBlueMask() {
-        return getMask(blue_length, blue_offset);
-    }
-
-    /**
-     * Returns the size of the header for a specific version of the framebuffer adb protocol.
-     * @param version the version of the protocol
-     * @return the number of int that makes up the header.
-     */
-    public static int getHeaderSize(int version) {
-        switch (version) {
-            case 16: // compatibility mode
-                return 3; // size, width, height
-            case 1:
-                return 12; // bpp, size, width, height, 4*(length, offset)
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns a rotated version of the image
-     * The image is rotated counter-clockwise.
-     */
-    public RawImage getRotated() {
-        RawImage rotated = new RawImage();
-        rotated.version = this.version;
-        rotated.bpp = this.bpp;
-        rotated.size = this.size;
-        rotated.red_offset = this.red_offset;
-        rotated.red_length = this.red_length;
-        rotated.blue_offset = this.blue_offset;
-        rotated.blue_length = this.blue_length;
-        rotated.green_offset = this.green_offset;
-        rotated.green_length = this.green_length;
-        rotated.alpha_offset = this.alpha_offset;
-        rotated.alpha_length = this.alpha_length;
-
-        rotated.width = this.height;
-        rotated.height = this.width;
-
-        int count = this.data.length;
-        rotated.data = new byte[count];
-
-        int byteCount = this.bpp >> 3; // bpp is in bits, we want bytes to match our array
-        final int w = this.width;
-        final int h = this.height;
-        for (int y = 0 ; y < h ; y++) {
-            for (int x = 0 ; x < w ; x++) {
-                System.arraycopy(
-                        this.data, (y * w + x) * byteCount,
-                        rotated.data, ((w-x-1) * h + y) * byteCount,
-                        byteCount);
-            }
-        }
-
-        return rotated;
-    }
-
-    /**
-     * Returns an ARGB integer value for the pixel at <var>index</var> in {@link #data}.
-     */
-    public int getARGB(int index) {
-        int value;
-        if (bpp == 16) {
-            value = data[index] & 0x00FF;
-            value |= (data[index+1] << 8) & 0x0FF00;
-        } else if (bpp == 32) {
-            value = data[index] & 0x00FF;
-            value |= (data[index+1] & 0x00FF) << 8;
-            value |= (data[index+2] & 0x00FF) << 16;
-            value |= (data[index+3] & 0x00FF) << 24;
-        } else {
-            throw new UnsupportedOperationException("RawImage.getARGB(int) only works in 16 and 32 bit mode.");
-        }
-
-        int r = ((value >>> red_offset) & getMask(red_length)) << (8 - red_length);
-        int g = ((value >>> green_offset) & getMask(green_length)) << (8 - green_length);
-        int b = ((value >>> blue_offset) & getMask(blue_length)) << (8 - blue_length);
-        int a;
-        if (alpha_length == 0) {
-            a = 0xFF; // force alpha to opaque if there's no alpha value in the framebuffer.
-        } else {
-            a = ((value >>> alpha_offset) & getMask(alpha_length)) << (8 - alpha_length);
-        }
-
-        return a << 24 | r << 16 | g << 8 | b;
-    }
-
-    /**
-     * creates a mask value based on a length and offset.
-     * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData
-     */
-    private int getMask(int length, int offset) {
-        int res = getMask(length) << offset;
-
-        // if the bpp is 32 bits then we need to invert it because the buffer is in little endian
-        if (bpp == 32) {
-            return Integer.reverseBytes(res);
-        }
-
-        return res;
-    }
-
-    /**
-     * Creates a mask value based on a length.
-     * @param length
-     * @return
-     */
-    private int getMask(int length) {
-        int res = 0;
-        for (int i = 0 ; i < length ; i++) {
-            res = (res << 1) + 1;
-        }
-
-        return res;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
deleted file mode 100644
index 9f6b561..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-import com.android.ddmlib.AdbHelper.AdbResponse;
-import com.android.ddmlib.FileListingService.FileEntry;
-import com.android.ddmlib.utils.ArrayHelper;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-
-/**
- * Sync service class to push/pull to/from devices/emulators, through the debug bridge.
- * <p/>
- * To get a {@link SyncService} object, use {@link Device#getSyncService()}.
- */
-public final class SyncService {
-
-    private final static byte[] ID_OKAY = { 'O', 'K', 'A', 'Y' };
-    private final static byte[] ID_FAIL = { 'F', 'A', 'I', 'L' };
-    private final static byte[] ID_STAT = { 'S', 'T', 'A', 'T' };
-    private final static byte[] ID_RECV = { 'R', 'E', 'C', 'V' };
-    private final static byte[] ID_DATA = { 'D', 'A', 'T', 'A' };
-    private final static byte[] ID_DONE = { 'D', 'O', 'N', 'E' };
-    private final static byte[] ID_SEND = { 'S', 'E', 'N', 'D' };
-//    private final static byte[] ID_LIST = { 'L', 'I', 'S', 'T' };
-//    private final static byte[] ID_DENT = { 'D', 'E', 'N', 'T' };
-
-    private final static NullSyncProgresMonitor sNullSyncProgressMonitor =
-            new NullSyncProgresMonitor();
-
-    private final static int S_ISOCK = 0xC000; // type: symbolic link
-    private final static int S_IFLNK = 0xA000; // type: symbolic link
-    private final static int S_IFREG = 0x8000; // type: regular file
-    private final static int S_IFBLK = 0x6000; // type: block device
-    private final static int S_IFDIR = 0x4000; // type: directory
-    private final static int S_IFCHR = 0x2000; // type: character device
-    private final static int S_IFIFO = 0x1000; // type: fifo
-/*
-    private final static int S_ISUID = 0x0800; // set-uid bit
-    private final static int S_ISGID = 0x0400; // set-gid bit
-    private final static int S_ISVTX = 0x0200; // sticky bit
-    private final static int S_IRWXU = 0x01C0; // user permissions
-    private final static int S_IRUSR = 0x0100; // user: read
-    private final static int S_IWUSR = 0x0080; // user: write
-    private final static int S_IXUSR = 0x0040; // user: execute
-    private final static int S_IRWXG = 0x0038; // group permissions
-    private final static int S_IRGRP = 0x0020; // group: read
-    private final static int S_IWGRP = 0x0010; // group: write
-    private final static int S_IXGRP = 0x0008; // group: execute
-    private final static int S_IRWXO = 0x0007; // other permissions
-    private final static int S_IROTH = 0x0004; // other: read
-    private final static int S_IWOTH = 0x0002; // other: write
-    private final static int S_IXOTH = 0x0001; // other: execute
-*/
-
-    private final static int SYNC_DATA_MAX = 64*1024;
-    private final static int REMOTE_PATH_MAX_LENGTH = 1024;
-
-    /** Result code for transfer success. */
-    public static final int RESULT_OK = 0;
-    /** Result code for canceled transfer */
-    public static final int RESULT_CANCELED = 1;
-    /** Result code for unknown error */
-    public static final int RESULT_UNKNOWN_ERROR = 2;
-    /** Result code for network connection error */
-    public static final int RESULT_CONNECTION_ERROR = 3;
-    /** Result code for unknown remote object during a pull */
-    public static final int RESULT_NO_REMOTE_OBJECT = 4;
-    /** Result code when attempting to pull multiple files into a file */
-    public static final int RESULT_TARGET_IS_FILE = 5;
-    /** Result code when attempting to pull multiple into a directory that does not exist. */
-    public static final int RESULT_NO_DIR_TARGET = 6;
-    /** Result code for wrong encoding on the remote path. */
-    public static final int RESULT_REMOTE_PATH_ENCODING = 7;
-    /** Result code for remote path that is too long. */
-    public static final int RESULT_REMOTE_PATH_LENGTH = 8;
-    /** Result code for error while writing local file. */
-    public static final int RESULT_FILE_WRITE_ERROR = 9;
-    /** Result code for error while reading local file. */
-    public static final int RESULT_FILE_READ_ERROR = 10;
-    /** Result code for attempting to push a file that does not exist. */
-    public static final int RESULT_NO_LOCAL_FILE = 11;
-    /** Result code for attempting to push a directory. */
-    public static final int RESULT_LOCAL_IS_DIRECTORY = 12;
-    /** Result code for when the target path of a multi file push is a file. */
-    public static final int RESULT_REMOTE_IS_FILE = 13;
-    /** Result code for receiving too much data from the remove device at once */
-    public static final int RESULT_BUFFER_OVERRUN = 14;
-
-    /**
-     * A file transfer result.
-     * <p/>
-     * This contains a code, and an optional string
-     */
-    public static class SyncResult {
-        private int mCode;
-        private String mMessage;
-        SyncResult(int code, String message) {
-            mCode = code;
-            mMessage = message;
-        }
-
-        SyncResult(int code, Exception e) {
-            this(code, e.getMessage());
-        }
-
-        SyncResult(int code) {
-            this(code, errorCodeToString(code));
-        }
-
-        public int getCode() {
-            return mCode;
-        }
-
-        public String getMessage() {
-            return mMessage;
-        }
-    }
-
-    /**
-     * Classes which implement this interface provide methods that deal
-     * with displaying transfer progress.
-     */
-    public interface ISyncProgressMonitor {
-        /**
-         * Sent when the transfer starts
-         * @param totalWork the total amount of work.
-         */
-        public void start(int totalWork);
-        /**
-         * Sent when the transfer is finished or interrupted.
-         */
-        public void stop();
-        /**
-         * Sent to query for possible cancellation.
-         * @return true if the transfer should be stopped.
-         */
-        public boolean isCanceled();
-        /**
-         * Sent when a sub task is started.
-         * @param name the name of the sub task.
-         */
-        public void startSubTask(String name);
-        /**
-         * Sent when some progress have been made.
-         * @param work the amount of work done.
-         */
-        public void advance(int work);
-    }
-
-    /**
-     * A Sync progress monitor that does nothing
-     */
-    private static class NullSyncProgresMonitor implements ISyncProgressMonitor {
-        public void advance(int work) {
-        }
-        public boolean isCanceled() {
-            return false;
-        }
-
-        public void start(int totalWork) {
-        }
-        public void startSubTask(String name) {
-        }
-        public void stop() {
-        }
-    }
-
-    private InetSocketAddress mAddress;
-    private Device mDevice;
-    private SocketChannel mChannel;
-
-    /**
-     * Buffer used to send data. Allocated when needed and reused afterward.
-     */
-    private byte[] mBuffer;
-
-    /**
-     * Creates a Sync service object.
-     * @param address The address to connect to
-     * @param device the {@link Device} that the service connects to.
-     */
-    SyncService(InetSocketAddress address, Device device) {
-        mAddress = address;
-        mDevice = device;
-    }
-
-    /**
-     * Opens the sync connection. This must be called before any calls to push[File] / pull[File].
-     * @return true if the connection opened, false if adb refuse the connection. This can happen
-     * if the {@link Device} is invalid.
-     * @throws IOException If the connection to adb failed.
-     */
-    boolean openSync() throws IOException {
-        try {
-            mChannel = SocketChannel.open(mAddress);
-            mChannel.configureBlocking(false);
-
-            // target a specific device
-            AdbHelper.setDevice(mChannel, mDevice);
-
-            byte[] request = AdbHelper.formAdbRequest("sync:"); // $NON-NLS-1$
-            AdbHelper.write(mChannel, request, -1, DdmPreferences.getTimeOut());
-
-            AdbResponse resp = AdbHelper.readAdbResponse(mChannel, false /* readDiagString */);
-
-            if (!resp.ioSuccess || !resp.okay) {
-                Log.w("ddms",
-                        "Got timeout or unhappy response from ADB sync req: "
-                        + resp.message);
-                mChannel.close();
-                mChannel = null;
-                return false;
-            }
-        } catch (IOException e) {
-            if (mChannel != null) {
-                try {
-                    mChannel.close();
-                } catch (IOException e2) {
-                    // we want to throw the original exception, so we ignore this one.
-                }
-                mChannel = null;
-            }
-
-            throw e;
-        }
-
-        return true;
-    }
-
-    /**
-     * Closes the connection.
-     */
-    public void close() {
-        if (mChannel != null) {
-            try {
-                mChannel.close();
-            } catch (IOException e) {
-                // nothing to be done really...
-            }
-            mChannel = null;
-        }
-    }
-
-    /**
-     * Returns a sync progress monitor that does nothing. This allows background tasks that don't
-     * want/need to display ui, to pass a valid {@link ISyncProgressMonitor}.
-     * <p/>This object can be reused multiple times and can be used by concurrent threads.
-     */
-    public static ISyncProgressMonitor getNullProgressMonitor() {
-        return sNullSyncProgressMonitor;
-    }
-
-    /**
-     * Converts an error code into a non-localized string
-     * @param code the error code;
-     */
-    private static String errorCodeToString(int code) {
-        switch (code) {
-            case RESULT_OK:
-                return "Success.";
-            case RESULT_CANCELED:
-                return "Tranfert canceled by the user.";
-            case RESULT_UNKNOWN_ERROR:
-                return "Unknown Error.";
-            case RESULT_CONNECTION_ERROR:
-                return "Adb Connection Error.";
-            case RESULT_NO_REMOTE_OBJECT:
-                return "Remote object doesn't exist!";
-            case RESULT_TARGET_IS_FILE:
-                return "Target object is a file.";
-            case RESULT_NO_DIR_TARGET:
-                return "Target directory doesn't exist.";
-            case RESULT_REMOTE_PATH_ENCODING:
-                return "Remote Path encoding is not supported.";
-            case RESULT_REMOTE_PATH_LENGTH:
-                return "Remove path is too long.";
-            case RESULT_FILE_WRITE_ERROR:
-                return "Writing local file failed!";
-            case RESULT_FILE_READ_ERROR:
-                return "Reading local file failed!";
-            case RESULT_NO_LOCAL_FILE:
-                return "Local file doesn't exist.";
-            case RESULT_LOCAL_IS_DIRECTORY:
-                return "Local path is a directory.";
-            case RESULT_REMOTE_IS_FILE:
-                return "Remote path is a file.";
-            case RESULT_BUFFER_OVERRUN:
-                return "Receiving too much data.";
-        }
-
-        throw new RuntimeException();
-    }
-
-    /**
-     * Pulls file(s) or folder(s).
-     * @param entries the remote item(s) to pull
-     * @param localPath The local destination. If the entries count is > 1 or
-     *      if the unique entry is a folder, this should be a folder.
-     * @param monitor The progress monitor. Cannot be null.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     *
-     * @see FileListingService.FileEntry
-     * @see #getNullProgressMonitor()
-     */
-    public SyncResult pull(FileEntry[] entries, String localPath, ISyncProgressMonitor monitor) {
-
-        // first we check the destination is a directory and exists
-        File f = new File(localPath);
-        if (f.exists() == false) {
-            return new SyncResult(RESULT_NO_DIR_TARGET);
-        }
-        if (f.isDirectory() == false) {
-            return new SyncResult(RESULT_TARGET_IS_FILE);
-        }
-
-        // get a FileListingService object
-        FileListingService fls = new FileListingService(mDevice);
-
-        // compute the number of file to move
-        int total = getTotalRemoteFileSize(entries, fls);
-
-        // start the monitor
-        monitor.start(total);
-
-        SyncResult result = doPull(entries, localPath, fls, monitor);
-
-        monitor.stop();
-
-        return result;
-    }
-
-    /**
-     * Pulls a single file.
-     * @param remote the remote file
-     * @param localFilename The local destination.
-     * @param monitor The progress monitor. Cannot be null.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     *
-     * @see FileListingService.FileEntry
-     * @see #getNullProgressMonitor()
-     */
-    public SyncResult pullFile(FileEntry remote, String localFilename,
-            ISyncProgressMonitor monitor) {
-        int total = remote.getSizeValue();
-        monitor.start(total);
-
-        SyncResult result = doPullFile(remote.getFullPath(), localFilename, monitor);
-
-        monitor.stop();
-        return result;
-    }
-
-    /**
-     * Pulls a single file.
-     * <p/>Because this method just deals with a String for the remote file instead of a
-     * {@link FileEntry}, the size of the file being pulled is unknown and the
-     * {@link ISyncProgressMonitor} will not properly show the progress
-     * @param remoteFilepath the full path to the remote file
-     * @param localFilename The local destination.
-     * @param monitor The progress monitor. Cannot be null.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     *
-     * @see #getNullProgressMonitor()
-     */
-    public SyncResult pullFile(String remoteFilepath, String localFilename,
-            ISyncProgressMonitor monitor) {
-        monitor.start(0);
-        //TODO: use the {@link FileListingService} to get the file size.
-
-        SyncResult result = doPullFile(remoteFilepath, localFilename, monitor);
-
-        monitor.stop();
-        return result;
-    }
-
-    /**
-     * Push several files.
-     * @param local An array of loca files to push
-     * @param remote the remote {@link FileEntry} representing a directory.
-     * @param monitor The progress monitor. Cannot be null.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     */
-    public SyncResult push(String[] local, FileEntry remote, ISyncProgressMonitor monitor) {
-        if (remote.isDirectory() == false) {
-            return new SyncResult(RESULT_REMOTE_IS_FILE);
-        }
-
-        // make a list of File from the list of String
-        ArrayList<File> files = new ArrayList<File>();
-        for (String path : local) {
-            files.add(new File(path));
-        }
-
-        // get the total count of the bytes to transfer
-        File[] fileArray = files.toArray(new File[files.size()]);
-        int total = getTotalLocalFileSize(fileArray);
-
-        monitor.start(total);
-
-        SyncResult result = doPush(fileArray, remote.getFullPath(), monitor);
-
-        monitor.stop();
-
-        return result;
-    }
-
-    /**
-     * Push a single file.
-     * @param local the local filepath.
-     * @param remote The remote filepath.
-     * @param monitor The progress monitor. Cannot be null.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     */
-    public SyncResult pushFile(String local, String remote, ISyncProgressMonitor monitor) {
-        File f = new File(local);
-        if (f.exists() == false) {
-            return new SyncResult(RESULT_NO_LOCAL_FILE);
-        }
-
-        if (f.isDirectory()) {
-            return new SyncResult(RESULT_LOCAL_IS_DIRECTORY);
-        }
-
-        monitor.start((int)f.length());
-
-        SyncResult result = doPushFile(local, remote, monitor);
-
-        monitor.stop();
-
-        return result;
-    }
-
-    /**
-     * compute the recursive file size of all the files in the list. Folder
-     * have a weight of 1.
-     * @param entries
-     * @param fls
-     * @return
-     */
-    private int getTotalRemoteFileSize(FileEntry[] entries, FileListingService fls) {
-        int count = 0;
-        for (FileEntry e : entries) {
-            int type = e.getType();
-            if (type == FileListingService.TYPE_DIRECTORY) {
-                // get the children
-                FileEntry[] children = fls.getChildren(e, false, null);
-                count += getTotalRemoteFileSize(children, fls) + 1;
-            } else if (type == FileListingService.TYPE_FILE) {
-                count += e.getSizeValue();
-            }
-        }
-
-        return count;
-    }
-
-    /**
-     * compute the recursive file size of all the files in the list. Folder
-     * have a weight of 1.
-     * This does not check for circular links.
-     * @param files
-     * @return
-     */
-    private int getTotalLocalFileSize(File[] files) {
-        int count = 0;
-
-        for (File f : files) {
-            if (f.exists()) {
-                if (f.isDirectory()) {
-                    return getTotalLocalFileSize(f.listFiles()) + 1;
-                } else if (f.isFile()) {
-                    count += f.length();
-                }
-            }
-        }
-
-        return count;
-    }
-
-    /**
-     * Pulls multiple files/folders recursively.
-     * @param entries The list of entry to pull
-     * @param localPath the localpath to a directory
-     * @param fileListingService a FileListingService object to browse through remote directories.
-     * @param monitor the progress monitor. Must be started already.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     */
-    private SyncResult doPull(FileEntry[] entries, String localPath,
-            FileListingService fileListingService,
-            ISyncProgressMonitor monitor) {
-
-        for (FileEntry e : entries) {
-            // check if we're cancelled
-            if (monitor.isCanceled() == true) {
-                return new SyncResult(RESULT_CANCELED);
-            }
-
-            // get type (we only pull directory and files for now)
-            int type = e.getType();
-            if (type == FileListingService.TYPE_DIRECTORY) {
-                monitor.startSubTask(e.getFullPath());
-                String dest = localPath + File.separator + e.getName();
-
-                // make the directory
-                File d = new File(dest);
-                d.mkdir();
-
-                // then recursively call the content. Since we did a ls command
-                // to get the number of files, we can use the cache
-                FileEntry[] children = fileListingService.getChildren(e, true, null);
-                SyncResult result = doPull(children, dest, fileListingService, monitor);
-                if (result.mCode != RESULT_OK) {
-                    return result;
-                }
-                monitor.advance(1);
-            } else if (type == FileListingService.TYPE_FILE) {
-                monitor.startSubTask(e.getFullPath());
-                String dest = localPath + File.separator + e.getName();
-                SyncResult result = doPullFile(e.getFullPath(), dest, monitor);
-                if (result.mCode != RESULT_OK) {
-                    return result;
-                }
-            }
-        }
-
-        return new SyncResult(RESULT_OK);
-    }
-
-    /**
-     * Pulls a remote file
-     * @param remotePath the remote file (length max is 1024)
-     * @param localPath the local destination
-     * @param monitor the monitor. The monitor must be started already.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     */
-    private SyncResult doPullFile(String remotePath, String localPath,
-            ISyncProgressMonitor monitor) {
-        byte[] msg = null;
-        byte[] pullResult = new byte[8];
-
-        final int timeOut = DdmPreferences.getTimeOut();
-
-        try {
-            byte[] remotePathContent = remotePath.getBytes(AdbHelper.DEFAULT_ENCODING);
-
-            if (remotePathContent.length > REMOTE_PATH_MAX_LENGTH) {
-                return new SyncResult(RESULT_REMOTE_PATH_LENGTH);
-            }
-
-            // create the full request message
-            msg = createFileReq(ID_RECV, remotePathContent);
-
-            // and send it.
-            AdbHelper.write(mChannel, msg, -1, timeOut);
-
-            // read the result, in a byte array containing 2 ints
-            // (id, size)
-            AdbHelper.read(mChannel, pullResult, -1, timeOut);
-
-            // check we have the proper data back
-            if (checkResult(pullResult, ID_DATA) == false &&
-                    checkResult(pullResult, ID_DONE) == false) {
-                return new SyncResult(RESULT_CONNECTION_ERROR);
-            }
-        } catch (UnsupportedEncodingException e) {
-            return new SyncResult(RESULT_REMOTE_PATH_ENCODING, e);
-        } catch (IOException e) {
-            return new SyncResult(RESULT_CONNECTION_ERROR, e);
-        }
-
-        // access the destination file
-        File f = new File(localPath);
-
-        // create the stream to write in the file. We use a new try/catch block to differentiate
-        // between file and network io exceptions.
-        FileOutputStream fos = null;
-        try {
-            fos = new FileOutputStream(f);
-        } catch (FileNotFoundException e) {
-            return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
-        }
-
-        // the buffer to read the data
-        byte[] data = new byte[SYNC_DATA_MAX];
-
-        // loop to get data until we're done.
-        while (true) {
-            // check if we're cancelled
-            if (monitor.isCanceled() == true) {
-                return new SyncResult(RESULT_CANCELED);
-            }
-
-            // if we're done, we stop the loop
-            if (checkResult(pullResult, ID_DONE)) {
-                break;
-            }
-            if (checkResult(pullResult, ID_DATA) == false) {
-                // hmm there's an error
-                return new SyncResult(RESULT_CONNECTION_ERROR);
-            }
-            int length = ArrayHelper.swap32bitFromArray(pullResult, 4);
-            if (length > SYNC_DATA_MAX) {
-                // buffer overrun!
-                // error and exit
-                return new SyncResult(RESULT_BUFFER_OVERRUN);
-            }
-
-            try {
-                // now read the length we received
-                AdbHelper.read(mChannel, data, length, timeOut);
-
-                // get the header for the next packet.
-                AdbHelper.read(mChannel, pullResult, -1, timeOut);
-            } catch (IOException e) {
-                return new SyncResult(RESULT_CONNECTION_ERROR, e);
-            }
-
-            // write the content in the file
-            try {
-                fos.write(data, 0, length);
-            } catch (IOException e) {
-                return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
-            }
-
-            monitor.advance(length);
-        }
-
-        try {
-            fos.flush();
-        } catch (IOException e) {
-            return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
-        }
-        return new SyncResult(RESULT_OK);
-    }
-
-
-    /**
-     * Push multiple files
-     * @param fileArray
-     * @param remotePath
-     * @param monitor
-     * @return a {@link SyncResult} object with a code and an optional message.
-     */
-    private SyncResult doPush(File[] fileArray, String remotePath, ISyncProgressMonitor monitor) {
-        for (File f : fileArray) {
-            // check if we're canceled
-            if (monitor.isCanceled() == true) {
-                return new SyncResult(RESULT_CANCELED);
-            }
-            if (f.exists()) {
-                if (f.isDirectory()) {
-                    // append the name of the directory to the remote path
-                    String dest = remotePath + "/" + f.getName(); // $NON-NLS-1S
-                    monitor.startSubTask(dest);
-                    SyncResult result = doPush(f.listFiles(), dest, monitor);
-
-                    if (result.mCode != RESULT_OK) {
-                        return result;
-                    }
-
-                    monitor.advance(1);
-                } else if (f.isFile()) {
-                    // append the name of the file to the remote path
-                    String remoteFile = remotePath + "/" + f.getName(); // $NON-NLS-1S
-                    monitor.startSubTask(remoteFile);
-                    SyncResult result = doPushFile(f.getAbsolutePath(), remoteFile, monitor);
-                    if (result.mCode != RESULT_OK) {
-                        return result;
-                    }
-                }
-            }
-        }
-
-        return new SyncResult(RESULT_OK);
-    }
-
-    /**
-     * Push a single file
-     * @param localPath the local file to push
-     * @param remotePath the remote file (length max is 1024)
-     * @param monitor the monitor. The monitor must be started already.
-     * @return a {@link SyncResult} object with a code and an optional message.
-     */
-    private SyncResult doPushFile(String localPath, String remotePath,
-            ISyncProgressMonitor monitor) {
-        FileInputStream fis = null;
-        byte[] msg;
-
-        final int timeOut = DdmPreferences.getTimeOut();
-
-        try {
-            byte[] remotePathContent = remotePath.getBytes(AdbHelper.DEFAULT_ENCODING);
-
-            if (remotePathContent.length > REMOTE_PATH_MAX_LENGTH) {
-                return new SyncResult(RESULT_REMOTE_PATH_LENGTH);
-            }
-
-            File f = new File(localPath);
-
-            // this shouldn't happen but still...
-            if (f.exists() == false) {
-                return new SyncResult(RESULT_NO_LOCAL_FILE);
-            }
-
-            // create the stream to read the file
-            fis = new FileInputStream(f);
-
-            // create the header for the action
-            msg = createSendFileReq(ID_SEND, remotePathContent, 0644);
-        } catch (UnsupportedEncodingException e) {
-            return new SyncResult(RESULT_REMOTE_PATH_ENCODING, e);
-        } catch (FileNotFoundException e) {
-            return new SyncResult(RESULT_FILE_READ_ERROR, e);
-        }
-
-        // and send it. We use a custom try/catch block to make the difference between
-        // file and network IO exceptions.
-        try {
-            AdbHelper.write(mChannel, msg, -1, timeOut);
-        } catch (IOException e) {
-            return new SyncResult(RESULT_CONNECTION_ERROR, e);
-        }
-
-        // create the buffer used to read.
-        // we read max SYNC_DATA_MAX, but we need 2 4 bytes at the beginning.
-        if (mBuffer == null) {
-            mBuffer = new byte[SYNC_DATA_MAX + 8];
-        }
-        System.arraycopy(ID_DATA, 0, mBuffer, 0, ID_DATA.length);
-
-        // look while there is something to read
-        while (true) {
-            // check if we're canceled
-            if (monitor.isCanceled() == true) {
-                return new SyncResult(RESULT_CANCELED);
-            }
-
-            // read up to SYNC_DATA_MAX
-            int readCount = 0;
-            try {
-                readCount = fis.read(mBuffer, 8, SYNC_DATA_MAX);
-            } catch (IOException e) {
-                return new SyncResult(RESULT_FILE_READ_ERROR, e);
-            }
-
-            if (readCount == -1) {
-                // we reached the end of the file
-                break;
-            }
-
-            // now send the data to the device
-            // first write the amount read
-            ArrayHelper.swap32bitsToArray(readCount, mBuffer, 4);
-
-            // now write it
-            try {
-                AdbHelper.write(mChannel, mBuffer, readCount+8, timeOut);
-            } catch (IOException e) {
-                return new SyncResult(RESULT_CONNECTION_ERROR, e);
-            }
-
-            // and advance the monitor
-            monitor.advance(readCount);
-        }
-        // close the local file
-        try {
-            fis.close();
-        } catch (IOException e) {
-            return new SyncResult(RESULT_FILE_READ_ERROR, e);
-        }
-
-        try {
-            // create the DONE message
-            long time = System.currentTimeMillis() / 1000;
-            msg = createReq(ID_DONE, (int)time);
-
-            // and send it.
-            AdbHelper.write(mChannel, msg, -1, timeOut);
-
-            // read the result, in a byte array containing 2 ints
-            // (id, size)
-            byte[] result = new byte[8];
-            AdbHelper.read(mChannel, result, -1 /* full length */, timeOut);
-
-            if (checkResult(result, ID_OKAY) == false) {
-                if (checkResult(result, ID_FAIL)) {
-                    // read some error message...
-                    int len = ArrayHelper.swap32bitFromArray(result, 4);
-
-                    AdbHelper.read(mChannel, mBuffer, len, timeOut);
-
-                    // output the result?
-                    String message = new String(mBuffer, 0, len);
-                    Log.e("ddms", "transfer error: " + message);
-                    return new SyncResult(RESULT_UNKNOWN_ERROR, message);
-                }
-
-                return new SyncResult(RESULT_UNKNOWN_ERROR);
-            }
-        } catch (IOException e) {
-            return new SyncResult(RESULT_CONNECTION_ERROR, e);
-        }
-
-        return new SyncResult(RESULT_OK);
-    }
-
-    /**
-     * Returns the mode of the remote file.
-     * @param path the remote file
-     * @return and Integer containing the mode if all went well or null
-     *      otherwise
-     */
-    private Integer readMode(String path) {
-        try {
-            // create the stat request message.
-            byte[] msg = createFileReq(ID_STAT, path);
-
-            AdbHelper.write(mChannel, msg, -1 /* full length */, DdmPreferences.getTimeOut());
-
-            // read the result, in a byte array containing 4 ints
-            // (id, mode, size, time)
-            byte[] statResult = new byte[16];
-            AdbHelper.read(mChannel, statResult, -1 /* full length */, DdmPreferences.getTimeOut());
-
-            // check we have the proper data back
-            if (checkResult(statResult, ID_STAT) == false) {
-                return null;
-            }
-
-            // we return the mode (2nd int in the array)
-            return ArrayHelper.swap32bitFromArray(statResult, 4);
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Create a command with a code and an int values
-     * @param command
-     * @param value
-     * @return
-     */
-    private static byte[] createReq(byte[] command, int value) {
-        byte[] array = new byte[8];
-
-        System.arraycopy(command, 0, array, 0, 4);
-        ArrayHelper.swap32bitsToArray(value, array, 4);
-
-        return array;
-    }
-
-    /**
-     * Creates the data array for a stat request.
-     * @param command the 4 byte command (ID_STAT, ID_RECV, ...)
-     * @param path The path of the remote file on which to execute the command
-     * @return the byte[] to send to the device through adb
-     */
-    private static byte[] createFileReq(byte[] command, String path) {
-        byte[] pathContent = null;
-        try {
-            pathContent = path.getBytes(AdbHelper.DEFAULT_ENCODING);
-        } catch (UnsupportedEncodingException e) {
-            return null;
-        }
-
-        return createFileReq(command, pathContent);
-    }
-
-    /**
-     * Creates the data array for a file request. This creates an array with a 4 byte command + the
-     * remote file name.
-     * @param command the 4 byte command (ID_STAT, ID_RECV, ...).
-     * @param path The path, as a byte array, of the remote file on which to
-     *      execute the command.
-     * @return the byte[] to send to the device through adb
-     */
-    private static byte[] createFileReq(byte[] command, byte[] path) {
-        byte[] array = new byte[8 + path.length];
-
-        System.arraycopy(command, 0, array, 0, 4);
-        ArrayHelper.swap32bitsToArray(path.length, array, 4);
-        System.arraycopy(path, 0, array, 8, path.length);
-
-        return array;
-    }
-
-    private static byte[] createSendFileReq(byte[] command, byte[] path, int mode) {
-        // make the mode into a string
-        String modeStr = "," + (mode & 0777); // $NON-NLS-1S
-        byte[] modeContent = null;
-        try {
-            modeContent = modeStr.getBytes(AdbHelper.DEFAULT_ENCODING);
-        } catch (UnsupportedEncodingException e) {
-            return null;
-        }
-
-        byte[] array = new byte[8 + path.length + modeContent.length];
-
-        System.arraycopy(command, 0, array, 0, 4);
-        ArrayHelper.swap32bitsToArray(path.length + modeContent.length, array, 4);
-        System.arraycopy(path, 0, array, 8, path.length);
-        System.arraycopy(modeContent, 0, array, 8 + path.length, modeContent.length);
-
-        return array;
-
-
-    }
-
-    /**
-     * Checks the result array starts with the provided code
-     * @param result The result array to check
-     * @param code The 4 byte code.
-     * @return true if the code matches.
-     */
-    private static boolean checkResult(byte[] result, byte[] code) {
-        if (result[0] != code[0] ||
-                result[1] != code[1] ||
-                result[2] != code[2] ||
-                result[3] != code[3]) {
-            return false;
-        }
-
-        return true;
-
-    }
-
-    private static int getFileType(int mode) {
-        if ((mode & S_ISOCK) == S_ISOCK) {
-            return FileListingService.TYPE_SOCKET;
-        }
-
-        if ((mode & S_IFLNK) == S_IFLNK) {
-            return FileListingService.TYPE_LINK;
-        }
-
-        if ((mode & S_IFREG) == S_IFREG) {
-            return FileListingService.TYPE_FILE;
-        }
-
-        if ((mode & S_IFBLK) == S_IFBLK) {
-            return FileListingService.TYPE_BLOCK;
-        }
-
-        if ((mode & S_IFDIR) == S_IFDIR) {
-            return FileListingService.TYPE_DIRECTORY;
-        }
-
-        if ((mode & S_IFCHR) == S_IFCHR) {
-            return FileListingService.TYPE_CHARACTER;
-        }
-
-        if ((mode & S_IFIFO) == S_IFIFO) {
-            return FileListingService.TYPE_FIFO;
-        }
-
-        return FileListingService.TYPE_OTHER;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ThreadInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ThreadInfo.java
deleted file mode 100644
index 8f284f3..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ThreadInfo.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.android.ddmlib;
-
-/**
- * Holds a thread information.
- */
-public final class ThreadInfo implements IStackTraceInfo {
-    private int mThreadId;
-    private String mThreadName;
-    private int mStatus;
-    private int mTid;
-    private int mUtime;
-    private int mStime;
-    private boolean mIsDaemon;
-    private StackTraceElement[] mTrace;
-    private long mTraceTime;
-
-    // priority?
-    // total CPU used?
-    // method at top of stack?
-
-    /**
-     * Construct with basic identification.
-     */
-    ThreadInfo(int threadId, String threadName) {
-        mThreadId = threadId;
-        mThreadName = threadName;
-
-        mStatus = -1;
-        //mTid = mUtime = mStime = 0;
-        //mIsDaemon = false;
-    }
-
-    /**
-     * Set with the values we get from a THST chunk.
-     */
-    void updateThread(int status, int tid, int utime, int stime, boolean isDaemon) {
-
-        mStatus = status;
-        mTid = tid;
-        mUtime = utime;
-        mStime = stime;
-        mIsDaemon = isDaemon;
-    }
-    
-    /**
-     * Sets the stack call of the thread.
-     * @param trace stackcall information.
-     */
-    void setStackCall(StackTraceElement[] trace) {
-        mTrace = trace;
-        mTraceTime = System.currentTimeMillis();
-    }
-
-    /**
-     * Returns the thread's ID.
-     */
-    public int getThreadId() {
-        return mThreadId;
-    }
-
-    /**
-     * Returns the thread's name.
-     */
-    public String getThreadName() {
-        return mThreadName;
-    }
-    
-    void setThreadName(String name) {
-        mThreadName = name;
-    }
-
-    /**
-     * Returns the system tid.
-     */
-    public int getTid() {
-        return mTid;
-    }
-
-    /**
-     * Returns the VM thread status.
-     */
-    public int getStatus() {
-        return mStatus;
-    }
-
-    /**
-     * Returns the cumulative user time.
-     */
-    public int getUtime() {
-        return mUtime;
-    }
-
-    /**
-     * Returns the cumulative system time.
-     */
-    public int getStime() {
-        return mStime;
-    }
-
-    /**
-     * Returns whether this is a daemon thread.
-     */
-    public boolean isDaemon() {
-        return mIsDaemon;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.IStackTraceInfo#getStackTrace()
-     */
-    public StackTraceElement[] getStackTrace() {
-        return mTrace;
-    }
-
-    /**
-     * Returns the approximate time of the stacktrace data.
-     * @see #getStackTrace()
-     */
-    public long getStackCallTime() {
-        return mTraceTime;
-    }
-}
-
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventContainer.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventContainer.java
deleted file mode 100644
index ec9186c..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventContainer.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * 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.android.ddmlib.log;
-
-import com.android.ddmlib.log.LogReceiver.LogEntry;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Represents an event and its data.
- */
-public class EventContainer {
-    
-    /**
-     * Comparison method for {@link EventContainer#testValue(int, Object, com.android.ddmlib.log.EventContainer.CompareMethod)}
-     *
-     */
-    public enum CompareMethod {
-        EQUAL_TO("equals", "=="),
-        LESSER_THAN("less than or equals to", "<="),
-        LESSER_THAN_STRICT("less than", "<"),
-        GREATER_THAN("greater than or equals to", ">="),
-        GREATER_THAN_STRICT("greater than", ">"),
-        BIT_CHECK("bit check", "&");
-        
-        private final String mName;
-        private final String mTestString;
-
-        private CompareMethod(String name, String testString) {
-            mName = name;
-            mTestString = testString;
-        }
-
-        /**
-         * Returns the display string.
-         */
-        @Override
-        public String toString() {
-            return mName;
-        }
-
-        /**
-         * Returns a short string representing the comparison.
-         */
-        public String testString() {
-            return mTestString;
-        }
-    }
-
-    
-    /**
-     * Type for event data.
-     */
-    public static enum EventValueType {
-        UNKNOWN(0),
-        INT(1),
-        LONG(2),
-        STRING(3),
-        LIST(4),
-        TREE(5);
-        
-        private final static Pattern STORAGE_PATTERN = Pattern.compile("^(\\d+)@(.*)$"); //$NON-NLS-1$
-        
-        private int mValue;
-        
-        /**
-         * Returns a {@link EventValueType} from an integer value, or <code>null</code> if no match
-         * was found.
-         * @param value the integer value.
-         */
-        static EventValueType getEventValueType(int value) {
-            for (EventValueType type : values()) {
-                if (type.mValue == value) {
-                    return type;
-                }
-            }
-            
-            return null;
-        }
-
-        /**
-         * Returns a storage string for an {@link Object} of type supported by
-         * {@link EventValueType}.
-         * <p/>
-         * Strings created by this method can be reloaded with
-         * {@link #getObjectFromStorageString(String)}.
-         * <p/>
-         * NOTE: for now, only {@link #STRING}, {@link #INT}, and {@link #LONG} are supported.
-         * @param object the object to "convert" into a storage string.
-         * @return a string storing the object and its type or null if the type was not recognized.
-         */
-        public static String getStorageString(Object object) {
-            if (object instanceof String) {
-                return STRING.mValue + "@" + (String)object; //$NON-NLS-1$ 
-            } else if (object instanceof Integer) {
-                return INT.mValue + "@" + object.toString(); //$NON-NLS-1$ 
-            } else if (object instanceof Long) {
-                return LONG.mValue + "@" + object.toString(); //$NON-NLS-1$ 
-            }
-            
-            return null;
-        }
-        
-        /**
-         * Creates an {@link Object} from a storage string created with
-         * {@link #getStorageString(Object)}.
-         * @param value the storage string
-         * @return an {@link Object} or null if the string or type were not recognized.
-         */
-        public static Object getObjectFromStorageString(String value) {
-            Matcher m = STORAGE_PATTERN.matcher(value);
-            if (m.matches()) {
-                try {
-                    EventValueType type = getEventValueType(Integer.parseInt(m.group(1)));
-
-                    if (type == null) {
-                        return null;
-                    }
-                    
-                    switch (type) {
-                        case STRING:
-                            return m.group(2);
-                        case INT:
-                            return Integer.valueOf(m.group(2));
-                        case LONG:
-                            return Long.valueOf(m.group(2));
-                    }
-                } catch (NumberFormatException nfe) {
-                    return null;
-                }
-            }
-            
-            return null;
-        }
-        
-        
-        /**
-         * Returns the integer value of the enum.
-         */
-        public int getValue() {
-            return mValue;
-        }
-
-        @Override
-        public String toString() {
-            return super.toString().toLowerCase();
-        }
-
-        private EventValueType(int value) {
-            mValue = value;
-        }
-    }
-
-    public int mTag;
-    public int pid;    /* generating process's pid */
-    public int tid;    /* generating process's tid */
-    public int sec;    /* seconds since Epoch */
-    public int nsec;   /* nanoseconds */
-
-    private Object mData; 
-
-    /**
-     * Creates an {@link EventContainer} from a {@link LogEntry}.
-     * @param entry  the LogEntry from which pid, tid, and time info is copied.
-     * @param tag the event tag value
-     * @param data the data of the EventContainer.
-     */
-    EventContainer(LogEntry entry, int tag, Object data) {
-        getType(data);
-        mTag = tag;
-        mData = data;
-
-        pid = entry.pid;
-        tid = entry.tid;
-        sec = entry.sec;
-        nsec = entry.nsec;
-    }
-    
-    /**
-     * Creates an {@link EventContainer} with raw data
-     */
-    EventContainer(int tag, int pid, int tid, int sec, int nsec, Object data) {
-        getType(data);
-        mTag = tag;
-        mData = data;
-        
-        this.pid = pid;
-        this.tid = tid;
-        this.sec = sec;
-        this.nsec = nsec;
-    }
-
-    /**
-     * Returns the data as an int.
-     * @throws InvalidTypeException if the data type is not {@link EventValueType#INT}.
-     * @see #getType()
-     */
-    public final Integer getInt() throws InvalidTypeException {
-        if (getType(mData) == EventValueType.INT) {
-            return (Integer)mData;
-        }
-
-        throw new InvalidTypeException();
-    }
-    
-    /**
-     * Returns the data as a long.
-     * @throws InvalidTypeException if the data type is not {@link EventValueType#LONG}. 
-     * @see #getType()
-     */
-    public final Long getLong() throws InvalidTypeException {
-        if (getType(mData) == EventValueType.LONG) {
-            return (Long)mData;
-        }
-
-        throw new InvalidTypeException();
-    }
-
-    /**
-     * Returns the data as a String.
-     * @throws InvalidTypeException if the data type is not {@link EventValueType#STRING}.
-     * @see #getType()
-     */
-    public final String getString() throws InvalidTypeException {
-        if (getType(mData) == EventValueType.STRING) {
-            return (String)mData;
-        }
-
-        throw new InvalidTypeException();
-    }
-    
-    /**
-     * Returns a value by index. The return type is defined by its type.
-     * @param valueIndex the index of the value. If the data is not a list, this is ignored.
-     */
-    public Object getValue(int valueIndex) {
-        return getValue(mData, valueIndex, true);
-    }
-
-    /**
-     * Returns a value by index as a double.
-     * @param valueIndex the index of the value. If the data is not a list, this is ignored.
-     * @throws InvalidTypeException if the data type is not {@link EventValueType#INT},
-     * {@link EventValueType#LONG}, {@link EventValueType#LIST}, or if the item in the
-     * list at index <code>valueIndex</code> is not of type {@link EventValueType#INT} or
-     * {@link EventValueType#LONG}.
-     * @see #getType()
-     */
-    public double getValueAsDouble(int valueIndex) throws InvalidTypeException {
-        return getValueAsDouble(mData, valueIndex, true);
-    }
-
-    /**
-     * Returns a value by index as a String.
-     * @param valueIndex the index of the value. If the data is not a list, this is ignored.
-     * @throws InvalidTypeException if the data type is not {@link EventValueType#INT},
-     * {@link EventValueType#LONG}, {@link EventValueType#STRING}, {@link EventValueType#LIST},
-     * or if the item in the list at index <code>valueIndex</code> is not of type
-     * {@link EventValueType#INT}, {@link EventValueType#LONG}, or {@link EventValueType#STRING}
-     * @see #getType()
-     */
-    public String getValueAsString(int valueIndex) throws InvalidTypeException {
-        return getValueAsString(mData, valueIndex, true);
-    }
-    
-    /**
-     * Returns the type of the data.
-     */
-    public EventValueType getType() {
-        return getType(mData);
-    }
-
-    /**
-     * Returns the type of an object.
-     */
-    public final EventValueType getType(Object data) {
-        if (data instanceof Integer) {
-            return EventValueType.INT;
-        } else if (data instanceof Long) {
-            return EventValueType.LONG;
-        } else if (data instanceof String) {
-            return EventValueType.STRING;
-        } else if (data instanceof Object[]) {
-            // loop through the list to see if we have another list
-            Object[] objects = (Object[])data;
-            for (Object obj : objects) {
-                EventValueType type = getType(obj);
-                if (type == EventValueType.LIST || type == EventValueType.TREE) {
-                    return EventValueType.TREE;
-                }
-            }
-            return EventValueType.LIST;
-        }
-
-        return EventValueType.UNKNOWN;
-    }
-    
-    /**
-     * Checks that the <code>index</code>-th value of this event against a provided value.
-     * @param index the index of the value to test
-     * @param value the value to test against
-     * @param compareMethod the method of testing
-     * @return true if the test passed.
-     * @throws InvalidTypeException in case of type mismatch between the value to test and the value
-     * to test against, or if the compare method is incompatible with the type of the values.
-     * @see CompareMethod
-     */
-    public boolean testValue(int index, Object value,
-            CompareMethod compareMethod) throws InvalidTypeException {
-        EventValueType type = getType(mData);
-        if (index > 0 && type != EventValueType.LIST) {
-            throw new InvalidTypeException();
-        }
-        
-        Object data = mData;
-        if (type == EventValueType.LIST) {
-            data = ((Object[])mData)[index];
-        }
-
-        if (data.getClass().equals(data.getClass()) == false) {
-            throw new InvalidTypeException();
-        }
-
-        switch (compareMethod) {
-            case EQUAL_TO:
-                return data.equals(value);
-            case LESSER_THAN:
-                if (data instanceof Integer) {
-                    return (((Integer)data).compareTo((Integer)value) <= 0);
-                } else if (data instanceof Long) {
-                    return (((Long)data).compareTo((Long)value) <= 0);
-                }
-
-                // other types can't use this compare method.
-                throw new InvalidTypeException();
-            case LESSER_THAN_STRICT:
-                if (data instanceof Integer) {
-                    return (((Integer)data).compareTo((Integer)value) < 0);
-                } else if (data instanceof Long) {
-                    return (((Long)data).compareTo((Long)value) < 0);
-                }
-
-                // other types can't use this compare method.
-                throw new InvalidTypeException();
-            case GREATER_THAN:
-                if (data instanceof Integer) {
-                    return (((Integer)data).compareTo((Integer)value) >= 0);
-                } else if (data instanceof Long) {
-                    return (((Long)data).compareTo((Long)value) >= 0);
-                }
-
-                // other types can't use this compare method.
-                throw new InvalidTypeException();
-            case GREATER_THAN_STRICT:
-                if (data instanceof Integer) {
-                    return (((Integer)data).compareTo((Integer)value) > 0);
-                } else if (data instanceof Long) {
-                    return (((Long)data).compareTo((Long)value) > 0);
-                }
-
-                // other types can't use this compare method.
-                throw new InvalidTypeException();
-            case BIT_CHECK:
-                if (data instanceof Integer) {
-                    return (((Integer)data).intValue() & ((Integer)value).intValue()) != 0;
-                } else if (data instanceof Long) {
-                    return (((Long)data).longValue() & ((Long)value).longValue()) != 0;
-                }
-
-                // other types can't use this compare method.
-                throw new InvalidTypeException();
-            default :
-                throw new InvalidTypeException();
-        }
-    }
-    
-    private final Object getValue(Object data, int valueIndex, boolean recursive) {
-        EventValueType type = getType(data);
-        
-        switch (type) {
-            case INT:
-            case LONG:
-            case STRING:
-                return data;
-            case LIST:
-                if (recursive) {
-                    Object[] list = (Object[]) data;
-                    if (valueIndex >= 0 && valueIndex < list.length) {
-                        return getValue(list[valueIndex], valueIndex, false);
-                    }
-                }
-        }
-        
-        return null;
-    }
-
-    private final double getValueAsDouble(Object data, int valueIndex, boolean recursive)
-            throws InvalidTypeException {
-        EventValueType type = getType(data);
-        
-        switch (type) {
-            case INT:
-                return ((Integer)data).doubleValue();
-            case LONG:
-                return ((Long)data).doubleValue();
-            case STRING:
-                throw new InvalidTypeException();
-            case LIST:
-                if (recursive) {
-                    Object[] list = (Object[]) data;
-                    if (valueIndex >= 0 && valueIndex < list.length) {
-                        return getValueAsDouble(list[valueIndex], valueIndex, false);
-                    }
-                }
-        }
-        
-        throw new InvalidTypeException();
-    }
-
-    private final String getValueAsString(Object data, int valueIndex, boolean recursive)
-            throws InvalidTypeException {
-        EventValueType type = getType(data);
-        
-        switch (type) {
-            case INT:
-                return ((Integer)data).toString();
-            case LONG:
-                return ((Long)data).toString();
-            case STRING:
-                return (String)data;
-            case LIST:
-                if (recursive) {
-                    Object[] list = (Object[]) data;
-                    if (valueIndex >= 0 && valueIndex < list.length) {
-                        return getValueAsString(list[valueIndex], valueIndex, false);
-                    }
-                } else {
-                    throw new InvalidTypeException(
-                            "getValueAsString() doesn't support EventValueType.TREE");
-                }
-        }
-
-        throw new InvalidTypeException(
-                "getValueAsString() unsupported type:" + type);
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java
deleted file mode 100644
index 0b2ce69..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * 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.android.ddmlib.log;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.log.EventContainer.EventValueType;
-import com.android.ddmlib.log.EventValueDescription.ValueType;
-import com.android.ddmlib.log.LogReceiver.LogEntry;
-import com.android.ddmlib.utils.ArrayHelper;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Parser for the "event" log.
- */
-public final class EventLogParser {
-
-    /** Location of the tag map file on the device */
-    private final static String EVENT_TAG_MAP_FILE = "/system/etc/event-log-tags"; //$NON-NLS-1$
-
-    /**
-     * Event log entry types.  These must match up with the declarations in
-     * java/android/android/util/EventLog.java.
-     */
-    private final static int EVENT_TYPE_INT      = 0;
-    private final static int EVENT_TYPE_LONG     = 1;
-    private final static int EVENT_TYPE_STRING   = 2;
-    private final static int EVENT_TYPE_LIST     = 3;
-
-    private final static Pattern PATTERN_SIMPLE_TAG = Pattern.compile(
-    "^(\\d+)\\s+([A-Za-z0-9_]+)\\s*$"); //$NON-NLS-1$
-    private final static Pattern PATTERN_TAG_WITH_DESC = Pattern.compile(
-            "^(\\d+)\\s+([A-Za-z0-9_]+)\\s*(.*)\\s*$"); //$NON-NLS-1$
-    private final static Pattern PATTERN_DESCRIPTION = Pattern.compile(
-            "\\(([A-Za-z0-9_\\s]+)\\|(\\d+)(\\|\\d+){0,1}\\)"); //$NON-NLS-1$
-
-    private final static Pattern TEXT_LOG_LINE = Pattern.compile(
-            "(\\d\\d)-(\\d\\d)\\s(\\d\\d):(\\d\\d):(\\d\\d).(\\d{3})\\s+I/([a-zA-Z0-9_]+)\\s*\\(\\s*(\\d+)\\):\\s+(.*)"); //$NON-NLS-1$
-
-    private final TreeMap<Integer, String> mTagMap = new TreeMap<Integer, String>();
-
-    private final TreeMap<Integer, EventValueDescription[]> mValueDescriptionMap =
-        new TreeMap<Integer, EventValueDescription[]>();
-
-    public EventLogParser() {
-    }
-
-    /**
-     * Inits the parser for a specific Device.
-     * <p/>
-     * This methods reads the event-log-tags located on the device to find out
-     * what tags are being written to the event log and what their format is.
-     * @param device The device.
-     * @return <code>true</code> if success, <code>false</code> if failure or cancellation.
-     */
-    public boolean init(IDevice device) {
-        // read the event tag map file on the device.
-        try {
-            device.executeShellCommand("cat " + EVENT_TAG_MAP_FILE, //$NON-NLS-1$
-                    new MultiLineReceiver() {
-                @Override
-                public void processNewLines(String[] lines) {
-                    for (String line : lines) {
-                        processTagLine(line);
-                    }
-                }
-                public boolean isCancelled() {
-                    return false;
-                }
-            });
-        } catch (IOException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Inits the parser with the content of a tag file.
-     * @param tagFileContent the lines of a tag file.
-     * @return <code>true</code> if success, <code>false</code> if failure.
-     */
-    public boolean init(String[] tagFileContent) {
-        for (String line : tagFileContent) {
-            processTagLine(line);
-        }
-        return true;
-    }
-
-    /**
-     * Inits the parser with a specified event-log-tags file.
-     * @param filePath
-     * @return <code>true</code> if success, <code>false</code> if failure.
-     */
-    public boolean init(String filePath)  {
-        try {
-            BufferedReader reader = new BufferedReader(new FileReader(filePath));
-
-            String line = null;
-            do {
-                line = reader.readLine();
-                if (line != null) {
-                    processTagLine(line);
-                }
-            } while (line != null);
-
-            return true;
-        } catch (IOException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Processes a line from the event-log-tags file.
-     * @param line the line to process
-     */
-    private void processTagLine(String line) {
-        // ignore empty lines and comment lines
-        if (line.length() > 0 && line.charAt(0) != '#') {
-            Matcher m = PATTERN_TAG_WITH_DESC.matcher(line);
-            if (m.matches()) {
-                try {
-                    int value = Integer.parseInt(m.group(1));
-                    String name = m.group(2);
-                    if (name != null && mTagMap.get(value) == null) {
-                        mTagMap.put(value, name);
-                    }
-
-                    // special case for the GC tag. We ignore what is in the file,
-                    // and take what the custom GcEventContainer class tells us.
-                    // This is due to the event encoding several values on 2 longs.
-                    // @see GcEventContainer
-                    if (value == GcEventContainer.GC_EVENT_TAG) {
-                        mValueDescriptionMap.put(value,
-                            GcEventContainer.getValueDescriptions());
-                    } else {
-
-                        String description = m.group(3);
-                        if (description != null && description.length() > 0) {
-                            EventValueDescription[] desc =
-                                processDescription(description);
-
-                            if (desc != null) {
-                                mValueDescriptionMap.put(value, desc);
-                            }
-                        }
-                    }
-                } catch (NumberFormatException e) {
-                    // failed to convert the number into a string. just ignore it.
-                }
-            } else {
-                m = PATTERN_SIMPLE_TAG.matcher(line);
-                if (m.matches()) {
-                    int value = Integer.parseInt(m.group(1));
-                    String name = m.group(2);
-                    if (name != null && mTagMap.get(value) == null) {
-                        mTagMap.put(value, name);
-                    }
-                }
-            }
-        }
-    }
-
-    private EventValueDescription[] processDescription(String description) {
-        String[] descriptions = description.split("\\s*,\\s*"); //$NON-NLS-1$
-
-        ArrayList<EventValueDescription> list = new ArrayList<EventValueDescription>();
-
-        for (String desc : descriptions) {
-            Matcher m = PATTERN_DESCRIPTION.matcher(desc);
-            if (m.matches()) {
-                try {
-                    String name = m.group(1);
-
-                    String typeString = m.group(2);
-                    int typeValue = Integer.parseInt(typeString);
-                    EventValueType eventValueType = EventValueType.getEventValueType(typeValue);
-                    if (eventValueType == null) {
-                        // just ignore this description if the value is not recognized.
-                        // TODO: log the error.
-                    }
-
-                    typeString = m.group(3);
-                    if (typeString != null && typeString.length() > 0) {
-                        //skip the |
-                        typeString = typeString.substring(1);
-
-                        typeValue = Integer.parseInt(typeString);
-                        ValueType valueType = ValueType.getValueType(typeValue);
-
-                        list.add(new EventValueDescription(name, eventValueType, valueType));
-                    } else {
-                        list.add(new EventValueDescription(name, eventValueType));
-                    }
-                } catch (NumberFormatException nfe) {
-                    // just ignore this description if one number is malformed.
-                    // TODO: log the error.
-                } catch (InvalidValueTypeException e) {
-                    // just ignore this description if data type and data unit don't match
-                    // TODO: log the error.
-                }
-            } else {
-                Log.e("EventLogParser",  //$NON-NLS-1$
-                    String.format("Can't parse %1$s", description));  //$NON-NLS-1$
-            }
-        }
-
-        if (list.size() == 0) {
-            return null;
-        }
-
-        return list.toArray(new EventValueDescription[list.size()]);
-
-    }
-
-    public EventContainer parse(LogEntry entry) {
-        if (entry.len < 4) {
-            return null;
-        }
-
-        int inOffset = 0;
-
-        int tagValue = ArrayHelper.swap32bitFromArray(entry.data, inOffset);
-        inOffset += 4;
-
-        String tag = mTagMap.get(tagValue);
-        if (tag == null) {
-            Log.e("EventLogParser", String.format("unknown tag number: %1$d", tagValue));
-        }
-
-        ArrayList<Object> list = new ArrayList<Object>();
-        if (parseBinaryEvent(entry.data, inOffset, list) == -1) {
-            return null;
-        }
-
-        Object data;
-        if (list.size() == 1) {
-            data = list.get(0);
-        } else{
-            data = list.toArray();
-        }
-
-        EventContainer event = null;
-        if (tagValue == GcEventContainer.GC_EVENT_TAG) {
-            event = new GcEventContainer(entry, tagValue, data);
-        } else {
-            event = new EventContainer(entry, tagValue, data);
-        }
-
-        return event;
-    }
-
-    public EventContainer parse(String textLogLine) {
-        // line will look like
-        // 04-29 23:16:16.691 I/dvm_gc_info(  427): <data>
-        // where <data> is either
-        // [value1,value2...]
-        // or
-        // value
-        if (textLogLine.length() == 0) {
-            return null;
-        }
-
-        // parse the header first
-        Matcher m = TEXT_LOG_LINE.matcher(textLogLine);
-        if (m.matches()) {
-            try {
-                int month = Integer.parseInt(m.group(1));
-                int day = Integer.parseInt(m.group(2));
-                int hours = Integer.parseInt(m.group(3));
-                int minutes = Integer.parseInt(m.group(4));
-                int seconds = Integer.parseInt(m.group(5));
-                int milliseconds = Integer.parseInt(m.group(6));
-
-                // convert into seconds since epoch and nano-seconds.
-                Calendar cal = Calendar.getInstance();
-                cal.set(cal.get(Calendar.YEAR), month-1, day, hours, minutes, seconds);
-                int sec = (int)Math.floor(cal.getTimeInMillis()/1000);
-                int nsec = milliseconds * 1000000;
-
-                String tag = m.group(7);
-
-                // get the numerical tag value
-                int tagValue = -1;
-                Set<Entry<Integer, String>> tagSet = mTagMap.entrySet();
-                for (Entry<Integer, String> entry : tagSet) {
-                    if (tag.equals(entry.getValue())) {
-                        tagValue = entry.getKey();
-                        break;
-                    }
-                }
-
-                if (tagValue == -1) {
-                    return null;
-                }
-
-                int pid = Integer.parseInt(m.group(8));
-
-                Object data = parseTextData(m.group(9), tagValue);
-                if (data == null) {
-                    return null;
-                }
-
-                // now we can allocate and return the EventContainer
-                EventContainer event = null;
-                if (tagValue == GcEventContainer.GC_EVENT_TAG) {
-                    event = new GcEventContainer(tagValue, pid, -1 /* tid */, sec, nsec, data);
-                } else {
-                    event = new EventContainer(tagValue, pid, -1 /* tid */, sec, nsec, data);
-                }
-
-                return event;
-            } catch (NumberFormatException e) {
-                return null;
-            }
-        }
-
-        return null;
-    }
-
-    public Map<Integer, String> getTagMap() {
-        return mTagMap;
-    }
-
-    public Map<Integer, EventValueDescription[]> getEventInfoMap() {
-        return mValueDescriptionMap;
-    }
-
-    /**
-     * Recursively convert binary log data to printable form.
-     *
-     * This needs to be recursive because you can have lists of lists.
-     *
-     * If we run out of room, we stop processing immediately.  It's important
-     * for us to check for space on every output element to avoid producing
-     * garbled output.
-     *
-     * Returns the amount read on success, -1 on failure.
-     */
-    private static int parseBinaryEvent(byte[] eventData, int dataOffset, ArrayList<Object> list) {
-
-        if (eventData.length - dataOffset < 1)
-            return -1;
-
-        int offset = dataOffset;
-
-        int type = eventData[offset++];
-
-        //fprintf(stderr, "--- type=%d (rem len=%d)\n", type, eventDataLen);
-
-        switch (type) {
-        case EVENT_TYPE_INT: { /* 32-bit signed int */
-                int ival;
-
-                if (eventData.length - offset < 4)
-                    return -1;
-                ival = ArrayHelper.swap32bitFromArray(eventData, offset);
-                offset += 4;
-
-                list.add(new Integer(ival));
-            }
-            break;
-        case EVENT_TYPE_LONG: { /* 64-bit signed long */
-                long lval;
-
-                if (eventData.length - offset < 8)
-                    return -1;
-                lval = ArrayHelper.swap64bitFromArray(eventData, offset);
-                offset += 8;
-
-                list.add(new Long(lval));
-            }
-            break;
-        case EVENT_TYPE_STRING: { /* UTF-8 chars, not NULL-terminated */
-                int strLen;
-
-                if (eventData.length - offset < 4)
-                    return -1;
-                strLen = ArrayHelper.swap32bitFromArray(eventData, offset);
-                offset += 4;
-
-                if (eventData.length - offset < strLen)
-                    return -1;
-
-                // get the string
-                try {
-                    String str = new String(eventData, offset, strLen, "UTF-8"); //$NON-NLS-1$
-                    list.add(str);
-                } catch (UnsupportedEncodingException e) {
-                }
-                offset += strLen;
-                break;
-            }
-        case EVENT_TYPE_LIST: { /* N items, all different types */
-
-                if (eventData.length - offset < 1)
-                    return -1;
-
-                int count = eventData[offset++];
-
-                // make a new temp list
-                ArrayList<Object> subList = new ArrayList<Object>();
-                for (int i = 0; i < count; i++) {
-                    int result = parseBinaryEvent(eventData, offset, subList);
-                    if (result == -1) {
-                        return result;
-                    }
-
-                    offset += result;
-                }
-
-                list.add(subList.toArray());
-            }
-            break;
-        default:
-            Log.e("EventLogParser",  //$NON-NLS-1$
-                    String.format("Unknown binary event type %1$d", type));  //$NON-NLS-1$
-            return -1;
-        }
-
-        return offset - dataOffset;
-    }
-
-    private Object parseTextData(String data, int tagValue) {
-        // first, get the description of what we're supposed to parse
-        EventValueDescription[] desc = mValueDescriptionMap.get(tagValue);
-
-        if (desc == null) {
-            // TODO parse and create string values.
-            return null;
-        }
-
-        if (desc.length == 1) {
-            return getObjectFromString(data, desc[0].getEventValueType());
-        } else if (data.startsWith("[") && data.endsWith("]")) {
-            data = data.substring(1, data.length() - 1);
-
-            // get each individual values as String
-            String[] values = data.split(",");
-
-            if (tagValue == GcEventContainer.GC_EVENT_TAG) {
-                // special case for the GC event!
-                Object[] objects = new Object[2];
-
-                objects[0] = getObjectFromString(values[0], EventValueType.LONG);
-                objects[1] = getObjectFromString(values[1], EventValueType.LONG);
-
-                return objects;
-            } else {
-                // must be the same number as the number of descriptors.
-                if (values.length != desc.length) {
-                    return null;
-                }
-
-                Object[] objects = new Object[values.length];
-
-                for (int i = 0 ; i < desc.length ; i++) {
-                    Object obj = getObjectFromString(values[i], desc[i].getEventValueType());
-                    if (obj == null) {
-                        return null;
-                    }
-                    objects[i] = obj;
-                }
-
-                return objects;
-            }
-        }
-
-        return null;
-    }
-
-
-    private Object getObjectFromString(String value, EventValueType type) {
-        try {
-            switch (type) {
-                case INT:
-                    return Integer.valueOf(value);
-                case LONG:
-                    return Long.valueOf(value);
-                case STRING:
-                    return value;
-            }
-        } catch (NumberFormatException e) {
-            // do nothing, we'll return null.
-        }
-
-        return null;
-    }
-
-    /**
-     * Recreates the event-log-tags at the specified file path.
-     * @param filePath the file path to write the file.
-     * @throws IOException
-     */
-    public void saveTags(String filePath) throws IOException {
-        File destFile = new File(filePath);
-        destFile.createNewFile();
-        FileOutputStream fos = null;
-
-        try {
-
-            fos = new FileOutputStream(destFile);
-
-            for (Integer key : mTagMap.keySet()) {
-                // get the tag name
-                String tagName = mTagMap.get(key);
-
-                // get the value descriptions
-                EventValueDescription[] descriptors = mValueDescriptionMap.get(key);
-
-                String line = null;
-                if (descriptors != null) {
-                    StringBuilder sb = new StringBuilder();
-                    sb.append(String.format("%1$d %2$s", key, tagName)); //$NON-NLS-1$
-                    boolean first = true;
-                    for (EventValueDescription evd : descriptors) {
-                        if (first) {
-                            sb.append(" ("); //$NON-NLS-1$
-                            first = false;
-                        } else {
-                            sb.append(",("); //$NON-NLS-1$
-                        }
-                        sb.append(evd.getName());
-                        sb.append("|"); //$NON-NLS-1$
-                        sb.append(evd.getEventValueType().getValue());
-                        sb.append("|"); //$NON-NLS-1$
-                        sb.append(evd.getValueType().getValue());
-                        sb.append("|)"); //$NON-NLS-1$
-                    }
-                    sb.append("\n"); //$NON-NLS-1$
-
-                    line = sb.toString();
-                } else {
-                    line = String.format("%1$d %2$s\n", key, tagName); //$NON-NLS-1$
-                }
-
-                byte[] buffer = line.getBytes();
-                fos.write(buffer);
-            }
-        } finally {
-            if (fos != null) {
-                fos.close();
-            }
-        }
-    }
-
-
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventValueDescription.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventValueDescription.java
deleted file mode 100644
index b68b4e8..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventValueDescription.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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.android.ddmlib.log;
-
-import com.android.ddmlib.log.EventContainer.EventValueType;
-
-
-/**
- * Describes an {@link EventContainer} value.
- * <p/>
- * This is a stand-alone object, not linked to a particular Event. It describes the value, by
- * name, type ({@link EventValueType}), and (if needed) value unit ({@link ValueType}).
- * <p/>
- * The index of the value is not contained within this class, and is instead dependent on the
- * index of this particular object in the array of {@link EventValueDescription} returned by
- * {@link EventLogParser#getEventInfoMap()} when queried for a particular event tag.
- * 
- */
-public final class EventValueDescription {
-    
-    /**
-     * Represents the type of a numerical value. This is used to display values of vastly different
-     * type/range in graphs. 
-     */
-    public static enum ValueType {
-        NOT_APPLICABLE(0),
-        OBJECTS(1),
-        BYTES(2),
-        MILLISECONDS(3),
-        ALLOCATIONS(4),
-        ID(5),
-        PERCENT(6);
-
-        private int mValue;
-
-        /**
-         * Checks that the {@link EventValueType} is compatible with the {@link ValueType}.
-         * @param type the {@link EventValueType} to check.
-         * @throws InvalidValueTypeException if the types are not compatible.
-         */
-        public void checkType(EventValueType type) throws InvalidValueTypeException {
-            if ((type != EventValueType.INT && type != EventValueType.LONG)
-                    && this != NOT_APPLICABLE) {
-                throw new InvalidValueTypeException(
-                        String.format("%1$s doesn't support type %2$s", type, this));
-            }
-        }
-
-        /**
-         * Returns a {@link ValueType} from an integer value, or <code>null</code> if no match
-         * were found.
-         * @param value the integer value.
-         */
-        public static ValueType getValueType(int value) {
-            for (ValueType type : values()) {
-                if (type.mValue == value) {
-                    return type;
-                }
-            }
-            return null;
-        }
-
-        /**
-         * Returns the integer value of the enum.
-         */
-        public int getValue() {
-            return mValue;
-        }
-        
-        @Override
-        public String toString() {
-            return super.toString().toLowerCase();
-        }
-        
-        private ValueType(int value) {
-            mValue = value;
-        }
-    }
-    
-    private String mName;
-    private EventValueType mEventValueType;
-    private ValueType mValueType;
-    
-    /**
-     * Builds a {@link EventValueDescription} with a name and a type.
-     * <p/>
-     * If the type is {@link EventValueType#INT} or {@link EventValueType#LONG}, the
-     * {@link #mValueType} is set to {@link ValueType#BYTES} by default. It set to
-     * {@link ValueType#NOT_APPLICABLE} for all other {@link EventValueType} values.
-     * @param name
-     * @param type
-     */
-    EventValueDescription(String name, EventValueType type) {
-        mName = name;
-        mEventValueType = type;
-        if (mEventValueType == EventValueType.INT || mEventValueType == EventValueType.LONG) {
-            mValueType = ValueType.BYTES;
-        } else {
-            mValueType = ValueType.NOT_APPLICABLE;
-        }
-    }
-
-    /**
-     * Builds a {@link EventValueDescription} with a name and a type, and a {@link ValueType}.
-     * <p/>
-     * @param name
-     * @param type
-     * @param valueType
-     * @throws InvalidValueTypeException if type and valuetype are not compatible.
-     * 
-     */
-    EventValueDescription(String name, EventValueType type, ValueType valueType)
-            throws InvalidValueTypeException {
-        mName = name;
-        mEventValueType = type;
-        mValueType = valueType;
-        mValueType.checkType(mEventValueType);
-    }
-    
-    /**
-     * @return the Name.
-     */
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * @return the {@link EventValueType}.
-     */
-    public EventValueType getEventValueType() {
-        return mEventValueType;
-    }
-
-    /**
-     * @return the {@link ValueType}.
-     */
-    public ValueType getValueType() {
-        return mValueType;
-    }
-    
-    @Override
-    public String toString() {
-        if (mValueType != ValueType.NOT_APPLICABLE) {
-            return String.format("%1$s (%2$s, %3$s)", mName, mEventValueType.toString(),
-                    mValueType.toString());
-        }
-        
-        return String.format("%1$s (%2$s)", mName, mEventValueType.toString());
-    }
-
-    /**
-     * Checks if the value is of the proper type for this receiver.
-     * @param value the value to check.
-     * @return true if the value is of the proper type for this receiver.
-     */
-    public boolean checkForType(Object value) {
-        switch (mEventValueType) {
-            case INT:
-                return value instanceof Integer;
-            case LONG:
-                return value instanceof Long;
-            case STRING:
-                return value instanceof String;
-            case LIST:
-                return value instanceof Object[];
-        }
-        
-        return false;
-    }
-    
-    /**
-     * Returns an object of a valid type (based on the value returned by
-     * {@link #getEventValueType()}) from a String value.
-     * <p/>
-     * IMPORTANT {@link EventValueType#LIST} and {@link EventValueType#TREE} are not
-     * supported.
-     * @param value the value of the object expressed as a string.
-     * @return an object or null if the conversion could not be done.
-     */
-    public Object getObjectFromString(String value) {
-        switch (mEventValueType) {
-            case INT:
-                try {
-                    return Integer.valueOf(value);
-                } catch (NumberFormatException e) {
-                    return null;
-                }
-            case LONG:
-                try {
-                    return Long.valueOf(value);
-                } catch (NumberFormatException e) {
-                    return null;
-                }
-            case STRING:
-                return value;
-        }
-        
-        return null;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/GcEventContainer.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/GcEventContainer.java
deleted file mode 100644
index 7bae202..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/GcEventContainer.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * 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.android.ddmlib.log;
-
-import com.android.ddmlib.log.EventValueDescription.ValueType;
-import com.android.ddmlib.log.LogReceiver.LogEntry;
-
-/**
- * Custom Event Container for the Gc event since this event doesn't simply output data in
- * int or long format, but encodes several values on 4 longs.
- * <p/>
- * The array of {@link EventValueDescription}s parsed from the "event-log-tags" file must
- * be ignored, and instead, the array returned from {@link #getValueDescriptions()} must be used. 
- */
-final class GcEventContainer extends EventContainer {
-    
-    public final static int GC_EVENT_TAG = 20001;
-
-    private String processId;
-    private long gcTime;
-    private long bytesFreed;
-    private long objectsFreed;
-    private long actualSize;
-    private long allowedSize;
-    private long softLimit;
-    private long objectsAllocated;
-    private long bytesAllocated;
-    private long zActualSize;
-    private long zAllowedSize;
-    private long zObjectsAllocated;
-    private long zBytesAllocated;
-    private long dlmallocFootprint;
-    private long mallinfoTotalAllocatedSpace;
-    private long externalLimit;
-    private long externalBytesAllocated;
-
-    GcEventContainer(LogEntry entry, int tag, Object data) {
-        super(entry, tag, data);
-        init(data);
-    }
-
-    GcEventContainer(int tag, int pid, int tid, int sec, int nsec, Object data) {
-        super(tag, pid, tid, sec, nsec, data);
-        init(data);
-    }
-
-    /**
-     * @param data
-     */
-    private void init(Object data) {
-        if (data instanceof Object[]) {
-            Object[] values = (Object[])data;
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] instanceof Long) {
-                    parseDvmHeapInfo((Long)values[i], i);
-                }
-            }
-        }
-    }
-    
-    @Override
-    public EventValueType getType() {
-        return EventValueType.LIST;
-    }
-
-    @Override
-    public boolean testValue(int index, Object value, CompareMethod compareMethod)
-            throws InvalidTypeException {
-        // do a quick easy check on the type.
-        if (index == 0) {
-            if ((value instanceof String) == false) {
-                throw new InvalidTypeException();
-            }
-        } else if ((value instanceof Long) == false) {
-            throw new InvalidTypeException();
-        }
-        
-        switch (compareMethod) {
-            case EQUAL_TO:
-                if (index == 0) {
-                    return processId.equals(value);
-                } else {
-                    return getValueAsLong(index) == ((Long)value).longValue();
-                }
-            case LESSER_THAN:
-                return getValueAsLong(index) <= ((Long)value).longValue();
-            case LESSER_THAN_STRICT:
-                return getValueAsLong(index) < ((Long)value).longValue();
-            case GREATER_THAN:
-                return getValueAsLong(index) >= ((Long)value).longValue();
-            case GREATER_THAN_STRICT:
-                return getValueAsLong(index) > ((Long)value).longValue();
-            case BIT_CHECK:
-                return (getValueAsLong(index) & ((Long)value).longValue()) != 0;
-        }
-
-        throw new ArrayIndexOutOfBoundsException();
-    }
-
-    @Override
-    public Object getValue(int valueIndex) {
-        if (valueIndex == 0) {
-            return processId;
-        }
-        
-        try {
-            return new Long(getValueAsLong(valueIndex));
-        } catch (InvalidTypeException e) {
-            // this would only happened if valueIndex was 0, which we test above.
-        }
-        
-        return null;
-    }
-
-    @Override
-    public double getValueAsDouble(int valueIndex) throws InvalidTypeException {
-        return (double)getValueAsLong(valueIndex);
-    }
-
-    @Override
-    public String getValueAsString(int valueIndex) {
-        switch (valueIndex) {
-            case 0:
-                return processId;
-            default:
-                try {
-                    return Long.toString(getValueAsLong(valueIndex));
-                } catch (InvalidTypeException e) {
-                    // we shouldn't stop there since we test, in this method first.
-                }
-        }
-
-        throw new ArrayIndexOutOfBoundsException();
-    }
-    
-    /**
-     * Returns a custom array of {@link EventValueDescription} since the actual content of this
-     * event (list of (long, long) does not match the values encoded into those longs.
-     */
-    static EventValueDescription[] getValueDescriptions() {
-        try {
-            return new EventValueDescription[] {
-                    new EventValueDescription("Process Name", EventValueType.STRING),
-                    new EventValueDescription("GC Time", EventValueType.LONG,
-                            ValueType.MILLISECONDS),
-                    new EventValueDescription("Freed Objects", EventValueType.LONG,
-                            ValueType.OBJECTS),
-                    new EventValueDescription("Freed Bytes", EventValueType.LONG, ValueType.BYTES),
-                    new EventValueDescription("Soft Limit", EventValueType.LONG, ValueType.BYTES),
-                    new EventValueDescription("Actual Size (aggregate)", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("Allowed Size (aggregate)", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("Allocated Objects (aggregate)",
-                            EventValueType.LONG, ValueType.OBJECTS),
-                    new EventValueDescription("Allocated Bytes (aggregate)", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("Actual Size", EventValueType.LONG, ValueType.BYTES),
-                    new EventValueDescription("Allowed Size", EventValueType.LONG, ValueType.BYTES),
-                    new EventValueDescription("Allocated Objects", EventValueType.LONG,
-                            ValueType.OBJECTS),
-                    new EventValueDescription("Allocated Bytes", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("Actual Size (zygote)", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("Allowed Size (zygote)", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("Allocated Objects (zygote)", EventValueType.LONG,
-                            ValueType.OBJECTS),
-                    new EventValueDescription("Allocated Bytes (zygote)", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("External Allocation Limit", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("External Bytes Allocated", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("dlmalloc Footprint", EventValueType.LONG,
-                            ValueType.BYTES),
-                    new EventValueDescription("Malloc Info: Total Allocated Space",
-                            EventValueType.LONG, ValueType.BYTES),
-                  };
-        } catch (InvalidValueTypeException e) {
-            // this shouldn't happen since we control manual the EventValueType and the ValueType
-            // values. For development purpose, we assert if this happens.
-            assert false;
-        }
-
-        // this shouldn't happen, but the compiler complains otherwise.
-        return null;
-    }
-
-    private void parseDvmHeapInfo(long data, int index) {
-        switch (index) {
-            case 0:
-                //    [63   ] Must be zero
-                //    [62-24] ASCII process identifier
-                //    [23-12] GC time in ms
-                //    [11- 0] Bytes freed
-                
-                gcTime = float12ToInt((int)((data >> 12) & 0xFFFL));
-                bytesFreed = float12ToInt((int)(data & 0xFFFL));
-                
-                // convert the long into an array, in the proper order so that we can convert the
-                // first 5 char into a string.
-                byte[] dataArray = new byte[8];
-                put64bitsToArray(data, dataArray, 0);
-                
-                // get the name from the string
-                processId = new String(dataArray, 0, 5);
-                break;
-            case 1:
-                //    [63-62] 10
-                //    [61-60] Reserved; must be zero
-                //    [59-48] Objects freed
-                //    [47-36] Actual size (current footprint)
-                //    [35-24] Allowed size (current hard max)
-                //    [23-12] Objects allocated
-                //    [11- 0] Bytes allocated
-                objectsFreed = float12ToInt((int)((data >> 48) & 0xFFFL));
-                actualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
-                allowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
-                objectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
-                bytesAllocated = float12ToInt((int)(data & 0xFFFL));
-                break;
-            case 2:
-                //    [63-62] 11
-                //    [61-60] Reserved; must be zero
-                //    [59-48] Soft limit (current soft max)
-                //    [47-36] Actual size (current footprint)
-                //    [35-24] Allowed size (current hard max)
-                //    [23-12] Objects allocated
-                //    [11- 0] Bytes allocated
-                softLimit = float12ToInt((int)((data >> 48) & 0xFFFL));
-                zActualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
-                zAllowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
-                zObjectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
-                zBytesAllocated = float12ToInt((int)(data & 0xFFFL));
-                break;
-            case 3:
-                //    [63-48] Reserved; must be zero
-                //    [47-36] dlmallocFootprint
-                //    [35-24] mallinfo: total allocated space
-                //    [23-12] External byte limit
-                //    [11- 0] External bytes allocated
-                dlmallocFootprint = float12ToInt((int)((data >> 36) & 0xFFFL));
-                mallinfoTotalAllocatedSpace = float12ToInt((int)((data >> 24) & 0xFFFL));
-                externalLimit = float12ToInt((int)((data >> 12) & 0xFFFL));
-                externalBytesAllocated = float12ToInt((int)(data & 0xFFFL));
-                break;
-            default:
-                break;
-        }
-    }
-    
-    /**
-     * Converts a 12 bit float representation into an unsigned int (returned as a long)
-     * @param f12
-     */
-    private static long float12ToInt(int f12) {
-        return (f12 & 0x1FF) << ((f12 >>> 9) * 4);
-    }
-    
-    /**
-     * puts an unsigned value in an array.
-     * @param value The value to put.
-     * @param dest the destination array
-     * @param offset the offset in the array where to put the value.
-     *      Array length must be at least offset + 8
-     */
-    private static void put64bitsToArray(long value, byte[] dest, int offset) {
-        dest[offset + 7] = (byte)(value & 0x00000000000000FFL);
-        dest[offset + 6] = (byte)((value & 0x000000000000FF00L) >> 8);
-        dest[offset + 5] = (byte)((value & 0x0000000000FF0000L) >> 16);
-        dest[offset + 4] = (byte)((value & 0x00000000FF000000L) >> 24);
-        dest[offset + 3] = (byte)((value & 0x000000FF00000000L) >> 32);
-        dest[offset + 2] = (byte)((value & 0x0000FF0000000000L) >> 40);
-        dest[offset + 1] = (byte)((value & 0x00FF000000000000L) >> 48);
-        dest[offset + 0] = (byte)((value & 0xFF00000000000000L) >> 56);
-    }
-    
-    /**
-     * Returns the long value of the <code>valueIndex</code>-th value.
-     * @param valueIndex the index of the value.
-     * @throws InvalidTypeException if index is 0 as it is a string value.
-     */
-    private final long getValueAsLong(int valueIndex) throws InvalidTypeException {
-        switch (valueIndex) {
-            case 0:
-                throw new InvalidTypeException();
-            case 1:
-                return gcTime;
-            case 2:
-                return objectsFreed;
-            case 3:
-                return bytesFreed;
-            case 4:
-                return softLimit;
-            case 5:
-                return actualSize;
-            case 6:
-                return allowedSize;
-            case 7:
-                return objectsAllocated;
-            case 8:
-                return bytesAllocated;
-            case 9:
-                return actualSize - zActualSize;
-            case 10:
-                return allowedSize - zAllowedSize;
-            case 11:
-                return objectsAllocated - zObjectsAllocated;
-            case 12:
-                return bytesAllocated - zBytesAllocated;
-            case 13:
-               return zActualSize;
-            case 14:
-                return zAllowedSize;
-            case 15:
-                return zObjectsAllocated;
-            case 16:
-                return zBytesAllocated;
-            case 17:
-                return externalLimit;
-            case 18:
-                return externalBytesAllocated;
-            case 19:
-                return dlmallocFootprint;
-            case 20:
-                return mallinfoTotalAllocatedSpace;
-        }
-
-        throw new ArrayIndexOutOfBoundsException();
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidTypeException.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidTypeException.java
deleted file mode 100644
index 016f8aa..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidTypeException.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.android.ddmlib.log;
-
-import java.io.Serializable;
-
-/**
- * Exception thrown when accessing an {@link EventContainer} value with the wrong type.
- */
-public final class InvalidTypeException extends Exception {
-
-    /**
-     * Needed by {@link Serializable}.
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Constructs a new exception with the default detail message.
-     * @see java.lang.Exception
-     */
-    public InvalidTypeException() {
-        super("Invalid Type");
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message.
-     * @param message the detail message. The detail message is saved for later retrieval
-     * by the {@link Throwable#getMessage()} method.
-     * @see java.lang.Exception
-     */
-    public InvalidTypeException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new exception with the specified cause and a detail message of
-     * <code>(cause==null ? null : cause.toString())</code> (which typically contains
-     * the class and detail message of cause).
-     * @param cause the cause (which is saved for later retrieval by the
-     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
-     * and indicates that the cause is nonexistent or unknown.)
-     * @see java.lang.Exception
-     */
-    public InvalidTypeException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message and cause.
-     * @param message the detail message. The detail message is saved for later retrieval
-     * by the {@link Throwable#getMessage()} method.
-     * @param cause the cause (which is saved for later retrieval by the
-     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
-     * and indicates that the cause is nonexistent or unknown.)
-     * @see java.lang.Exception
-     */
-    public InvalidTypeException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidValueTypeException.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidValueTypeException.java
deleted file mode 100644
index a3050c8..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidValueTypeException.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.android.ddmlib.log;
-
-import com.android.ddmlib.log.EventContainer.EventValueType;
-import com.android.ddmlib.log.EventValueDescription.ValueType;
-
-import java.io.Serializable;
-
-/**
- * Exception thrown when associating an {@link EventValueType} with an incompatible
- * {@link ValueType}.
- */
-public final class InvalidValueTypeException extends Exception {
-
-    /**
-     * Needed by {@link Serializable}.
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Constructs a new exception with the default detail message.
-     * @see java.lang.Exception
-     */
-    public InvalidValueTypeException() {
-        super("Invalid Type");
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message.
-     * @param message the detail message. The detail message is saved for later retrieval
-     * by the {@link Throwable#getMessage()} method.
-     * @see java.lang.Exception
-     */
-    public InvalidValueTypeException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new exception with the specified cause and a detail message of
-     * <code>(cause==null ? null : cause.toString())</code> (which typically contains
-     * the class and detail message of cause).
-     * @param cause the cause (which is saved for later retrieval by the
-     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
-     * and indicates that the cause is nonexistent or unknown.)
-     * @see java.lang.Exception
-     */
-    public InvalidValueTypeException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message and cause.
-     * @param message the detail message. The detail message is saved for later retrieval
-     * by the {@link Throwable#getMessage()} method.
-     * @param cause the cause (which is saved for later retrieval by the
-     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
-     * and indicates that the cause is nonexistent or unknown.)
-     * @see java.lang.Exception
-     */
-    public InvalidValueTypeException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/LogReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/LogReceiver.java
deleted file mode 100644
index b49f025..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/LogReceiver.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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.android.ddmlib.log;
-
-
-import com.android.ddmlib.utils.ArrayHelper;
-
-import java.security.InvalidParameterException;
-
-/**
- * Receiver able to provide low level parsing for device-side log services.
- */
-public final class LogReceiver {
-
-    private final static int ENTRY_HEADER_SIZE = 20; // 2*2 + 4*4; see LogEntry.
-
-    /**
-     * Represents a log entry and its raw data.
-     */
-    public final static class LogEntry {
-        /*
-         * See //device/include/utils/logger.h
-         */
-        /** 16bit unsigned: length of the payload. */
-        public int  len; /* This is normally followed by a 16 bit padding */
-        /** pid of the process that generated this {@link LogEntry} */
-        public int   pid;
-        /** tid of the process that generated this {@link LogEntry} */
-        public int   tid;
-        /** Seconds since epoch. */
-        public int   sec;
-        /** nanoseconds. */
-        public int   nsec;
-        /** The entry's raw data. */
-        public byte[] data;
-    };
-
-    /**
-     * Classes which implement this interface provide a method that deals
-     * with {@link LogEntry} objects coming from log service through a {@link LogReceiver}.
-     * <p/>This interface provides two methods.
-     * <ul>
-     * <li>{@link #newEntry(com.android.ddmlib.log.LogReceiver.LogEntry)} provides a
-     * first level of parsing, extracting {@link LogEntry} objects out of the log service output.</li>
-     * <li>{@link #newData(byte[], int, int)} provides a way to receive the raw information
-     * coming directly from the log service.</li>
-     * </ul>
-     */
-    public interface ILogListener {
-        /**
-         * Sent when a new {@link LogEntry} has been parsed by the {@link LogReceiver}.
-         * @param entry the new log entry.
-         */
-        public void newEntry(LogEntry entry);
-        
-        /**
-         * Sent when new raw data is coming from the log service.
-         * @param data the raw data buffer.
-         * @param offset the offset into the buffer signaling the beginning of the new data.
-         * @param length the length of the new data.
-         */
-        public void newData(byte[] data, int offset, int length);
-    }
-
-    /** Current {@link LogEntry} being read, before sending it to the listener. */
-    private LogEntry mCurrentEntry;
-
-    /** Temp buffer to store partial entry headers. */
-    private byte[] mEntryHeaderBuffer = new byte[ENTRY_HEADER_SIZE];
-    /** Offset in the partial header buffer */
-    private int mEntryHeaderOffset = 0;
-    /** Offset in the partial entry data */
-    private int mEntryDataOffset = 0;
-    
-    /** Listener waiting for receive fully read {@link LogEntry} objects */
-    private ILogListener mListener;
-
-    private boolean mIsCancelled = false;
-    
-    /**
-     * Creates a {@link LogReceiver} with an {@link ILogListener}.
-     * <p/>
-     * The {@link ILogListener} will receive new log entries as they are parsed, in the form 
-     * of {@link LogEntry} objects.
-     * @param listener the listener to receive new log entries.
-     */
-    public LogReceiver(ILogListener listener) {
-        mListener = listener;
-    }
-    
-
-    /**
-     * Parses new data coming from the log service.
-     * @param data the data buffer
-     * @param offset the offset into the buffer signaling the beginning of the new data.
-     * @param length the length of the new data.
-     */
-    public void parseNewData(byte[] data, int offset, int length) {
-        // notify the listener of new raw data
-        if (mListener != null) {
-            mListener.newData(data, offset, length);
-        }
-
-        // loop while there is still data to be read and the receiver has not be cancelled.
-        while (length > 0 && mIsCancelled == false) {
-            // first check if we have no current entry.
-            if (mCurrentEntry == null) {
-                if (mEntryHeaderOffset + length < ENTRY_HEADER_SIZE) {
-                    // if we don't have enough data to finish the header, save
-                    // the data we have and return
-                    System.arraycopy(data, offset, mEntryHeaderBuffer, mEntryHeaderOffset, length);
-                    mEntryHeaderOffset += length;
-                    return;
-                } else {
-                    // we have enough to fill the header, let's do it.
-                    // did we store some part at the beginning of the header?
-                    if (mEntryHeaderOffset != 0) {
-                        // copy the rest of the entry header into the header buffer
-                        int size = ENTRY_HEADER_SIZE - mEntryHeaderOffset; 
-                        System.arraycopy(data, offset, mEntryHeaderBuffer, mEntryHeaderOffset,
-                                size);
-                        
-                        // create the entry from the header buffer
-                        mCurrentEntry = createEntry(mEntryHeaderBuffer, 0);
-    
-                        // since we used the whole entry header buffer, we reset  the offset
-                        mEntryHeaderOffset = 0;
-                        
-                        // adjust current offset and remaining length to the beginning
-                        // of the entry data
-                        offset += size;
-                        length -= size;
-                    } else {
-                        // create the entry directly from the data array
-                        mCurrentEntry = createEntry(data, offset);
-                        
-                        // adjust current offset and remaining length to the beginning
-                        // of the entry data
-                        offset += ENTRY_HEADER_SIZE;
-                        length -= ENTRY_HEADER_SIZE;
-                    }
-                }
-            }
-            
-            // at this point, we have an entry, and offset/length have been updated to skip
-            // the entry header.
-    
-            // if we have enough data for this entry or more, we'll need to end this entry
-            if (length >= mCurrentEntry.len - mEntryDataOffset) {
-                // compute and save the size of the data that we have to read for this entry,
-                // based on how much we may already have read.
-                int dataSize = mCurrentEntry.len - mEntryDataOffset;  
-    
-                // we only read what we need, and put it in the entry buffer.
-                System.arraycopy(data, offset, mCurrentEntry.data, mEntryDataOffset, dataSize);
-                
-                // notify the listener of a new entry
-                if (mListener != null) {
-                    mListener.newEntry(mCurrentEntry);
-                }
-    
-                // reset some flags: we have read 0 data of the current entry.
-                // and we have no current entry being read.
-                mEntryDataOffset = 0;
-                mCurrentEntry = null;
-                
-                // and update the data buffer info to the end of the current entry / start
-                // of the next one.
-                offset += dataSize;
-                length -= dataSize;
-            } else {
-                // we don't have enough data to fill this entry, so we store what we have
-                // in the entry itself.
-                System.arraycopy(data, offset, mCurrentEntry.data, mEntryDataOffset, length);
-                
-                // save the amount read for the data.
-                mEntryDataOffset += length;
-                return;
-            }
-        }
-    }
-
-    /**
-     * Returns whether this receiver is canceling the remote service.
-     */
-    public boolean isCancelled() {
-        return mIsCancelled;
-    }
-    
-    /**
-     * Cancels the current remote service.
-     */
-    public void cancel() {
-        mIsCancelled = true;
-    }
-    
-    /**
-     * Creates a {@link LogEntry} from the array of bytes. This expects the data buffer size
-     * to be at least <code>offset + {@link #ENTRY_HEADER_SIZE}</code>.
-     * @param data the data buffer the entry is read from.
-     * @param offset the offset of the first byte from the buffer representing the entry.
-     * @return a new {@link LogEntry} or <code>null</code> if some error happened.
-     */
-    private LogEntry createEntry(byte[] data, int offset) {
-        if (data.length < offset + ENTRY_HEADER_SIZE) {
-            throw new InvalidParameterException(
-                    "Buffer not big enough to hold full LoggerEntry header");
-        }
-
-        // create the new entry and fill it.
-        LogEntry entry = new LogEntry();
-        entry.len = ArrayHelper.swapU16bitFromArray(data, offset);
-        
-        // we've read only 16 bits, but since there's also a 16 bit padding,
-        // we can skip right over both.
-        offset += 4;
-        
-        entry.pid = ArrayHelper.swap32bitFromArray(data, offset);
-        offset += 4;
-        entry.tid = ArrayHelper.swap32bitFromArray(data, offset);
-        offset += 4;
-        entry.sec = ArrayHelper.swap32bitFromArray(data, offset);
-        offset += 4;
-        entry.nsec = ArrayHelper.swap32bitFromArray(data, offset);
-        offset += 4;
-        
-        // allocate the data
-        entry.data = new byte[entry.len];
-        
-        return entry;
-    }
-    
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java
deleted file mode 100644
index b61a698..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.android.ddmlib.testrunner;
-
-/**
- * Receives event notifications during instrumentation test runs. 
- * Patterned after {@link junit.runner.TestRunListener}.
- */
-public interface ITestRunListener {
-
-    /**
-     *  Types of test failures.
-     */
-    enum TestFailure {
-        /** Test failed due to unanticipated uncaught exception. */
-        ERROR,
-        /** Test failed due to a false assertion. */
-        FAILURE
-    }
-
-    /** 
-     * Reports the start of a test run.
-     * 
-     * @param testCount total number of tests in test run
-     */
-    public void testRunStarted(int testCount);
-    
-    /**
-     * Reports end of test run.
-     * 
-     * @param elapsedTime device reported elapsed time, in milliseconds
-     */
-    public void testRunEnded(long elapsedTime);
-
-    /**
-     * Reports test run stopped before completion.
-     * 
-     * @param elapsedTime device reported elapsed time, in milliseconds
-     */
-    public void testRunStopped(long elapsedTime);
-
-    /**
-     * Reports the start of an individual test case.
-     * 
-     * @param test identifies the test
-     */
-    public void testStarted(TestIdentifier test);
-
-    /**
-     * Reports the execution end of an individual test case.
-     * If {@link #testFailed} was not invoked, this test passed.
-     * 
-     * @param test identifies the test
-     */
-    public void testEnded(TestIdentifier test);
-
-    /**
-     * Reports the failure of a individual test case.
-     * Will be called between testStarted and testEnded.
-     * 
-     * @param status failure type
-     * @param test identifies the test
-     * @param trace stack trace of failure
-     */
-    public void testFailed(TestFailure status, TestIdentifier test, String trace);
-    
-    /** 
-     * Reports test run failed to execute due to a fatal error.
-     */
-    public void testRunFailed(String errorMessage);
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java
deleted file mode 100755
index 1a0b21f..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * 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.android.ddmlib.testrunner;
-
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-
-/**
- * Parses the 'raw output mode' results of an instrumentation test run from shell and informs a 
- * ITestRunListener of the results.
- * 
- * <p>Expects the following output:
- * 
- * <p>If fatal error occurred when attempted to run the tests:
- * <pre>
- * INSTRUMENTATION_STATUS: Error=error Message
- * INSTRUMENTATION_FAILED: 
- * </pre>
- * <p>or
- * <pre>
- * INSTRUMENTATION_RESULT: shortMsg=error Message
- * </pre>
- * 
- * <p>Otherwise, expect a series of test results, each one containing a set of status key/value
- * pairs, delimited by a start(1)/pass(0)/fail(-2)/error(-1) status code result. At end of test 
- * run, expects that the elapsed test time in seconds will be displayed  
- * 
- * <p>For example:
- * <pre>
- * INSTRUMENTATION_STATUS_CODE: 1
- * INSTRUMENTATION_STATUS: class=com.foo.FooTest
- * INSTRUMENTATION_STATUS: test=testFoo
- * INSTRUMENTATION_STATUS: numtests=2
- * INSTRUMENTATION_STATUS: stack=com.foo.FooTest#testFoo:312
- *    com.foo.X
- * INSTRUMENTATION_STATUS_CODE: -2   
- * ... 
- * 
- * Time: X
- * </pre>
- * <p>Note that the "value" portion of the key-value pair may wrap over several text lines
- */
-public class InstrumentationResultParser extends MultiLineReceiver {
-    
-    /** Relevant test status keys. */
-    private static class StatusKeys {
-        private static final String TEST = "test";
-        private static final String CLASS = "class";
-        private static final String STACK = "stack";
-        private static final String NUMTESTS = "numtests";
-        private static final String ERROR = "Error";
-        private static final String SHORTMSG = "shortMsg";
-    }
-    
-    /** Test result status codes. */
-    private static class StatusCodes {
-        private static final int FAILURE = -2;
-        private static final int START = 1;
-        private static final int ERROR = -1;
-        private static final int OK = 0;
-    }
-
-    /** Prefixes used to identify output. */
-    private static class Prefixes {
-        private static final String STATUS = "INSTRUMENTATION_STATUS: ";
-        private static final String STATUS_CODE = "INSTRUMENTATION_STATUS_CODE: ";
-        private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: ";
-        private static final String CODE = "INSTRUMENTATION_CODE: ";
-        private static final String RESULT = "INSTRUMENTATION_RESULT: ";
-        private static final String TIME_REPORT = "Time: ";
-    }
-    
-    private final ITestRunListener mTestListener;
-
-    /** 
-     * Test result data
-     */
-    private static class TestResult {
-        private Integer mCode = null;
-        private String mTestName = null;
-        private String mTestClass = null;
-        private String mStackTrace = null;
-        private Integer mNumTests = null;
-        
-        /** Returns true if all expected values have been parsed */
-        boolean isComplete() {
-            return mCode != null && mTestName != null && mTestClass != null;
-        }
-        
-        /** Provides a more user readable string for TestResult, if possible */
-        @Override
-        public String toString() {
-            StringBuilder output = new StringBuilder();
-            if (mTestClass != null ) {
-                output.append(mTestClass);
-                output.append('#');
-            }    
-            if (mTestName != null) {
-                output.append(mTestName);
-            }
-            if (output.length() > 0) {
-                return output.toString();
-            }    
-            return "unknown result";
-        }
-    }
-    
-    /** Stores the status values for the test result currently being parsed */
-    private TestResult mCurrentTestResult = null;
-    
-    /** Stores the current "key" portion of the status key-value being parsed. */
-    private String mCurrentKey = null;
-    
-    /** Stores the current "value" portion of the status key-value being parsed. */
-    private StringBuilder mCurrentValue = null;
-    
-    /** True if start of test has already been reported to listener. */
-    private boolean mTestStartReported = false;
-    
-    /** The elapsed time of the test run, in milliseconds. */
-    private long mTestTime = 0;
-    
-    /** True if current test run has been canceled by user. */
-    private boolean mIsCancelled = false;
-    
-    private static final String LOG_TAG = "InstrumentationResultParser";
-    
-    /**
-     * Creates the InstrumentationResultParser.
-     * 
-     * @param listener informed of test results as the tests are executing
-     */
-    public InstrumentationResultParser(ITestRunListener listener) {
-        mTestListener = listener;
-    }
-    
-    /**
-     * Processes the instrumentation test output from shell.
-     * 
-     * @see MultiLineReceiver#processNewLines
-     */
-    @Override
-    public void processNewLines(String[] lines) {
-        for (String line : lines) {
-            parse(line);
-            // in verbose mode, dump all adb output to log
-            Log.v(LOG_TAG, line);
-        }
-    }
-    
-    /**
-     * Parse an individual output line. Expects a line that is one of:
-     * <ul>
-     * <li> 
-     * The start of a new status line (starts with Prefixes.STATUS or Prefixes.STATUS_CODE), 
-     * and thus there is a new key=value pair to parse, and the previous key-value pair is 
-     * finished. 
-     * </li>
-     * <li>
-     * A continuation of the previous status (the "value" portion of the key has wrapped
-     * to the next line).
-     * </li>  
-     * <li> A line reporting a fatal error in the test run (Prefixes.STATUS_FAILED) </li>
-     * <li> A line reporting the total elapsed time of the test run. (Prefixes.TIME_REPORT) </li>  
-     * </ul>
-     *    
-     * @param line  Text output line
-     */
-    private void parse(String line) {
-        if (line.startsWith(Prefixes.STATUS_CODE)) {
-            // Previous status key-value has been collected. Store it.
-            submitCurrentKeyValue();
-            parseStatusCode(line);
-        } else if (line.startsWith(Prefixes.STATUS)) {
-            // Previous status key-value has been collected. Store it.
-            submitCurrentKeyValue();
-            parseKey(line, Prefixes.STATUS.length());
-        } else if (line.startsWith(Prefixes.RESULT)) {
-            // Previous status key-value has been collected. Store it.
-            submitCurrentKeyValue();
-            parseKey(line, Prefixes.RESULT.length());  
-        } else if (line.startsWith(Prefixes.STATUS_FAILED) || 
-                   line.startsWith(Prefixes.CODE)) {
-            // Previous status key-value has been collected. Store it.
-            submitCurrentKeyValue();
-            // just ignore the remaining data on this line            
-        } else if (line.startsWith(Prefixes.TIME_REPORT)) {
-            parseTime(line, Prefixes.TIME_REPORT.length());
-        } else {
-            if (mCurrentValue != null) {
-                // this is a value that has wrapped to next line. 
-                mCurrentValue.append("\r\n");
-                mCurrentValue.append(line);
-            } else {
-                Log.w(LOG_TAG, "unrecognized line " + line);
-            }
-        }
-    }
-    
-    /**
-     * Stores the currently parsed key-value pair into mCurrentTestInfo.
-     */
-    private void submitCurrentKeyValue() {
-        if (mCurrentKey != null && mCurrentValue != null) {
-            TestResult testInfo = getCurrentTestInfo();
-            String statusValue = mCurrentValue.toString();
-
-            if (mCurrentKey.equals(StatusKeys.CLASS)) {
-                testInfo.mTestClass = statusValue.trim();
-            } else if (mCurrentKey.equals(StatusKeys.TEST)) {
-                testInfo.mTestName = statusValue.trim();
-            } else if (mCurrentKey.equals(StatusKeys.NUMTESTS)) {
-                try {
-                    testInfo.mNumTests = Integer.parseInt(statusValue);
-                } catch (NumberFormatException e) {
-                    Log.e(LOG_TAG, "Unexpected integer number of tests, received " + statusValue);
-                }
-            } else if (mCurrentKey.equals(StatusKeys.ERROR) || 
-                    mCurrentKey.equals(StatusKeys.SHORTMSG)) {
-                // test run must have failed
-                handleTestRunFailed(statusValue); 
-            } else if (mCurrentKey.equals(StatusKeys.STACK)) {
-                testInfo.mStackTrace = statusValue;
-            }
-
-            mCurrentKey = null;
-            mCurrentValue = null;
-        }
-    }
-    
-    private TestResult getCurrentTestInfo() {
-        if (mCurrentTestResult == null) {
-            mCurrentTestResult = new TestResult();
-        }
-        return mCurrentTestResult;
-    }
-    
-    private void clearCurrentTestInfo() {
-        mCurrentTestResult = null;
-    }
-    
-    /**
-     * Parses the key from the current line.
-     * Expects format of "key=value".
-     *  
-     * @param line full line of text to parse 
-     * @param keyStartPos the starting position of the key in the given line
-     */
-    private void parseKey(String line, int keyStartPos) {
-        int endKeyPos = line.indexOf('=', keyStartPos);
-        if (endKeyPos != -1) {
-            mCurrentKey = line.substring(keyStartPos, endKeyPos).trim();
-            parseValue(line, endKeyPos + 1);
-        }
-    }
-    
-    /**
-     * Parses the start of a key=value pair.
-     *  
-     * @param line - full line of text to parse 
-     * @param valueStartPos - the starting position of the value in the given line
-     */
-    private void parseValue(String line, int valueStartPos) {
-        mCurrentValue = new StringBuilder();
-        mCurrentValue.append(line.substring(valueStartPos));
-    }
-    
-    /**
-     * Parses out a status code result. 
-     */
-    private void parseStatusCode(String line) {
-        String value = line.substring(Prefixes.STATUS_CODE.length()).trim();
-        TestResult testInfo = getCurrentTestInfo();
-        try {
-            testInfo.mCode = Integer.parseInt(value);    
-        } catch (NumberFormatException e) {
-            Log.e(LOG_TAG, "Expected integer status code, received: " + value);
-        }
-        
-        // this means we're done with current test result bundle
-        reportResult(testInfo);
-        clearCurrentTestInfo();
-    }
-    
-    /**
-     * Returns true if test run canceled.
-     * 
-     * @see IShellOutputReceiver#isCancelled()
-     */
-    public boolean isCancelled() {
-        return mIsCancelled;
-    }
-    
-    /**
-     * Requests cancellation of test run.
-     */
-    public void cancel() {
-        mIsCancelled = true;
-    }
-    
-    /**
-     * Reports a test result to the test run listener. Must be called when a individual test
-     * result has been fully parsed. 
-     * 
-     * @param statusMap key-value status pairs of test result
-     */
-    private void reportResult(TestResult testInfo) {
-        if (!testInfo.isComplete()) {
-            Log.w(LOG_TAG, "invalid instrumentation status bundle " + testInfo.toString());
-            return;
-        }
-        reportTestRunStarted(testInfo);
-        TestIdentifier testId = new TestIdentifier(testInfo.mTestClass, testInfo.mTestName);
-
-        switch (testInfo.mCode) {
-            case StatusCodes.START:
-                mTestListener.testStarted(testId);
-                break;
-            case StatusCodes.FAILURE:
-                mTestListener.testFailed(ITestRunListener.TestFailure.FAILURE, testId, 
-                        getTrace(testInfo));
-                mTestListener.testEnded(testId);
-                break;
-            case StatusCodes.ERROR:
-                mTestListener.testFailed(ITestRunListener.TestFailure.ERROR, testId, 
-                        getTrace(testInfo));
-                mTestListener.testEnded(testId);
-                break;
-            case StatusCodes.OK:
-                mTestListener.testEnded(testId);
-                break;
-            default:
-                Log.e(LOG_TAG, "Unknown status code received: " + testInfo.mCode);
-                mTestListener.testEnded(testId);
-            break;
-        }
-
-    }
-    
-    /**
-     * Reports the start of a test run, and the total test count, if it has not been previously 
-     * reported.
-     * 
-     * @param testInfo current test status values
-     */
-    private void reportTestRunStarted(TestResult testInfo) {
-        // if start test run not reported yet
-        if (!mTestStartReported && testInfo.mNumTests != null) {
-            mTestListener.testRunStarted(testInfo.mNumTests);
-            mTestStartReported = true;
-        }
-    }
-    
-    /**
-     * Returns the stack trace of the current failed test, from the provided testInfo.
-     */
-    private String getTrace(TestResult testInfo) {
-        if (testInfo.mStackTrace != null) {
-            return testInfo.mStackTrace;    
-        } else {
-            Log.e(LOG_TAG, "Could not find stack trace for failed test ");
-            return new Throwable("Unknown failure").toString();
-        }
-    }
-    
-    /**
-     * Parses out and store the elapsed time.
-     */
-    private void parseTime(String line, int startPos) {
-        String timeString = line.substring(startPos);
-        try {
-            float timeSeconds = Float.parseFloat(timeString);
-            mTestTime = (long) (timeSeconds * 1000); 
-        } catch (NumberFormatException e) {
-            Log.e(LOG_TAG, "Unexpected time format " + timeString);
-        }
-    }
-    
-    /**
-     * Process a instrumentation run failure
-     */
-    private void handleTestRunFailed(String errorMsg) {
-        mTestListener.testRunFailed(errorMsg == null ? "Unknown error" : errorMsg);
-    }
-    
-    /**
-     * Called by parent when adb session is complete. 
-     */
-    @Override
-    public void done() {
-        super.done();
-        mTestListener.testRunEnded(mTestTime);
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
deleted file mode 100644
index 9dd1d16..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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.android.ddmlib.testrunner;
-
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-
-import java.io.IOException;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Runs a Android test command remotely and reports results.
- */
-public class RemoteAndroidTestRunner  {
-
-    private final String mPackageName;
-    private final  String mRunnerName;
-    private IDevice mRemoteDevice;
-    /** map of name-value instrumentation argument pairs */
-    private Map<String, String> mArgMap;
-    private InstrumentationResultParser mParser;
-
-    private static final String LOG_TAG = "RemoteAndroidTest";
-    private static final String DEFAULT_RUNNER_NAME = "android.test.InstrumentationTestRunner";
-
-    private static final char CLASS_SEPARATOR = ',';
-    private static final char METHOD_SEPARATOR = '#';
-    private static final char RUNNER_SEPARATOR = '/';
-
-    // defined instrumentation argument names  
-    private static final String CLASS_ARG_NAME = "class";
-    private static final String LOG_ARG_NAME = "log";
-    private static final String DEBUG_ARG_NAME = "debug";
-    private static final String COVERAGE_ARG_NAME = "coverage";
-    private static final String PACKAGE_ARG_NAME = "package";
- 
-    /**
-     * Creates a remote Android test runner.
-     * 
-     * @param packageName the Android application package that contains the tests to run 
-     * @param runnerName the instrumentation test runner to execute. If null, will use default
-     *   runner 
-     * @param remoteDevice the Android device to execute tests on
-     */
-    public RemoteAndroidTestRunner(String packageName, 
-                                   String runnerName,
-                                   IDevice remoteDevice) {
-        
-        mPackageName = packageName;
-        mRunnerName = runnerName;
-        mRemoteDevice = remoteDevice;
-        mArgMap = new Hashtable<String, String>();
-    }
-
-    /**
-     * Alternate constructor. Uses default instrumentation runner.
-     * 
-     * @param packageName the Android application package that contains the tests to run 
-     * @param remoteDevice the Android device to execute tests on
-     */
-    public RemoteAndroidTestRunner(String packageName, 
-                                   IDevice remoteDevice) {
-        this(packageName, null, remoteDevice);
-    }
-
-    /**
-     * Returns the application package name.
-     */
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /**
-     * Returns the runnerName.
-     */
-    public String getRunnerName() {
-        if (mRunnerName == null) {
-            return DEFAULT_RUNNER_NAME;
-        }
-        return mRunnerName;
-    }
-
-    /**
-     * Returns the complete instrumentation component path.
-     */
-    private String getRunnerPath() {
-        return getPackageName() + RUNNER_SEPARATOR + getRunnerName();
-    }
-
-    /**
-     * Sets to run only tests in this class
-     * Must be called before 'run'.
-     * 
-     * @param className fully qualified class name (eg x.y.z)
-     */
-    public void setClassName(String className) {
-        addInstrumentationArg(CLASS_ARG_NAME, className);
-    }
-
-    /**
-     * Sets to run only tests in the provided classes
-     * Must be called before 'run'.
-     * <p>
-     * If providing more than one class, requires a InstrumentationTestRunner that supports 
-     * the multiple class argument syntax.
-     * 
-     * @param classNames array of fully qualified class names (eg x.y.z)
-     */
-    public void setClassNames(String[] classNames) {
-        StringBuilder classArgBuilder = new StringBuilder();
-        
-        for (int i = 0; i < classNames.length; i++) {
-            if (i != 0) {
-                classArgBuilder.append(CLASS_SEPARATOR);
-            }
-            classArgBuilder.append(classNames[i]);
-        }
-        setClassName(classArgBuilder.toString());
-    }
-
-    /**
-     * Sets to run only specified test method
-     * Must be called before 'run'.
-     * 
-     * @param className fully qualified class name (eg x.y.z)
-     * @param testName method name
-     */
-    public void setMethodName(String className, String testName) {
-        setClassName(className + METHOD_SEPARATOR + testName);
-    }
-
-    /**
-     * Sets to run all tests in specified package
-     * Must be called before 'run'.
-     * 
-     * @param packageName fully qualified package name (eg x.y.z)
-     */
-    public void setTestPackageName(String packageName) {
-        addInstrumentationArg(PACKAGE_ARG_NAME, packageName);
-    }
-
-    /**
-     * Adds a argument to include in instrumentation command.
-     * <p/>
-     * Must be called before 'run'. If an argument with given name has already been provided, it's
-     * value will be overridden. 
-     * 
-     * @param name the name of the instrumentation bundle argument
-     * @param value the value of the argument
-     */
-    public void addInstrumentationArg(String name, String value) {
-        if (name == null || value == null) {
-            throw new IllegalArgumentException("name or value arguments cannot be null");
-        }
-        mArgMap.put(name, value);  
-    }
-
-    /**
-     * Adds a boolean argument to include in instrumentation command.
-     * <p/>
-     * @see RemoteAndroidTestRunner#addInstrumentationArg
-     * 
-     * @param name the name of the instrumentation bundle argument
-     * @param value the value of the argument
-     */
-    public void addBooleanArg(String name, boolean value) {
-        addInstrumentationArg(name, Boolean.toString(value));
-    }
-  
-    /**
-     * Sets this test run to log only mode - skips test execution.
-     */
-    public void setLogOnly(boolean logOnly) {
-        addBooleanArg(LOG_ARG_NAME, logOnly);
-    }
-
-    /**
-     * Sets this debug mode of this test run. If true, the Android test runner will wait for a 
-     * debugger to attach before proceeding with test execution.
-     */
-    public void setDebug(boolean debug) {
-        addBooleanArg(DEBUG_ARG_NAME, debug);
-    }
-
-    /**
-     * Sets this code coverage mode of this test run. 
-     */
-    public void setCoverage(boolean coverage) {
-        addBooleanArg(COVERAGE_ARG_NAME, coverage);
-    }
-
-    /**
-     * Execute this test run.
-     * 
-     * @param listener listens for test results
-     */
-    public void run(ITestRunListener listener) {
-        final String runCaseCommandStr = String.format("am instrument -w -r %s %s",
-            getArgsCommand(), getRunnerPath());
-        Log.d(LOG_TAG, runCaseCommandStr);
-        mParser = new InstrumentationResultParser(listener);
-
-        try {
-            mRemoteDevice.executeShellCommand(runCaseCommandStr, mParser);
-        } catch (IOException e) {
-            Log.e(LOG_TAG, e);
-            listener.testRunFailed(e.toString());
-        }
-    }
-
-    /**
-     * Requests cancellation of this test run.
-     */
-    public void cancel() {
-        if (mParser != null) {
-            mParser.cancel();
-        }
-    }
-
-    /**
-     * Returns the full instrumentation command line syntax for the provided instrumentation 
-     * arguments.  
-     * Returns an empty string if no arguments were specified.
-     */
-    private String getArgsCommand() {
-        StringBuilder commandBuilder = new StringBuilder();
-        for (Entry<String, String> argPair : mArgMap.entrySet()) {
-            final String argCmd = String.format(" -e %s %s", argPair.getKey(),
-                    argPair.getValue());
-            commandBuilder.append(argCmd);
-        }
-        return commandBuilder.toString();
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java
deleted file mode 100644
index 4d3b108..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.android.ddmlib.testrunner;
-
-/**
- * Identifies a parsed instrumentation test 
- */
-public class TestIdentifier {
-
-    private final String mClassName;
-    private final String mTestName;
-    
-    /**
-     * Creates a test identifier
-     * 
-     * @param className fully qualified class name of the test. Cannot be null.
-     * @param testName name of the test. Cannot be null.
-     */
-    public TestIdentifier(String className, String testName) {
-        if (className == null || testName == null) {
-            throw new IllegalArgumentException("className and testName must " + 
-                    "be non-null");
-        }
-        mClassName = className;
-        mTestName = testName;
-    }
-    
-    /**
-     * Returns the fully qualified class name of the test
-     */
-    public String getClassName() {
-        return mClassName;
-    }
-
-    /**
-     * Returns the name of the test
-     */
-    public String getTestName() {
-        return mTestName;
-    }
-    
-    /**
-     * Tests equality by comparing class and method name
-     */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof TestIdentifier)) {
-            return false;
-        }
-        TestIdentifier otherTest = (TestIdentifier)other;
-        return getClassName().equals(otherTest.getClassName())  && 
-                getTestName().equals(otherTest.getTestName());
-    }
-    
-    /**
-     * Generates hashCode based on class and method name.
-     */
-    @Override
-    public int hashCode() {
-        return getClassName().hashCode() * 31 + getTestName().hashCode();
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/utils/ArrayHelper.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/utils/ArrayHelper.java
deleted file mode 100644
index 8167e5d..0000000
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/utils/ArrayHelper.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.android.ddmlib.utils;
-
-/**
- * Utility class providing array to int/long conversion for data received from devices through adb. 
- */
-public final class ArrayHelper {
-
-    /**
-     * Swaps an unsigned value around, and puts the result in an array that can be sent to a device.
-     * @param value The value to swap.
-     * @param dest the destination array
-     * @param offset the offset in the array where to put the swapped value.
-     *      Array length must be at least offset + 4
-     */
-    public static void swap32bitsToArray(int value, byte[] dest, int offset) {
-        dest[offset] = (byte)(value & 0x000000FF);
-        dest[offset + 1] = (byte)((value & 0x0000FF00) >> 8);
-        dest[offset + 2] = (byte)((value & 0x00FF0000) >> 16);
-        dest[offset + 3] = (byte)((value & 0xFF000000) >> 24);
-    }
-
-    /**
-     * Reads a signed 32 bit integer from an array coming from a device.
-     * @param value the array containing the int
-     * @param offset the offset in the array at which the int starts
-     * @return the integer read from the array
-     */
-    public static int swap32bitFromArray(byte[] value, int offset) {
-        int v = 0;
-        v |= ((int)value[offset]) & 0x000000FF;
-        v |= (((int)value[offset + 1]) & 0x000000FF) << 8;
-        v |= (((int)value[offset + 2]) & 0x000000FF) << 16;
-        v |= (((int)value[offset + 3]) & 0x000000FF) << 24;
-
-        return v;
-    }
-    
-    /**
-     * Reads an unsigned 16 bit integer from an array coming from a device,
-     * and returns it as an 'int'
-     * @param value the array containing the 16 bit int (2 byte).
-     * @param offset the offset in the array at which the int starts
-     *      Array length must be at least offset + 2
-     * @return the integer read from the array.
-     */
-    public static int swapU16bitFromArray(byte[] value, int offset) {
-        int v = 0;
-        v |= ((int)value[offset]) & 0x000000FF;
-        v |= (((int)value[offset + 1]) & 0x000000FF) << 8;
-
-        return v;
-    }
-    
-    /**
-     * Reads a signed 64 bit integer from an array coming from a device.
-     * @param value the array containing the int
-     * @param offset the offset in the array at which the int starts
-     *      Array length must be at least offset + 8
-     * @return the integer read from the array
-     */
-    public static long swap64bitFromArray(byte[] value, int offset) {
-        long v = 0;
-        v |= ((long)value[offset]) & 0x00000000000000FFL;
-        v |= (((long)value[offset + 1]) & 0x00000000000000FFL) << 8;
-        v |= (((long)value[offset + 2]) & 0x00000000000000FFL) << 16;
-        v |= (((long)value[offset + 3]) & 0x00000000000000FFL) << 24;
-        v |= (((long)value[offset + 4]) & 0x00000000000000FFL) << 32;
-        v |= (((long)value[offset + 5]) & 0x00000000000000FFL) << 40;
-        v |= (((long)value[offset + 6]) & 0x00000000000000FFL) << 48;
-        v |= (((long)value[offset + 7]) & 0x00000000000000FFL) << 56;
-
-        return v;
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java b/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java
deleted file mode 100644
index 7742dd6..0000000
--- a/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * 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.android.ddmlib.testrunner;
-
-import junit.framework.TestCase;
-
-
-/**
- * Tests InstrumentationResultParser.
- */
-public class InstrumentationResultParserTest extends TestCase {
-
-    private InstrumentationResultParser mParser;
-    private VerifyingTestResult mTestResult;
-
-    // static dummy test names to use for validation
-    private static final String CLASS_NAME = "com.test.FooTest";
-    private static final String TEST_NAME = "testFoo";
-    private static final String STACK_TRACE = "java.lang.AssertionFailedException";
-
-    /**
-     * @param name - test name
-     */
-    public InstrumentationResultParserTest(String name) {
-        super(name);
-    }
-
-    /**
-     * @see junit.framework.TestCase#setUp()
-     */
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestResult = new VerifyingTestResult();
-        mParser = new InstrumentationResultParser(mTestResult);
-    }
-
-    /**
-     * Tests that the test run started and test start events is sent on first
-     * bundle received.
-     */
-    public void testTestStarted() {
-        StringBuilder output = buildCommonResult();
-        addStartCode(output);
-
-        injectTestString(output.toString());
-        assertCommonAttributes();
-        assertEquals(0, mTestResult.mNumTestsRun);
-    }
-
-    /**
-     * Tests that a single successful test execution.
-     */
-    public void testTestSuccess() {
-        StringBuilder output = buildCommonResult();
-        addStartCode(output);
-        addCommonStatus(output);
-        addSuccessCode(output);
-
-        injectTestString(output.toString());
-        assertCommonAttributes();
-        assertEquals(1, mTestResult.mNumTestsRun);
-        assertEquals(null, mTestResult.mTestStatus);
-    }
-
-    /**
-     * Test basic parsing of failed test case.
-     */
-    public void testTestFailed() {
-        StringBuilder output = buildCommonResult();
-        addStartCode(output);
-        addCommonStatus(output);
-        addStackTrace(output);
-        addFailureCode(output);
-
-        injectTestString(output.toString());
-        assertCommonAttributes();
-
-        assertEquals(1, mTestResult.mNumTestsRun);
-        assertEquals(ITestRunListener.TestFailure.FAILURE, mTestResult.mTestStatus);
-        assertEquals(STACK_TRACE, mTestResult.mTrace);
-    }
-    
-    /**
-     * Test basic parsing and conversion of time from output.
-     */
-    public void testTimeParsing() {
-        final String timeString = "Time: 4.9";
-        injectTestString(timeString);
-        assertEquals(4900, mTestResult.mTestTime);
-    }
-    
-    /**
-     * Test basic parsing of a test run failure.
-     */
-    public void testRunFailed() {
-        StringBuilder output = new StringBuilder();        
-        final String errorMessage = "Unable to find instrumentation info";
-        addStatusKey(output, "Error", errorMessage);
-        addStatusCode(output, "-1");
-        output.append("INSTRUMENTATION_FAILED: com.dummy/android.test.InstrumentationTestRunner");
-        addLineBreak(output);
-        
-        injectTestString(output.toString());
-        
-        assertEquals(errorMessage, mTestResult.mRunFailedMessage);
-    }
-    
-    /**
-     * Test parsing of a test run failure, where an instrumentation component failed to load
-     * Parsing input takes the from of INSTRUMENTATION_RESULT: fff
-     */
-    public void testRunFailedResult() {
-        StringBuilder output = new StringBuilder();        
-        final String errorMessage = "Unable to instantiate instrumentation";
-        output.append("INSTRUMENTATION_RESULT: shortMsg=");
-        output.append(errorMessage);
-        addLineBreak(output);
-        output.append("INSTRUMENTATION_CODE: 0");
-        addLineBreak(output);
-        
-        injectTestString(output.toString());
-        
-        assertEquals(errorMessage, mTestResult.mRunFailedMessage);
-    }
-
-    /**
-     * Builds a common test result using TEST_NAME and TEST_CLASS.
-     */
-    private StringBuilder buildCommonResult() {
-        StringBuilder output = new StringBuilder();
-        // add test start bundle
-        addCommonStatus(output);
-        addStatusCode(output, "1");
-        // add end test bundle, without status
-        addCommonStatus(output);
-        return output;
-    }
-
-    /**
-     * Adds common status results to the provided output.
-     */
-    private void addCommonStatus(StringBuilder output) {
-        addStatusKey(output, "stream", "\r\n" + CLASS_NAME);
-        addStatusKey(output, "test", TEST_NAME);
-        addStatusKey(output, "class", CLASS_NAME);
-        addStatusKey(output, "current", "1");
-        addStatusKey(output, "numtests", "1");
-        addStatusKey(output, "id", "InstrumentationTestRunner");
-    }
-
-    /**
-     * Adds a stack trace status bundle to output.
-     */
-    private void addStackTrace(StringBuilder output) {
-        addStatusKey(output, "stack", STACK_TRACE);
-
-    }
-
-    /**
-     * Helper method to add a status key-value bundle.
-     */
-    private void addStatusKey(StringBuilder outputBuilder, String key,
-            String value) {
-        outputBuilder.append("INSTRUMENTATION_STATUS: ");
-        outputBuilder.append(key);
-        outputBuilder.append('=');
-        outputBuilder.append(value);
-        addLineBreak(outputBuilder);
-    }
-
-    /**
-     * Append line break characters to output
-     */
-    private void addLineBreak(StringBuilder outputBuilder) {
-        outputBuilder.append("\r\n");
-    }
-
-    private void addStartCode(StringBuilder outputBuilder) {
-        addStatusCode(outputBuilder, "1");
-    }
-
-    private void addSuccessCode(StringBuilder outputBuilder) {
-        addStatusCode(outputBuilder, "0");
-    }
-
-    private void addFailureCode(StringBuilder outputBuilder) {
-        addStatusCode(outputBuilder, "-2");
-    }
-
-    private void addStatusCode(StringBuilder outputBuilder, String value) {
-        outputBuilder.append("INSTRUMENTATION_STATUS_CODE: ");
-        outputBuilder.append(value);
-        addLineBreak(outputBuilder);
-    }
-
-    /**
-     * inject a test string into the result parser.
-     * 
-     * @param result
-     */
-    private void injectTestString(String result) {
-        byte[] data = result.getBytes();
-        mParser.addOutput(data, 0, data.length);
-        mParser.flush();
-    }
-
-    private void assertCommonAttributes() {
-        assertEquals(CLASS_NAME, mTestResult.mSuiteName);
-        assertEquals(1, mTestResult.mTestCount);
-        assertEquals(TEST_NAME, mTestResult.mTestName);
-    }
-
-    /**
-     * A specialized test listener that stores a single test events.
-     */
-    private class VerifyingTestResult implements ITestRunListener {
-
-        String mSuiteName;
-        int mTestCount;
-        int mNumTestsRun;
-        String mTestName;
-        long mTestTime;
-        TestFailure mTestStatus;
-        String mTrace;
-        boolean mStopped;
-        /** stores the error message provided to testRunFailed */
-        String mRunFailedMessage;
-
-        VerifyingTestResult() {
-            mNumTestsRun = 0;
-            mTestStatus = null;
-            mStopped = false;
-            mRunFailedMessage = null;
-        }
-
-        public void testEnded(TestIdentifier test) {
-            mNumTestsRun++;
-            assertEquals("Unexpected class name", mSuiteName, test.getClassName());
-            assertEquals("Unexpected test ended", mTestName, test.getTestName());
-
-        }
-
-        public void testFailed(TestFailure status, TestIdentifier test, String trace) {
-            mTestStatus = status;
-            mTrace = trace;
-            assertEquals("Unexpected class name", mSuiteName, test.getClassName());
-            assertEquals("Unexpected test ended", mTestName, test.getTestName());
-        }
-
-        public void testRunEnded(long elapsedTime) {
-            mTestTime = elapsedTime;
-
-        }
-
-        public void testRunStarted(int testCount) {
-            mTestCount = testCount;
-        }
-
-        public void testRunStopped(long elapsedTime) {
-            mTestTime = elapsedTime;
-            mStopped = true;
-        }
-
-        public void testStarted(TestIdentifier test) {
-            mSuiteName = test.getClassName();
-            mTestName = test.getTestName();
-        }
-
-        public void testRunFailed(String errorMessage) {
-            mRunFailedMessage = errorMessage;
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java b/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
deleted file mode 100644
index 29ec9fe..0000000
--- a/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * 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.android.ddmlib.testrunner;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.FileListingService;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.RawImage;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.log.LogReceiver;
-
-import java.io.IOException;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-/**
- * Tests RemoteAndroidTestRunner.
- */
-public class RemoteAndroidTestRunnerTest extends TestCase {
-
-    private RemoteAndroidTestRunner mRunner;
-    private MockDevice mMockDevice;
-
-    private static final String TEST_PACKAGE = "com.test";
-    private static final String TEST_RUNNER = "com.test.InstrumentationTestRunner";
-
-    /**
-     * @see junit.framework.TestCase#setUp()
-     */
-    @Override
-    protected void setUp() throws Exception {
-        mMockDevice = new MockDevice();
-        mRunner = new RemoteAndroidTestRunner(TEST_PACKAGE, TEST_RUNNER, mMockDevice);
-    }
-
-    /**
-     * Test the basic case building of the instrumentation runner command with no arguments.
-     */
-    public void testRun() {
-        mRunner.run(new EmptyListener());
-        assertStringsEquals(String.format("am instrument -w -r %s/%s", TEST_PACKAGE, TEST_RUNNER),
-                mMockDevice.getLastShellCommand());
-    }
-
-    /**
-     * Test the building of the instrumentation runner command with log set.
-     */
-    public void testRunWithLog() {
-        mRunner.setLogOnly(true);
-        mRunner.run(new EmptyListener());
-        assertStringsEquals(String.format("am instrument -w -r -e log true %s/%s", TEST_PACKAGE,
-                TEST_RUNNER), mMockDevice.getLastShellCommand());
-    }
-
-    /**
-     * Test the building of the instrumentation runner command with method set.
-     */
-    public void testRunWithMethod() {
-        final String className = "FooTest";
-        final String testName = "fooTest";
-        mRunner.setMethodName(className, testName);
-        mRunner.run(new EmptyListener());
-        assertStringsEquals(String.format("am instrument -w -r -e class %s#%s %s/%s", className,
-                testName, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
-    }
-
-    /**
-     * Test the building of the instrumentation runner command with test package set.
-     */
-    public void testRunWithPackage() {
-        final String packageName = "foo.test";
-        mRunner.setTestPackageName(packageName);
-        mRunner.run(new EmptyListener());
-        assertStringsEquals(String.format("am instrument -w -r -e package %s %s/%s", packageName,
-                TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
-    }
-
-    /**
-     * Test the building of the instrumentation runner command with extra argument added.
-     */
-    public void testRunWithAddInstrumentationArg() {
-        final String extraArgName = "blah";
-        final String extraArgValue = "blahValue";
-        mRunner.addInstrumentationArg(extraArgName, extraArgValue);
-        mRunner.run(new EmptyListener());
-        assertStringsEquals(String.format("am instrument -w -r -e %s %s %s/%s", extraArgName,
-                extraArgValue, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
-    }
-
-
-    /**
-     * Assert two strings are equal ignoring whitespace.
-     */
-    private void assertStringsEquals(String str1, String str2) {
-        String strippedStr1 = str1.replaceAll(" ", "");
-        String strippedStr2 = str2.replaceAll(" ", "");
-        assertEquals(strippedStr1, strippedStr2);
-    }
-
-    /**
-     * A dummy device that does nothing except store the provided executed shell command for
-     * later retrieval.
-     */
-    private static class MockDevice implements IDevice {
-
-        private String mLastShellCommand;
-
-        /**
-         * Stores the provided command for later retrieval from getLastShellCommand.
-         */
-        public void executeShellCommand(String command,
-                IShellOutputReceiver receiver) throws IOException {
-            mLastShellCommand = command;
-        }
-
-        /**
-         * Get the last command provided to executeShellCommand.
-         */
-        public String getLastShellCommand() {
-            return mLastShellCommand;
-        }
-
-        public boolean createForward(int localPort, int remotePort) {
-            throw new UnsupportedOperationException();
-        }
-
-        public Client getClient(String applicationName) {
-            throw new UnsupportedOperationException();
-        }
-
-        public String getClientName(int pid) {
-            throw new UnsupportedOperationException();
-        }
-
-        public Client[] getClients() {
-            throw new UnsupportedOperationException();
-        }
-
-        public FileListingService getFileListingService() {
-            throw new UnsupportedOperationException();
-        }
-
-        public Map<String, String> getProperties() {
-            throw new UnsupportedOperationException();
-        }
-
-        public String getProperty(String name) {
-            throw new UnsupportedOperationException();
-        }
-
-        public int getPropertyCount() {
-            throw new UnsupportedOperationException();
-        }
-
-        public RawImage getScreenshot() throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public String getSerialNumber() {
-            throw new UnsupportedOperationException();
-        }
-
-        public DeviceState getState() {
-            throw new UnsupportedOperationException();
-        }
-
-        public SyncService getSyncService() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean hasClients() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isBootLoader() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isEmulator() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isOffline() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isOnline() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean removeForward(int localPort, int remotePort) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void runEventLogService(LogReceiver receiver) throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public void runLogService(String logname, LogReceiver receiver) throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public String getAvdName() {
-            return "";
-        }
-
-        public String installPackage(String packageFilePath, boolean reinstall)
-                throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public String uninstallPackage(String packageName) throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public String installRemotePackage(String remoteFilePath,
-                boolean reinstall) throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public void removeRemotePackage(String remoteFilePath)
-                throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public String syncPackageToDevice(String localFilePath)
-                throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-    /**
-     * An empty implementation of ITestRunListener.
-     */
-    private static class EmptyListener implements ITestRunListener {
-
-        public void testEnded(TestIdentifier test) {
-            // ignore
-        }
-
-        public void testFailed(TestFailure status, TestIdentifier test, String trace) {
-            // ignore
-        }
-
-        public void testRunEnded(long elapsedTime) {
-            // ignore
-        }
-
-        public void testRunFailed(String errorMessage) {
-            // ignore
-        }
-
-        public void testRunStarted(int testCount) {
-            // ignore
-        }
-
-        public void testRunStopped(long elapsedTime) {
-            // ignore
-        }
-
-        public void testStarted(TestIdentifier test) {
-            // ignore
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/.classpath b/tools/ddms/libs/ddmuilib/.classpath
deleted file mode 100644
index 2cd368c..0000000
--- a/tools/ddms/libs/ddmuilib/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="Makefile|resources/" kind="src" path="src"/>
-	<classpathentry kind="src" path="src/resources"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_JFREECHART"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/ddms/libs/ddmuilib/.project b/tools/ddms/libs/ddmuilib/.project
deleted file mode 100644
index 29cb2f2..0000000
--- a/tools/ddms/libs/ddmuilib/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ddmuilib</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/ddms/libs/ddmuilib/Android.mk b/tools/ddms/libs/ddmuilib/Android.mk
deleted file mode 100644
index 7059e5e..0000000
--- a/tools/ddms/libs/ddmuilib/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-DDMUILIB_LOCAL_DIR := $(call my-dir)
-include $(DDMUILIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/ddms/libs/ddmuilib/README b/tools/ddms/libs/ddmuilib/README
deleted file mode 100644
index d66b84a..0000000
--- a/tools/ddms/libs/ddmuilib/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Using the Eclipse projects for ddmuilib.
-
-ddmuilib requires SWT to compile.
-
-SWT is available in the depot under prebuild/<platform>/swt
-
-Because the build path cannot contain relative path that are not inside the project directory,
-the .classpath file references a user library called ANDROID_SWT.
-
-In order to compile the project, make a user library called ANDROID_SWT containing the jar
-available at prebuild/<platform>/swt.
\ No newline at end of file
diff --git a/tools/ddms/libs/ddmuilib/src/Android.mk b/tools/ddms/libs/ddmuilib/src/Android.mk
deleted file mode 100644
index 68ceac1..0000000
--- a/tools/ddms/libs/ddmuilib/src/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAVA_LIBRARIES := \
-	ddmlib \
-	swt \
-	org.eclipse.jface_3.4.2.M20090107-0800 \
-	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
-	org.eclipse.core.commands_3.4.0.I20080509-2000 \
-	jcommon-1.0.12 \
-	jfreechart-1.0.9 \
-	jfreechart-1.0.9-swt
-	
-LOCAL_MODULE := ddmuilib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java
deleted file mode 100644
index 47e0933..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.*;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.Collection;
-import java.util.HashMap;
-
-/**
- * Represents an addr2line process to get filename/method information from a
- * memory address.<br>
- * Each process can only handle one library, which should be provided when
- * creating a new process.<br>
- * <br>
- * The processes take some time to load as they need to parse the library files.
- * For this reason, processes cannot be manually started. Instead the class
- * keeps an internal list of processes and one asks for a process for a specific
- * library, using <code>getProcess(String library)<code>.<br></br>
- * Internally, the processes are started in pipe mode to be able to query them
- * with multiple addresses.
- */
-public class Addr2Line {
-
-    /**
-     * Loaded processes list. This is also used as a locking object for any
-     * methods dealing with starting/stopping/creating processes/querying for
-     * method.
-     */
-    private static final HashMap<String, Addr2Line> sProcessCache =
-            new HashMap<String, Addr2Line>();
-
-    /**
-     * byte array representing a carriage return. Used to push addresses in the
-     * process pipes.
-     */
-    private static final byte[] sCrLf = {
-        '\n'
-    };
-
-    /** Path to the library */
-    private String mLibrary;
-
-    /** the command line process */
-    private Process mProcess;
-
-    /** buffer to read the result of the command line process from */
-    private BufferedReader mResultReader;
-
-    /**
-     * output stream to provide new addresses to decode to the command line
-     * process
-     */
-    private BufferedOutputStream mAddressWriter;
-
-    /**
-     * Returns the instance of a Addr2Line process for the specified library.
-     * <br>The library should be in a format that makes<br>
-     * <code>$ANDROID_PRODUCT_OUT + "/symbols" + library</code> a valid file.
-     *
-     * @param library the library in which to look for addresses.
-     * @return a new Addr2Line object representing a started process, ready to
-     *         be queried for addresses. If any error happened when launching a
-     *         new process, <code>null</code> will be returned.
-     */
-    public static Addr2Line getProcess(final String library) {
-        // synchronize around the hashmap object
-        if (library != null) {
-            synchronized (sProcessCache) {
-                // look for an existing process
-                Addr2Line process = sProcessCache.get(library);
-
-                // if we don't find one, we create it
-                if (process == null) {
-                    process = new Addr2Line(library);
-
-                    // then we start it
-                    boolean status = process.start();
-
-                    if (status) {
-                        // if starting the process worked, then we add it to the
-                        // list.
-                        sProcessCache.put(library, process);
-                    } else {
-                        // otherwise we just drop the object, to return null
-                        process = null;
-                    }
-                }
-                // return the process
-                return process;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Construct the object with a library name.
-     * <br>The library should be in a format that makes<br>
-     * <code>$ANDROID_PRODUCT_OUT + "/symbols" + library</code> a valid file.
-     *
-     * @param library the library in which to look for address.
-     */
-    private Addr2Line(final String library) {
-        mLibrary = library;
-    }
-
-    /**
-     * Starts the command line process.
-     *
-     * @return true if the process was started, false if it failed to start, or
-     *         if there was any other errors.
-     */
-    private boolean start() {
-        // because this is only called from getProcess() we know we don't need
-        // to synchronize this code.
-
-        // get the output directory.
-        String symbols = System.getenv("ANDROID_SYMBOLS");
-        if (symbols == null) {
-            symbols = DdmUiPreferences.getSymbolDirectory();
-        }
-
-        // build the command line
-        String[] command = new String[5];
-        command[0] = DdmUiPreferences.getAddr2Line();
-        command[1] = "-C";
-        command[2] = "-f";
-        command[3] = "-e";
-        command[4] = symbols + mLibrary.replaceAll("libc\\.so", "libc_debug\\.so");
-
-        try {
-            // attempt to start the process
-            mProcess = Runtime.getRuntime().exec(command);
-
-            if (mProcess != null) {
-                // get the result reader
-                InputStreamReader is = new InputStreamReader(mProcess
-                        .getInputStream());
-                mResultReader = new BufferedReader(is);
-
-                // get the outstream to write the addresses
-                mAddressWriter = new BufferedOutputStream(mProcess
-                        .getOutputStream());
-
-                // check our streams are here
-                if (mResultReader == null || mAddressWriter == null) {
-                    // not here? stop the process and return false;
-                    mProcess.destroy();
-                    mProcess = null;
-                    return false;
-                }
-
-                // return a success
-                return true;
-            }
-
-        } catch (IOException e) {
-            // log the error
-            String msg = String.format(
-                    "Error while trying to start %1$s process for library %2$s",
-                    DdmUiPreferences.getAddr2Line(), mLibrary);
-            Log.e("ddm-Addr2Line", msg);
-
-            // drop the process just in case
-            if (mProcess != null) {
-                mProcess.destroy();
-                mProcess = null;
-            }
-        }
-
-        // we can be here either cause the allocation of mProcess failed, or we
-        // caught an exception
-        return false;
-    }
-
-    /**
-     * Stops the command line process.
-     */
-    public void stop() {
-        synchronized (sProcessCache) {
-            if (mProcess != null) {
-                // remove the process from the list
-                sProcessCache.remove(mLibrary);
-
-                // then stops the process
-                mProcess.destroy();
-
-                // set the reference to null.
-                // this allows to make sure another thread calling getAddress()
-                // will not query a stopped thread
-                mProcess = null;
-            }
-        }
-    }
-
-    /**
-     * Stops all current running processes.
-     */
-    public static void stopAll() {
-        // because of concurrent access (and our use of HashMap.values()), we
-        // can't rely on the synchronized inside stop(). We need to put one
-        // around the whole loop.
-        synchronized (sProcessCache) {
-            // just a basic loop on all the values in the hashmap and call to
-            // stop();
-            Collection<Addr2Line> col = sProcessCache.values();
-            for (Addr2Line a2l : col) {
-                a2l.stop();
-            }
-        }
-    }
-
-    /**
-     * Looks up an address and returns method name, source file name, and line
-     * number.
-     *
-     * @param addr the address to look up
-     * @return a BacktraceInfo object containing the method/filename/linenumber
-     *         or null if the process we stopped before the query could be
-     *         processed, or if an IO exception happened.
-     */
-    public NativeStackCallInfo getAddress(long addr) {
-        // even though we don't access the hashmap object, we need to
-        // synchronized on it to prevent
-        // another thread from stopping the process we're going to query.
-        synchronized (sProcessCache) {
-            // check the process is still alive/allocated
-            if (mProcess != null) {
-                // prepare to the write the address to the output buffer.
-
-                // first, conversion to a string containing the hex value.
-                String tmp = Long.toString(addr, 16);
-
-                try {
-                    // write the address to the buffer
-                    mAddressWriter.write(tmp.getBytes());
-
-                    // add CR-LF
-                    mAddressWriter.write(sCrLf);
-
-                    // flush it all.
-                    mAddressWriter.flush();
-
-                    // read the result. We need to read 2 lines
-                    String method = mResultReader.readLine();
-                    String source = mResultReader.readLine();
-
-                    // make the backtrace object and return it
-                    if (method != null && source != null) {
-                        return new NativeStackCallInfo(mLibrary, method, source);
-                    }
-                } catch (IOException e) {
-                    // log the error
-                    Log.e("ddms",
-                            "Error while trying to get information for addr: "
-                                    + tmp + " in library: " + mLibrary);
-                    // we'll return null later
-                }
-            }
-        }
-        return null;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/AllocationPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/AllocationPanel.java
deleted file mode 100644
index 11c0e19..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/AllocationPanel.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.AllocationInfo;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.ClientData.AllocationTrackingStatus;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Sash;
-import org.eclipse.swt.widgets.Table;
-
-/**
- * Base class for our information panels.
- */
-public class AllocationPanel extends TablePanel {
-
-    private final static String PREFS_ALLOC_COL_SIZE = "allocPanel.Col0"; //$NON-NLS-1$
-    private final static String PREFS_ALLOC_COL_CLASS = "allocPanel.Col1"; //$NON-NLS-1$
-    private final static String PREFS_ALLOC_COL_THREAD = "allocPanel.Col2"; //$NON-NLS-1$
-    private final static String PREFS_ALLOC_COL_TRACE_CLASS = "allocPanel.Col3"; //$NON-NLS-1$
-    private final static String PREFS_ALLOC_COL_TRACE_METHOD = "allocPanel.Col4"; //$NON-NLS-1$
-
-    private final static String PREFS_ALLOC_SASH = "allocPanel.sash"; //$NON-NLS-1$
-
-    private static final String PREFS_STACK_COL_CLASS = "allocPanel.stack.col0"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_METHOD = "allocPanel.stack.col1"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_FILE = "allocPanel.stack.col2"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_LINE = "allocPanel.stack.col3"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_NATIVE = "allocPanel.stack.col4"; //$NON-NLS-1$
-
-    private Composite mAllocationBase;
-    private Table mAllocationTable;
-    private TableViewer mAllocationViewer;
-
-    private StackTracePanel mStackTracePanel;
-    private Table mStackTraceTable;
-    private Button mEnableButton;
-    private Button mRequestButton;
-
-    /**
-     * Content Provider to display the allocations of a client.
-     * Expected input is a {@link Client} object, elements used in the table are of type
-     * {@link AllocationInfo}.
-     */
-    private static class AllocationContentProvider implements IStructuredContentProvider {
-        public Object[] getElements(Object inputElement) {
-            if (inputElement instanceof Client) {
-                AllocationInfo[] allocs = ((Client)inputElement).getClientData().getAllocations();
-                if (allocs != null) {
-                    return allocs;
-                }
-            }
-
-            return new Object[0];
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            // pass
-        }
-    }
-
-    /**
-     * A Label Provider to use with {@link AllocationContentProvider}. It expects the elements to be
-     * of type {@link AllocationInfo}.
-     */
-    private static class AllocationLabelProvider implements ITableLabelProvider {
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            return null;
-        }
-
-        public String getColumnText(Object element, int columnIndex) {
-            if (element instanceof AllocationInfo) {
-                AllocationInfo alloc = (AllocationInfo)element;
-                switch (columnIndex) {
-                    case 0:
-                        return Integer.toString(alloc.getSize());
-                    case 1:
-                        return alloc.getAllocatedClass();
-                    case 2:
-                        return Short.toString(alloc.getThreadId());
-                    case 3:
-                        StackTraceElement[] traces = alloc.getStackTrace();
-                        if (traces.length > 0) {
-                            return traces[0].getClassName();
-                        }
-                        break;
-                    case 4:
-                        traces = alloc.getStackTrace();
-                        if (traces.length > 0) {
-                            return traces[0].getMethodName();
-                        }
-                        break;
-                }
-            }
-
-            return null;
-        }
-
-        public void addListener(ILabelProviderListener listener) {
-            // pass
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public boolean isLabelProperty(Object element, String property) {
-            // pass
-            return false;
-        }
-
-        public void removeListener(ILabelProviderListener listener) {
-            // pass
-        }
-    }
-
-    /**
-     * Create our control(s).
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        final IPreferenceStore store = DdmUiPreferences.getStore();
-
-        // base composite for selected client with enabled thread update.
-        mAllocationBase = new Composite(parent, SWT.NONE);
-        mAllocationBase.setLayout(new FormLayout());
-
-        // table above the sash
-        Composite topParent = new Composite(mAllocationBase, SWT.NONE);
-        topParent.setLayout(new GridLayout(2, false));
-
-        mEnableButton = new Button(topParent, SWT.PUSH);
-        mEnableButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                Client current = getCurrentClient();
-                AllocationTrackingStatus status = current.getClientData().getAllocationStatus();
-                if (status == AllocationTrackingStatus.ON) {
-                    current.enableAllocationTracker(false);
-                } else {
-                    current.enableAllocationTracker(true);
-                }
-                current.requestAllocationStatus();
-            }
-        });
-
-        mRequestButton = new Button(topParent, SWT.PUSH);
-        mRequestButton.setText("Get Allocations");
-        mRequestButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                getCurrentClient().requestAllocationDetails();
-            }
-        });
-
-        setUpButtons(false /* enabled */, AllocationTrackingStatus.OFF);
-
-        mAllocationTable = new Table(topParent, SWT.MULTI | SWT.FULL_SELECTION);
-        GridData gridData;
-        mAllocationTable.setLayoutData(gridData = new GridData(GridData.FILL_BOTH));
-        gridData.horizontalSpan = 2;
-        mAllocationTable.setHeaderVisible(true);
-        mAllocationTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(
-                mAllocationTable,
-                "Allocation Size",
-                SWT.RIGHT,
-                "888", //$NON-NLS-1$
-                PREFS_ALLOC_COL_SIZE, store);
-
-        TableHelper.createTableColumn(
-                mAllocationTable,
-                "Allocated Class",
-                SWT.LEFT,
-                "Allocated Class", //$NON-NLS-1$
-                PREFS_ALLOC_COL_CLASS, store);
-
-        TableHelper.createTableColumn(
-                mAllocationTable,
-                "Thread Id",
-                SWT.LEFT,
-                "999", //$NON-NLS-1$
-                PREFS_ALLOC_COL_THREAD, store);
-
-        TableHelper.createTableColumn(
-                mAllocationTable,
-                "Allocated in",
-                SWT.LEFT,
-                "utime", //$NON-NLS-1$
-                PREFS_ALLOC_COL_TRACE_CLASS, store);
-
-        TableHelper.createTableColumn(
-                mAllocationTable,
-                "Allocated in",
-                SWT.LEFT,
-                "utime", //$NON-NLS-1$
-                PREFS_ALLOC_COL_TRACE_METHOD, store);
-
-        mAllocationViewer = new TableViewer(mAllocationTable);
-        mAllocationViewer.setContentProvider(new AllocationContentProvider());
-        mAllocationViewer.setLabelProvider(new AllocationLabelProvider());
-
-        mAllocationViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                AllocationInfo selectedAlloc = getAllocationSelection(event.getSelection());
-                updateAllocationStackTrace(selectedAlloc);
-            }
-        });
-
-        // the separating sash
-        final Sash sash = new Sash(mAllocationBase, SWT.HORIZONTAL);
-        Color darkGray = parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
-        sash.setBackground(darkGray);
-
-        // the UI below the sash
-        mStackTracePanel = new StackTracePanel();
-        mStackTraceTable = mStackTracePanel.createPanel(mAllocationBase,
-                PREFS_STACK_COL_CLASS,
-                PREFS_STACK_COL_METHOD,
-                PREFS_STACK_COL_FILE,
-                PREFS_STACK_COL_LINE,
-                PREFS_STACK_COL_NATIVE,
-                store);
-
-        // now setup the sash.
-        // form layout data
-        FormData data = new FormData();
-        data.top = new FormAttachment(0, 0);
-        data.bottom = new FormAttachment(sash, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        topParent.setLayoutData(data);
-
-        final FormData sashData = new FormData();
-        if (store != null && store.contains(PREFS_ALLOC_SASH)) {
-            sashData.top = new FormAttachment(0, store.getInt(PREFS_ALLOC_SASH));
-        } else {
-            sashData.top = new FormAttachment(50,0); // 50% across
-        }
-        sashData.left = new FormAttachment(0, 0);
-        sashData.right = new FormAttachment(100, 0);
-        sash.setLayoutData(sashData);
-
-        data = new FormData();
-        data.top = new FormAttachment(sash, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        mStackTraceTable.setLayoutData(data);
-
-        // allow resizes, but cap at minPanelWidth
-        sash.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                Rectangle sashRect = sash.getBounds();
-                Rectangle panelRect = mAllocationBase.getClientArea();
-                int bottom = panelRect.height - sashRect.height - 100;
-                e.y = Math.max(Math.min(e.y, bottom), 100);
-                if (e.y != sashRect.y) {
-                    sashData.top = new FormAttachment(0, e.y);
-                    store.setValue(PREFS_ALLOC_SASH, e.y);
-                    mAllocationBase.layout();
-                }
-            }
-        });
-
-        return mAllocationBase;
-    }
-
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        mAllocationTable.setFocus();
-    }
-
-    /**
-     * Sent when an existing client information changed.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param client the updated client.
-     * @param changeMask the bit mask describing the changed properties. It can contain
-     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-     * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-     * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-     *
-     * @see IClientChangeListener#clientChanged(Client, int)
-     */
-    public void clientChanged(final Client client, int changeMask) {
-        if (client == getCurrentClient()) {
-            if ((changeMask & Client.CHANGE_HEAP_ALLOCATIONS) != 0) {
-                try {
-                    mAllocationTable.getDisplay().asyncExec(new Runnable() {
-                        public void run() {
-                            mAllocationViewer.refresh();
-                            updateAllocationStackCall();
-                        }
-                    });
-                } catch (SWTException e) {
-                    // widget is disposed, we do nothing
-                }
-            } else if ((changeMask & Client.CHANGE_HEAP_ALLOCATION_STATUS) != 0) {
-                try {
-                    mAllocationTable.getDisplay().asyncExec(new Runnable() {
-                        public void run() {
-                            setUpButtons(true, client.getClientData().getAllocationStatus());
-                        }
-                    });
-                } catch (SWTException e) {
-                    // widget is disposed, we do nothing
-                }
-            }
-        }
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}.
-     */
-    @Override
-    public void deviceSelected() {
-        // pass
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}.
-     */
-    @Override
-    public void clientSelected() {
-        if (mAllocationTable.isDisposed()) {
-            return;
-        }
-
-        Client client = getCurrentClient();
-
-        mStackTracePanel.setCurrentClient(client);
-        mStackTracePanel.setViewerInput(null); // always empty on client selection change.
-
-        if (client != null) {
-            setUpButtons(true /* enabled */, client.getClientData().getAllocationStatus());
-        } else {
-            setUpButtons(false /* enabled */, AllocationTrackingStatus.OFF);
-        }
-
-        mAllocationViewer.setInput(client);
-    }
-
-    /**
-     * Updates the stack call of the currently selected thread.
-     * <p/>
-     * This <b>must</b> be called from the UI thread.
-     */
-    private void updateAllocationStackCall() {
-        Client client = getCurrentClient();
-        if (client != null) {
-            // get the current selection in the ThreadTable
-            AllocationInfo selectedAlloc = getAllocationSelection(null);
-
-            if (selectedAlloc != null) {
-                updateAllocationStackTrace(selectedAlloc);
-            } else {
-                updateAllocationStackTrace(null);
-            }
-        }
-    }
-
-    /**
-     * updates the stackcall of the specified allocation. If <code>null</code> the UI is emptied
-     * of current data.
-     * @param thread
-     */
-    private void updateAllocationStackTrace(AllocationInfo alloc) {
-        mStackTracePanel.setViewerInput(alloc);
-    }
-
-    @Override
-    protected void setTableFocusListener() {
-        addTableToFocusListener(mAllocationTable);
-        addTableToFocusListener(mStackTraceTable);
-    }
-
-    /**
-     * Returns the current allocation selection or <code>null</code> if none is found.
-     * If a {@link ISelection} object is specified, the first {@link AllocationInfo} from this
-     * selection is returned, otherwise, the <code>ISelection</code> returned by
-     * {@link TableViewer#getSelection()} is used.
-     * @param selection the {@link ISelection} to use, or <code>null</code>
-     */
-    private AllocationInfo getAllocationSelection(ISelection selection) {
-        if (selection == null) {
-            selection = mAllocationViewer.getSelection();
-        }
-
-        if (selection instanceof IStructuredSelection) {
-            IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-            Object object = structuredSelection.getFirstElement();
-            if (object instanceof AllocationInfo) {
-                return (AllocationInfo)object;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     *
-     * @param enabled
-     * @param trackingStatus
-     */
-    private void setUpButtons(boolean enabled, AllocationTrackingStatus trackingStatus) {
-        if (enabled) {
-            switch (trackingStatus) {
-                case UNKNOWN:
-                    mEnableButton.setText("?");
-                    mEnableButton.setEnabled(false);
-                    mRequestButton.setEnabled(false);
-                    break;
-                case OFF:
-                    mEnableButton.setText("Start Tracking");
-                    mEnableButton.setEnabled(true);
-                    mRequestButton.setEnabled(false);
-                    break;
-                case ON:
-                    mEnableButton.setText("Stop Tracking");
-                    mEnableButton.setEnabled(true);
-                    mRequestButton.setEnabled(true);
-                    break;
-            }
-        } else {
-            mEnableButton.setEnabled(false);
-            mRequestButton.setEnabled(false);
-            mEnableButton.setText("Start Tracking");
-        }
-    }
-}
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BackgroundThread.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BackgroundThread.java
deleted file mode 100644
index 0ed4c95..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BackgroundThread.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Log;
-
-/**
- * base background thread class. The class provides a synchronous quit method
- * which sets a quitting flag to true. Inheriting classes should regularly test
- * this flag with <code>isQuitting()</code> and should finish if the flag is
- * true.
- */
-public abstract class BackgroundThread extends Thread {
-    private boolean mQuit = false;
-
-    /**
-     * Tell the thread to exit. This is usually called from the UI thread. The
-     * call is synchronous and will only return once the thread has terminated
-     * itself.
-     */
-    public final void quit() {
-        mQuit = true;
-        Log.d("ddms", "Waiting for BackgroundThread to quit");
-        try {
-            this.join();
-        } catch (InterruptedException ie) {
-            ie.printStackTrace();
-        }
-    }
-
-    /** returns if the thread was asked to quit. */
-    protected final boolean isQuitting() {
-        return mQuit;
-    }
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java
deleted file mode 100644
index 3e66ea5..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.HeapSegment;
-import com.android.ddmlib.ClientData.HeapData;
-import com.android.ddmlib.HeapSegment.HeapSegmentElement;
-
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.PaletteData;
-
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
-
-
-/**
- * Base Panel for heap panels.
- */
-public abstract class BaseHeapPanel extends TablePanel {
-
-    /** store the processed heap segment, so that we don't recompute Image for nothing */
-    protected byte[] mProcessedHeapData;
-    private Map<Integer, ArrayList<HeapSegmentElement>> mHeapMap;
-
-    /**
-     * Serialize the heap data into an array. The resulting array is available through
-     * <code>getSerializedData()</code>.
-     * @param heapData The heap data to serialize
-     * @return true if the data changed.
-     */
-    protected boolean serializeHeapData(HeapData heapData) {
-        Collection<HeapSegment> heapSegments;
-
-        // Atomically get and clear the heap data.
-        synchronized (heapData) {
-            // get the segments
-            heapSegments = heapData.getHeapSegments();
-            
-            
-            if (heapSegments != null) {
-                // if they are not null, we never processed them.
-                // Before we process then, we drop them from the HeapData
-                heapData.clearHeapData();
-
-                // process them into a linear byte[]
-                doSerializeHeapData(heapSegments);
-                heapData.setProcessedHeapData(mProcessedHeapData);
-                heapData.setProcessedHeapMap(mHeapMap);
-                
-            } else {
-                // the heap segments are null. Let see if the heapData contains a 
-                // list that is already processed.
-                
-                byte[] pixData = heapData.getProcessedHeapData();
-                
-                // and compare it to the one we currently have in the panel.
-                if (pixData == mProcessedHeapData) {
-                    // looks like its the same
-                    return false;
-                } else {
-                    mProcessedHeapData = pixData;
-                }
-                
-                Map<Integer, ArrayList<HeapSegmentElement>> heapMap =
-                    heapData.getProcessedHeapMap();
-                mHeapMap = heapMap;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns the serialized heap data
-     */
-    protected byte[] getSerializedData() {
-        return mProcessedHeapData;
-    }
-
-    /**
-     * Processes and serialize the heapData.
-     * <p/>
-     * The resulting serialized array is {@link #mProcessedHeapData}.
-     * <p/>
-     * the resulting map is {@link #mHeapMap}.
-     * @param heapData the collection of {@link HeapSegment} that forms the heap data.
-     */
-    private void doSerializeHeapData(Collection<HeapSegment> heapData) {
-        mHeapMap = new TreeMap<Integer, ArrayList<HeapSegmentElement>>();
-
-        Iterator<HeapSegment> iterator;
-        ByteArrayOutputStream out;
-
-        out = new ByteArrayOutputStream(4 * 1024);
-
-        iterator = heapData.iterator();
-        while (iterator.hasNext()) {
-            HeapSegment hs = iterator.next();
-
-            HeapSegmentElement e = null;
-            while (true) {
-                int v;
-
-                e = hs.getNextElement(null);
-                if (e == null) {
-                    break;
-                }
-                
-                if (e.getSolidity() == HeapSegmentElement.SOLIDITY_FREE) {
-                    v = 1;
-                } else {
-                    v = e.getKind() + 2;
-                }
-                
-                // put the element in the map
-                ArrayList<HeapSegmentElement> elementList = mHeapMap.get(v);
-                if (elementList == null) {
-                    elementList = new ArrayList<HeapSegmentElement>();
-                    mHeapMap.put(v, elementList);
-                }
-                elementList.add(e);
-
-
-                int len = e.getLength() / 8;
-                while (len > 0) {
-                    out.write(v);
-                    --len;
-                }
-            }
-        }
-        mProcessedHeapData = out.toByteArray();
-        
-        // sort the segment element in the heap info.
-        Collection<ArrayList<HeapSegmentElement>> elementLists = mHeapMap.values();
-        for (ArrayList<HeapSegmentElement> elementList : elementLists) {
-            Collections.sort(elementList);
-        }
-    }
-    
-    /**
-     * Creates a linear image of the heap data.
-     * @param pixData
-     * @param h
-     * @param palette
-     * @return
-     */
-    protected ImageData createLinearHeapImage(byte[] pixData, int h, PaletteData palette) {
-        int w = pixData.length / h;
-        if (pixData.length % h != 0) {
-            w++;
-        }
-
-        // Create the heap image.
-        ImageData id = new ImageData(w, h, 8, palette);
-
-        int x = 0;
-        int y = 0;
-        for (byte b : pixData) {
-            if (b >= 0) {
-                id.setPixel(x, y, b);
-            }
-
-            y++;
-            if (y >= h) {
-                y = 0;
-                x++;
-            }
-        }
-
-        return id;
-    }
-
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ClientDisplayPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ClientDisplayPanel.java
deleted file mode 100644
index a711933..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ClientDisplayPanel.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-
-public abstract class ClientDisplayPanel extends SelectionDependentPanel
-        implements IClientChangeListener {
-
-    @Override
-    protected void postCreation() {
-        AndroidDebugBridge.addClientChangeListener(this);
-    }
-
-    public void dispose() {
-        AndroidDebugBridge.removeClientChangeListener(this);
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DdmUiPreferences.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DdmUiPreferences.java
deleted file mode 100644
index f832a4e..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DdmUiPreferences.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * Preference entry point for ddmuilib. Allows the lib to access a preference
- * store (org.eclipse.jface.preference.IPreferenceStore) defined by the
- * application that includes the lib.
- */
-public final class DdmUiPreferences {
-
-    public static final int DEFAULT_THREAD_REFRESH_INTERVAL = 4;  // seconds
-
-    private static int sThreadRefreshInterval = DEFAULT_THREAD_REFRESH_INTERVAL;
-    
-    private static IPreferenceStore mStore;
-    
-    private static String sSymbolLocation =""; //$NON-NLS-1$
-    private static String sAddr2LineLocation =""; //$NON-NLS-1$
-    private static String sTraceviewLocation =""; //$NON-NLS-1$
-
-    public static void setStore(IPreferenceStore store) {
-        mStore = store;
-    }
-    
-    public static IPreferenceStore getStore() {
-        return mStore;
-    }
-
-    public static int getThreadRefreshInterval() {
-        return sThreadRefreshInterval;
-    }
-
-    public static void setThreadRefreshInterval(int port) {
-        sThreadRefreshInterval = port;
-    }
-    
-    static String getSymbolDirectory() {
-        return sSymbolLocation;
-    }
-
-    public static void setSymbolsLocation(String location) {
-        sSymbolLocation = location;
-    }
-
-    static String getAddr2Line() {
-        return sAddr2LineLocation;
-    }
-
-    public static void setAddr2LineLocation(String location) {
-        sAddr2LineLocation = location;
-    }
-
-    public static String getTraceview() {
-        return sTraceviewLocation;
-    }
-
-    public static void setTraceviewLocation(String location) {
-        sTraceviewLocation = location;
-    }
-
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java
deleted file mode 100644
index 691692f..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.DdmPreferences;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ddmlib.ClientData.DebuggerStatus;
-import com.android.ddmlib.IDevice.DeviceState;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
-
-import java.util.ArrayList;
-
-/**
- * A display of both the devices and their clients.
- */
-public final class DevicePanel extends Panel implements IDebugBridgeChangeListener,
-        IDeviceChangeListener, IClientChangeListener {
-
-    private final static String PREFS_COL_NAME_SERIAL = "devicePanel.Col0"; //$NON-NLS-1$
-    private final static String PREFS_COL_PID_STATE = "devicePanel.Col1"; //$NON-NLS-1$
-    private final static String PREFS_COL_PORT_BUILD = "devicePanel.Col4"; //$NON-NLS-1$
-
-    private final static int DEVICE_COL_SERIAL = 0;
-    private final static int DEVICE_COL_STATE = 1;
-    // col 2, 3 not used.
-    private final static int DEVICE_COL_BUILD = 4;
-
-    private final static int CLIENT_COL_NAME = 0;
-    private final static int CLIENT_COL_PID = 1;
-    private final static int CLIENT_COL_THREAD = 2;
-    private final static int CLIENT_COL_HEAP = 3;
-    private final static int CLIENT_COL_PORT = 4;
-
-    public final static int ICON_WIDTH = 16;
-    public final static String ICON_THREAD = "thread.png"; //$NON-NLS-1$
-    public final static String ICON_HEAP = "heap.png"; //$NON-NLS-1$
-    public final static String ICON_HALT = "halt.png"; //$NON-NLS-1$
-    public final static String ICON_GC = "gc.png"; //$NON-NLS-1$
-    public final static String ICON_HPROF = "hprof.png"; //$NON-NLS-1$
-    public final static String ICON_TRACING_START = "tracing_start.png"; //$NON-NLS-1$
-    public final static String ICON_TRACING_STOP = "tracing_stop.png"; //$NON-NLS-1$
-
-    private IDevice mCurrentDevice;
-    private Client mCurrentClient;
-
-    private Tree mTree;
-    private TreeViewer mTreeViewer;
-
-    private Image mDeviceImage;
-    private Image mEmulatorImage;
-
-    private Image mThreadImage;
-    private Image mHeapImage;
-    private Image mWaitingImage;
-    private Image mDebuggerImage;
-    private Image mDebugErrorImage;
-
-    private final ArrayList<IUiSelectionListener> mListeners = new ArrayList<IUiSelectionListener>();
-
-    private final ArrayList<IDevice> mDevicesToExpand = new ArrayList<IDevice>();
-
-    private IImageLoader mLoader;
-
-    private boolean mAdvancedPortSupport;
-
-    /**
-     * A Content provider for the {@link TreeViewer}.
-     * <p/>
-     * The input is a {@link AndroidDebugBridge}. First level elements are {@link IDevice} objects,
-     * and second level elements are {@link Client} object.
-     */
-    private class ContentProvider implements ITreeContentProvider {
-        public Object[] getChildren(Object parentElement) {
-            if (parentElement instanceof IDevice) {
-                return ((IDevice)parentElement).getClients();
-            }
-            return new Object[0];
-        }
-
-        public Object getParent(Object element) {
-            if (element instanceof Client) {
-                return ((Client)element).getDevice();
-            }
-            return null;
-        }
-
-        public boolean hasChildren(Object element) {
-            if (element instanceof IDevice) {
-                return ((IDevice)element).hasClients();
-            }
-
-            // Clients never have children.
-            return false;
-        }
-
-        public Object[] getElements(Object inputElement) {
-            if (inputElement instanceof AndroidDebugBridge) {
-                return ((AndroidDebugBridge)inputElement).getDevices();
-            }
-            return new Object[0];
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            // pass
-        }
-    }
-
-    /**
-     * A Label Provider for the {@link TreeViewer} in {@link DevicePanel}. It provides
-     * labels and images for {@link IDevice} and {@link Client} objects.
-     */
-    private class LabelProvider implements ITableLabelProvider {
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            if (columnIndex == DEVICE_COL_SERIAL && element instanceof IDevice) {
-                IDevice device = (IDevice)element;
-                if (device.isEmulator()) {
-                    return mEmulatorImage;
-                }
-
-                return mDeviceImage;
-            } else if (element instanceof Client) {
-                Client client = (Client)element;
-                ClientData cd = client.getClientData();
-
-                switch (columnIndex) {
-                    case CLIENT_COL_NAME:
-                        switch (cd.getDebuggerConnectionStatus()) {
-                            case DEFAULT:
-                                return null;
-                            case WAITING:
-                                return mWaitingImage;
-                            case ATTACHED:
-                                return mDebuggerImage;
-                            case ERROR:
-                                return mDebugErrorImage;
-                        }
-                        return null;
-                    case CLIENT_COL_THREAD:
-                        if (client.isThreadUpdateEnabled()) {
-                            return mThreadImage;
-                        }
-                        return null;
-                    case CLIENT_COL_HEAP:
-                        if (client.isHeapUpdateEnabled()) {
-                            return mHeapImage;
-                        }
-                        return null;
-                }
-            }
-            return null;
-        }
-
-        public String getColumnText(Object element, int columnIndex) {
-            if (element instanceof IDevice) {
-                IDevice device = (IDevice)element;
-                switch (columnIndex) {
-                    case DEVICE_COL_SERIAL:
-                        return device.getSerialNumber();
-                    case DEVICE_COL_STATE:
-                        return getStateString(device);
-                    case DEVICE_COL_BUILD: {
-                        String version = device.getProperty(IDevice.PROP_BUILD_VERSION);
-                        if (version != null) {
-                            String debuggable = device.getProperty(IDevice.PROP_DEBUGGABLE);
-                            if (device.isEmulator()) {
-                                String avdName = device.getAvdName();
-                                if (avdName == null) {
-                                    avdName = "?"; // the device is probably not online yet, so
-                                                   // we don't know its AVD name just yet.
-                                }
-                                if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$
-                                    return String.format("%1$s [%2$s, debug]", avdName,
-                                            version);
-                                } else {
-                                    return String.format("%1$s [%2$s]", avdName, version); //$NON-NLS-1$
-                                }
-                            } else {
-                                if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$
-                                    return String.format("%1$s, debug", version);
-                                } else {
-                                    return String.format("%1$s", version); //$NON-NLS-1$
-                                }
-                            }
-                        } else {
-                            return "unknown";
-                        }
-                    }
-                }
-            } else if (element instanceof Client) {
-                Client client = (Client)element;
-                ClientData cd = client.getClientData();
-
-                switch (columnIndex) {
-                    case CLIENT_COL_NAME:
-                        String name = cd.getClientDescription();
-                        if (name != null) {
-                            return name;
-                        }
-                        return "?";
-                    case CLIENT_COL_PID:
-                        return Integer.toString(cd.getPid());
-                    case CLIENT_COL_PORT:
-                        if (mAdvancedPortSupport) {
-                            int port = client.getDebuggerListenPort();
-                            String portString = "?";
-                            if (port != 0) {
-                                portString = Integer.toString(port);
-                            }
-                            if (client.isSelectedClient()) {
-                                return String.format("%1$s / %2$d", portString, //$NON-NLS-1$
-                                        DdmPreferences.getSelectedDebugPort());
-                            }
-
-                            return portString;
-                        }
-                }
-            }
-            return null;
-        }
-
-        public void addListener(ILabelProviderListener listener) {
-            // pass
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public boolean isLabelProperty(Object element, String property) {
-            // pass
-            return false;
-        }
-
-        public void removeListener(ILabelProviderListener listener) {
-            // pass
-        }
-    }
-
-    /**
-     * Classes which implement this interface provide methods that deals
-     * with {@link IDevice} and {@link Client} selection changes coming from the ui.
-     */
-    public interface IUiSelectionListener {
-        /**
-         * Sent when a new {@link IDevice} and {@link Client} are selected.
-         * @param selectedDevice the selected device. If null, no devices are selected.
-         * @param selectedClient The selected client. If null, no clients are selected.
-         */
-        public void selectionChanged(IDevice selectedDevice, Client selectedClient);
-    }
-
-    /**
-     * Creates the {@link DevicePanel} object.
-     * @param loader
-     * @param advancedPortSupport if true the device panel will add support for selected client port
-     * and display the ports in the ui.
-     */
-    public DevicePanel(IImageLoader loader, boolean advancedPortSupport) {
-        mLoader = loader;
-        mAdvancedPortSupport = advancedPortSupport;
-    }
-
-    public void addSelectionListener(IUiSelectionListener listener) {
-        mListeners.add(listener);
-    }
-
-    public void removeSelectionListener(IUiSelectionListener listener) {
-        mListeners.remove(listener);
-    }
-
-    @Override
-    protected Control createControl(Composite parent) {
-        loadImages(parent.getDisplay(), mLoader);
-
-        parent.setLayout(new FillLayout());
-
-        // create the tree and its column
-        mTree = new Tree(parent, SWT.SINGLE | SWT.FULL_SELECTION);
-        mTree.setHeaderVisible(true);
-        mTree.setLinesVisible(true);
-
-        IPreferenceStore store = DdmUiPreferences.getStore();
-
-        TableHelper.createTreeColumn(mTree, "Name", SWT.LEFT,
-                "com.android.home", //$NON-NLS-1$
-                PREFS_COL_NAME_SERIAL, store);
-        TableHelper.createTreeColumn(mTree, "", SWT.LEFT, //$NON-NLS-1$
-                "Offline", //$NON-NLS-1$
-                PREFS_COL_PID_STATE, store);
-
-        TreeColumn col = new TreeColumn(mTree, SWT.NONE);
-        col.setWidth(ICON_WIDTH + 8);
-        col.setResizable(false);
-        col = new TreeColumn(mTree, SWT.NONE);
-        col.setWidth(ICON_WIDTH + 8);
-        col.setResizable(false);
-
-        TableHelper.createTreeColumn(mTree, "", SWT.LEFT, //$NON-NLS-1$
-                "9999-9999", //$NON-NLS-1$
-                PREFS_COL_PORT_BUILD, store);
-
-        // create the tree viewer
-        mTreeViewer = new TreeViewer(mTree);
-
-        // make the device auto expanded.
-        mTreeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
-
-        // set up the content and label providers.
-        mTreeViewer.setContentProvider(new ContentProvider());
-        mTreeViewer.setLabelProvider(new LabelProvider());
-
-        mTree.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                notifyListeners();
-            }
-        });
-
-        return mTree;
-    }
-
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        mTree.setFocus();
-    }
-
-    @Override
-    protected void postCreation() {
-        // ask for notification of changes in AndroidDebugBridge (a new one is created when
-        // adb is restarted from a different location), IDevice and Client objects.
-        AndroidDebugBridge.addDebugBridgeChangeListener(this);
-        AndroidDebugBridge.addDeviceChangeListener(this);
-        AndroidDebugBridge.addClientChangeListener(this);
-    }
-
-    public void dispose() {
-        AndroidDebugBridge.removeDebugBridgeChangeListener(this);
-        AndroidDebugBridge.removeDeviceChangeListener(this);
-        AndroidDebugBridge.removeClientChangeListener(this);
-    }
-
-    /**
-     * Returns the selected {@link Client}. May be null.
-     */
-    public Client getSelectedClient() {
-        return mCurrentClient;
-    }
-
-    /**
-     * Returns the selected {@link IDevice}. If a {@link Client} is selected, it returns the
-     * IDevice object containing the client.
-     */
-    public IDevice getSelectedDevice() {
-        return mCurrentDevice;
-    }
-
-    /**
-     * Kills the selected {@link Client} by sending its VM a halt command.
-     */
-    public void killSelectedClient() {
-        if (mCurrentClient != null) {
-            Client client = mCurrentClient;
-
-            // reset the selection to the device.
-            TreePath treePath = new TreePath(new Object[] { mCurrentDevice });
-            TreeSelection treeSelection = new TreeSelection(treePath);
-            mTreeViewer.setSelection(treeSelection);
-
-            client.kill();
-        }
-    }
-
-    /**
-     * Forces a GC on the selected {@link Client}.
-     */
-    public void forceGcOnSelectedClient() {
-        if (mCurrentClient != null) {
-            mCurrentClient.executeGarbageCollector();
-        }
-    }
-
-    public void dumpHprof() {
-        if (mCurrentClient != null) {
-            mCurrentClient.dumpHprof();
-        }
-    }
-
-    public void toggleMethodProfiling() {
-        if (mCurrentClient != null) {
-            mCurrentClient.toggleMethodProfiling();
-        }
-    }
-
-    public void setEnabledHeapOnSelectedClient(boolean enable) {
-        if (mCurrentClient != null) {
-            mCurrentClient.setHeapUpdateEnabled(enable);
-        }
-    }
-
-    public void setEnabledThreadOnSelectedClient(boolean enable) {
-        if (mCurrentClient != null) {
-            mCurrentClient.setThreadUpdateEnabled(enable);
-        }
-    }
-
-    /**
-     * Sent when a new {@link AndroidDebugBridge} is started.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param bridge the new {@link AndroidDebugBridge} object.
-     *
-     * @see IDebugBridgeChangeListener#serverChanged(AndroidDebugBridge)
-     */
-    public void bridgeChanged(final AndroidDebugBridge bridge) {
-        if (mTree.isDisposed() == false) {
-            exec(new Runnable() {
-                public void run() {
-                    if (mTree.isDisposed() == false) {
-                        // set up the data source.
-                        mTreeViewer.setInput(bridge);
-
-                        // notify the listener of a possible selection change.
-                        notifyListeners();
-                    } else {
-                        // tree is disposed, we need to do something.
-                        // lets remove ourselves from the listener.
-                        AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
-                        AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
-                        AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
-                    }
-                }
-            });
-        }
-
-        // all current devices are obsolete
-        synchronized (mDevicesToExpand) {
-            mDevicesToExpand.clear();
-        }
-    }
-
-    /**
-     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceConnected(IDevice)
-     */
-    public void deviceConnected(IDevice device) {
-        exec(new Runnable() {
-            public void run() {
-                if (mTree.isDisposed() == false) {
-                    // refresh all
-                    mTreeViewer.refresh();
-
-                    // notify the listener of a possible selection change.
-                    notifyListeners();
-                } else {
-                    // tree is disposed, we need to do something.
-                    // lets remove ourselves from the listener.
-                    AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
-                    AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
-                    AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
-                }
-            }
-        });
-
-        // if it doesn't have clients yet, it'll need to be manually expanded when it gets them.
-        if (device.hasClients() == false) {
-            synchronized (mDevicesToExpand) {
-                mDevicesToExpand.add(device);
-            }
-        }
-    }
-
-    /**
-     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceDisconnected(IDevice)
-     */
-    public void deviceDisconnected(IDevice device) {
-        deviceConnected(device);
-
-        // just in case, we remove it from the list of devices to expand.
-        synchronized (mDevicesToExpand) {
-            mDevicesToExpand.remove(device);
-        }
-    }
-
-    /**
-     * Sent when a device data changed, or when clients are started/terminated on the device.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the device that was updated.
-     * @param changeMask the mask indicating what changed.
-     *
-     * @see IDeviceChangeListener#deviceChanged(IDevice)
-     */
-    public void deviceChanged(final IDevice device, int changeMask) {
-        boolean expand = false;
-        synchronized (mDevicesToExpand) {
-            int index = mDevicesToExpand.indexOf(device);
-            if (device.hasClients() && index != -1) {
-                mDevicesToExpand.remove(index);
-                expand = true;
-            }
-        }
-
-        final boolean finalExpand = expand;
-
-        exec(new Runnable() {
-            public void run() {
-                if (mTree.isDisposed() == false) {
-                    // look if the current device is selected. This is done in case the current
-                    // client of this particular device was killed. In this case, we'll need to
-                    // manually reselect the device.
-
-                    IDevice selectedDevice = getSelectedDevice();
-
-                    // refresh the device
-                    mTreeViewer.refresh(device);
-
-                    // if the selected device was the changed device and the new selection is
-                    // empty, we reselect the device.
-                    if (selectedDevice == device && mTreeViewer.getSelection().isEmpty()) {
-                        mTreeViewer.setSelection(new TreeSelection(new TreePath(
-                                new Object[] { device })));
-                    }
-
-                    // notify the listener of a possible selection change.
-                    notifyListeners();
-
-                    if (finalExpand) {
-                        mTreeViewer.setExpandedState(device, true);
-                    }
-                } else {
-                    // tree is disposed, we need to do something.
-                    // lets remove ourselves from the listener.
-                    AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
-                    AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
-                    AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
-                }
-            }
-        });
-    }
-
-    /**
-     * Sent when an existing client information changed.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param client the updated client.
-     * @param changeMask the bit mask describing the changed properties. It can contain
-     * any of the following values: {@link Client#CHANGE_INFO},
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-     * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-     * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-     *
-     * @see IClientChangeListener#clientChanged(Client, int)
-     */
-    public void clientChanged(final Client client, final int changeMask) {
-        exec(new Runnable() {
-            public void run() {
-                if (mTree.isDisposed() == false) {
-                    // refresh the client
-                    mTreeViewer.refresh(client);
-
-                    if ((changeMask & Client.CHANGE_DEBUGGER_STATUS) ==
-                            Client.CHANGE_DEBUGGER_STATUS &&
-                            client.getClientData().getDebuggerConnectionStatus() ==
-                                DebuggerStatus.WAITING) {
-                        // make sure the device is expanded. Normally the setSelection below
-                        // will auto expand, but the children of device may not already exist
-                        // at this time. Forcing an expand will make the TreeViewer create them.
-                        IDevice device = client.getDevice();
-                        if (mTreeViewer.getExpandedState(device) == false) {
-                            mTreeViewer.setExpandedState(device, true);
-                        }
-
-                        // create and set the selection
-                        TreePath treePath = new TreePath(new Object[] { device, client});
-                        TreeSelection treeSelection = new TreeSelection(treePath);
-                        mTreeViewer.setSelection(treeSelection);
-
-                        if (mAdvancedPortSupport) {
-                            client.setAsSelectedClient();
-                        }
-
-                        // notify the listener of a possible selection change.
-                        notifyListeners(device, client);
-                    }
-                } else {
-                    // tree is disposed, we need to do something.
-                    // lets remove ourselves from the listener.
-                    AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
-                    AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
-                    AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
-                }
-            }
-        });
-    }
-
-    private void loadImages(Display display, IImageLoader loader) {
-        if (mDeviceImage == null) {
-            mDeviceImage = ImageHelper.loadImage(loader, display, "device.png", //$NON-NLS-1$
-                    ICON_WIDTH, ICON_WIDTH,
-                    display.getSystemColor(SWT.COLOR_RED));
-        }
-        if (mEmulatorImage == null) {
-            mEmulatorImage = ImageHelper.loadImage(loader, display,
-                    "emulator.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
-                    display.getSystemColor(SWT.COLOR_BLUE));
-        }
-        if (mThreadImage == null) {
-            mThreadImage = ImageHelper.loadImage(loader, display, ICON_THREAD,
-                    ICON_WIDTH, ICON_WIDTH,
-                    display.getSystemColor(SWT.COLOR_YELLOW));
-        }
-        if (mHeapImage == null) {
-            mHeapImage = ImageHelper.loadImage(loader, display, ICON_HEAP,
-                    ICON_WIDTH, ICON_WIDTH,
-                    display.getSystemColor(SWT.COLOR_BLUE));
-        }
-        if (mWaitingImage == null) {
-            mWaitingImage = ImageHelper.loadImage(loader, display,
-                    "debug-wait.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
-                    display.getSystemColor(SWT.COLOR_RED));
-        }
-        if (mDebuggerImage == null) {
-            mDebuggerImage = ImageHelper.loadImage(loader, display,
-                    "debug-attach.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
-                    display.getSystemColor(SWT.COLOR_GREEN));
-        }
-        if (mDebugErrorImage == null) {
-            mDebugErrorImage = ImageHelper.loadImage(loader, display,
-                    "debug-error.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
-                    display.getSystemColor(SWT.COLOR_RED));
-        }
-    }
-
-    /**
-     * Returns a display string representing the state of the device.
-     * @param d the device
-     */
-    private static String getStateString(IDevice d) {
-        DeviceState deviceState = d.getState();
-        if (deviceState == DeviceState.ONLINE) {
-            return "Online";
-        } else if (deviceState == DeviceState.OFFLINE) {
-            return "Offline";
-        } else if (deviceState == DeviceState.BOOTLOADER) {
-            return "Bootloader";
-        }
-
-        return "??";
-    }
-
-    /**
-     * Executes the {@link Runnable} in the UI thread.
-     * @param runnable the runnable to execute.
-     */
-    private void exec(Runnable runnable) {
-        try {
-            Display display = mTree.getDisplay();
-            display.asyncExec(runnable);
-        } catch (SWTException e) {
-            // tree is disposed, we need to do something. lets remove ourselves from the listener.
-            AndroidDebugBridge.removeDebugBridgeChangeListener(this);
-            AndroidDebugBridge.removeDeviceChangeListener(this);
-            AndroidDebugBridge.removeClientChangeListener(this);
-        }
-    }
-
-    private void notifyListeners() {
-        // get the selection
-        TreeItem[] items = mTree.getSelection();
-
-        Client client = null;
-        IDevice device = null;
-
-        if (items.length == 1) {
-            Object object = items[0].getData();
-            if (object instanceof Client) {
-                client = (Client)object;
-                device = client.getDevice();
-            } else if (object instanceof IDevice) {
-                device = (IDevice)object;
-            }
-        }
-
-        notifyListeners(device, client);
-    }
-
-    private void notifyListeners(IDevice selectedDevice, Client selectedClient) {
-        if (selectedDevice != mCurrentDevice || selectedClient != mCurrentClient) {
-            mCurrentDevice = selectedDevice;
-            mCurrentClient = selectedClient;
-
-            for (IUiSelectionListener listener : mListeners) {
-                // notify the listener with a try/catch-all to make sure this thread won't die
-                // because of an uncaught exception before all the listeners were notified.
-                try {
-                    listener.selectionChanged(selectedDevice, selectedClient);
-                } catch (Exception e) {
-                }
-            }
-        }
-    }
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java
deleted file mode 100644
index 4410d3a..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.EmulatorConsole;
-import com.android.ddmlib.EmulatorConsole.GsmMode;
-import com.android.ddmlib.EmulatorConsole.GsmStatus;
-import com.android.ddmlib.EmulatorConsole.NetworkStatus;
-import com.android.ddmuilib.location.CoordinateControls;
-import com.android.ddmuilib.location.GpxParser;
-import com.android.ddmuilib.location.KmlParser;
-import com.android.ddmuilib.location.TrackContentProvider;
-import com.android.ddmuilib.location.TrackLabelProvider;
-import com.android.ddmuilib.location.TrackPoint;
-import com.android.ddmuilib.location.WayPoint;
-import com.android.ddmuilib.location.WayPointContentProvider;
-import com.android.ddmuilib.location.WayPointLabelProvider;
-import com.android.ddmuilib.location.GpxParser.Track;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.swt.widgets.TabItem;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Panel to control the emulator using EmulatorConsole objects.
- */
-public class EmulatorControlPanel extends SelectionDependentPanel {
-
-    // default location: Patio outside Charlie's
-    private final static double DEFAULT_LONGITUDE = -122.084095;
-    private final static double DEFAULT_LATITUDE = 37.422006;
-
-    private final static String SPEED_FORMAT = "Speed: %1$dX";
-
-
-    /**
-     * Map between the display gsm mode and the internal tag used by the display.
-     */
-    private final static String[][] GSM_MODES = new String[][] {
-        { "unregistered", GsmMode.UNREGISTERED.getTag() },
-        { "home", GsmMode.HOME.getTag() },
-        { "roaming", GsmMode.ROAMING.getTag() },
-        { "searching", GsmMode.SEARCHING.getTag() },
-        { "denied", GsmMode.DENIED.getTag() },
-    };
-
-    private final static String[] NETWORK_SPEEDS = new String[] {
-        "Full",
-        "GSM",
-        "HSCSD",
-        "GPRS",
-        "EDGE",
-        "UMTS",
-        "HSDPA",
-    };
-
-    private final static String[] NETWORK_LATENCIES = new String[] {
-        "None",
-        "GPRS",
-        "EDGE",
-        "UMTS",
-    };
-
-    private final static int[] PLAY_SPEEDS = new int[] { 1, 2, 5, 10, 20, 50 };
-
-    private final static String RE_PHONE_NUMBER = "^[+#0-9]+$"; //$NON-NLS-1$
-    private final static String PREFS_WAYPOINT_COL_NAME = "emulatorControl.waypoint.name"; //$NON-NLS-1$
-    private final static String PREFS_WAYPOINT_COL_LONGITUDE = "emulatorControl.waypoint.longitude"; //$NON-NLS-1$
-    private final static String PREFS_WAYPOINT_COL_LATITUDE = "emulatorControl.waypoint.latitude"; //$NON-NLS-1$
-    private final static String PREFS_WAYPOINT_COL_ELEVATION = "emulatorControl.waypoint.elevation"; //$NON-NLS-1$
-    private final static String PREFS_WAYPOINT_COL_DESCRIPTION = "emulatorControl.waypoint.desc"; //$NON-NLS-1$
-    private final static String PREFS_TRACK_COL_NAME = "emulatorControl.track.name"; //$NON-NLS-1$
-    private final static String PREFS_TRACK_COL_COUNT = "emulatorControl.track.count"; //$NON-NLS-1$
-    private final static String PREFS_TRACK_COL_FIRST = "emulatorControl.track.first"; //$NON-NLS-1$
-    private final static String PREFS_TRACK_COL_LAST = "emulatorControl.track.last"; //$NON-NLS-1$
-    private final static String PREFS_TRACK_COL_COMMENT = "emulatorControl.track.comment"; //$NON-NLS-1$
-
-    private IImageLoader mImageLoader;
-
-    private EmulatorConsole mEmulatorConsole;
-
-    private Composite mParent;
-
-    private Label mVoiceLabel;
-    private Combo mVoiceMode;
-    private Label mDataLabel;
-    private Combo mDataMode;
-    private Label mSpeedLabel;
-    private Combo mNetworkSpeed;
-    private Label mLatencyLabel;
-    private Combo mNetworkLatency;
-
-    private Label mNumberLabel;
-    private Text mPhoneNumber;
-
-    private Button mVoiceButton;
-    private Button mSmsButton;
-
-    private Label mMessageLabel;
-    private Text mSmsMessage;
-
-    private Button mCallButton;
-    private Button mCancelButton;
-
-    private TabFolder mLocationFolders;
-
-    private Button mDecimalButton;
-    private Button mSexagesimalButton;
-    private CoordinateControls mLongitudeControls;
-    private CoordinateControls mLatitudeControls;
-    private Button mGpxUploadButton;
-    private Table mGpxWayPointTable;
-    private Table mGpxTrackTable;
-    private Button mKmlUploadButton;
-    private Table mKmlWayPointTable;
-
-    private Button mPlayGpxButton;
-    private Button mGpxBackwardButton;
-    private Button mGpxForwardButton;
-    private Button mGpxSpeedButton;
-    private Button mPlayKmlButton;
-    private Button mKmlBackwardButton;
-    private Button mKmlForwardButton;
-    private Button mKmlSpeedButton;
-
-    private Image mPlayImage;
-    private Image mPauseImage;
-
-    private Thread mPlayingThread;
-    private boolean mPlayingTrack;
-    private int mPlayDirection = 1;
-    private int mSpeed;
-    private int mSpeedIndex;
-
-    private final SelectionAdapter mDirectionButtonAdapter = new SelectionAdapter() {
-        @Override
-        public void widgetSelected(SelectionEvent e) {
-            Button b = (Button)e.getSource();
-            if (b.getSelection() == false) {
-                // basically the button was unselected, which we don't allow.
-                // so we reselect it.
-                b.setSelection(true);
-                return;
-            }
-
-            // now handle selection change.
-            if (b == mGpxForwardButton || b == mKmlForwardButton) {
-                mGpxBackwardButton.setSelection(false);
-                mGpxForwardButton.setSelection(true);
-                mKmlBackwardButton.setSelection(false);
-                mKmlForwardButton.setSelection(true);
-                mPlayDirection = 1;
-
-            } else {
-                mGpxBackwardButton.setSelection(true);
-                mGpxForwardButton.setSelection(false);
-                mKmlBackwardButton.setSelection(true);
-                mKmlForwardButton.setSelection(false);
-                mPlayDirection = -1;
-            }
-        }
-    };
-
-    private final SelectionAdapter mSpeedButtonAdapter = new SelectionAdapter() {
-        @Override
-        public void widgetSelected(SelectionEvent e) {
-            mSpeedIndex = (mSpeedIndex+1) % PLAY_SPEEDS.length;
-            mSpeed = PLAY_SPEEDS[mSpeedIndex];
-
-            mGpxSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
-            mGpxPlayControls.pack();
-            mKmlSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
-            mKmlPlayControls.pack();
-
-            if (mPlayingThread != null) {
-                mPlayingThread.interrupt();
-            }
-        }
-     };
-    private Composite mKmlPlayControls;
-    private Composite mGpxPlayControls;
-
-
-    public EmulatorControlPanel(IImageLoader imageLoader) {
-        mImageLoader = imageLoader;
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}
-     */
-    @Override
-    public void deviceSelected() {
-        handleNewDevice(getCurrentDevice());
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}
-     */
-    @Override
-    public void clientSelected() {
-        // pass
-    }
-
-    /**
-     * Creates a control capable of displaying some information.  This is
-     * called once, when the application is initializing, from the UI thread.
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        mParent = parent;
-
-        final ScrolledComposite scollingParent = new ScrolledComposite(parent, SWT.V_SCROLL);
-        scollingParent.setExpandVertical(true);
-        scollingParent.setExpandHorizontal(true);
-        scollingParent.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        final Composite top = new Composite(scollingParent, SWT.NONE);
-        scollingParent.setContent(top);
-        top.setLayout(new GridLayout(1, false));
-
-        // set the resize for the scrolling to work (why isn't that done automatically?!?)
-        scollingParent.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Rectangle r = scollingParent.getClientArea();
-                scollingParent.setMinSize(top.computeSize(r.width, SWT.DEFAULT));
-            }
-        });
-
-        createRadioControls(top);
-
-        createCallControls(top);
-
-        createLocationControls(top);
-
-        doEnable(false);
-
-        top.layout();
-        Rectangle r = scollingParent.getClientArea();
-        scollingParent.setMinSize(top.computeSize(r.width, SWT.DEFAULT));
-
-        return scollingParent;
-    }
-
-    /**
-     * Create Radio (on/off/roaming, for voice/data) controls.
-     * @param top
-     */
-    private void createRadioControls(final Composite top) {
-        Group g1 = new Group(top, SWT.NONE);
-        g1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        g1.setLayout(new GridLayout(2, false));
-        g1.setText("Telephony Status");
-
-        // the inside of the group is 2 composite so that all the column of the controls (mainly
-        // combos) have the same width, while not taking the whole screen width
-        Composite insideGroup = new Composite(g1, SWT.NONE);
-        GridLayout gl = new GridLayout(4, false);
-        gl.marginBottom = gl.marginHeight = gl.marginLeft = gl.marginRight = 0;
-        insideGroup.setLayout(gl);
-
-        mVoiceLabel = new Label(insideGroup, SWT.NONE);
-        mVoiceLabel.setText("Voice:");
-        mVoiceLabel.setAlignment(SWT.RIGHT);
-
-        mVoiceMode = new Combo(insideGroup, SWT.READ_ONLY);
-        mVoiceMode.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        for (String[] mode : GSM_MODES) {
-            mVoiceMode.add(mode[0]);
-        }
-        mVoiceMode.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                setVoiceMode(mVoiceMode.getSelectionIndex());
-            }
-        });
-
-        mSpeedLabel = new Label(insideGroup, SWT.NONE);
-        mSpeedLabel.setText("Speed:");
-        mSpeedLabel.setAlignment(SWT.RIGHT);
-
-        mNetworkSpeed = new Combo(insideGroup, SWT.READ_ONLY);
-        mNetworkSpeed.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        for (String mode : NETWORK_SPEEDS) {
-            mNetworkSpeed.add(mode);
-        }
-        mNetworkSpeed.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                setNetworkSpeed(mNetworkSpeed.getSelectionIndex());
-            }
-        });
-
-        mDataLabel = new Label(insideGroup, SWT.NONE);
-        mDataLabel.setText("Data:");
-        mDataLabel.setAlignment(SWT.RIGHT);
-
-        mDataMode = new Combo(insideGroup, SWT.READ_ONLY);
-        mDataMode.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        for (String[] mode : GSM_MODES) {
-            mDataMode.add(mode[0]);
-        }
-        mDataMode.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                setDataMode(mDataMode.getSelectionIndex());
-            }
-        });
-
-        mLatencyLabel = new Label(insideGroup, SWT.NONE);
-        mLatencyLabel.setText("Latency:");
-        mLatencyLabel.setAlignment(SWT.RIGHT);
-
-        mNetworkLatency = new Combo(insideGroup, SWT.READ_ONLY);
-        mNetworkLatency.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        for (String mode : NETWORK_LATENCIES) {
-            mNetworkLatency.add(mode);
-        }
-        mNetworkLatency.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                setNetworkLatency(mNetworkLatency.getSelectionIndex());
-            }
-        });
-
-        // now an empty label to take the rest of the width of the group
-        Label l = new Label(g1, SWT.NONE);
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-    }
-
-    /**
-     * Create Voice/SMS call/hang up controls
-     * @param top
-     */
-    private void createCallControls(final Composite top) {
-        GridLayout gl;
-        Group g2 = new Group(top, SWT.NONE);
-        g2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        g2.setLayout(new GridLayout(1, false));
-        g2.setText("Telephony Actions");
-
-        // horizontal composite for label + text field
-        Composite phoneComp = new Composite(g2, SWT.NONE);
-        phoneComp.setLayoutData(new GridData(GridData.FILL_BOTH));
-        gl = new GridLayout(2, false);
-        gl.marginBottom = gl.marginHeight = gl.marginLeft = gl.marginRight = 0;
-        phoneComp.setLayout(gl);
-
-        mNumberLabel = new Label(phoneComp, SWT.NONE);
-        mNumberLabel.setText("Incoming number:");
-
-        mPhoneNumber = new Text(phoneComp, SWT.BORDER | SWT.LEFT | SWT.SINGLE);
-        mPhoneNumber.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mPhoneNumber.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                // Reenable the widgets based on the content of the text.
-                // doEnable checks the validity of the phone number to enable/disable some
-                // widgets.
-                // Looks like we're getting a callback at creation time, so we can't
-                // suppose that we are enabled when the text is modified...
-                doEnable(mEmulatorConsole != null);
-            }
-        });
-
-        mVoiceButton = new Button(phoneComp, SWT.RADIO);
-        GridData gd = new GridData();
-        gd.horizontalSpan = 2;
-        mVoiceButton.setText("Voice");
-        mVoiceButton.setLayoutData(gd);
-        mVoiceButton.setEnabled(false);
-        mVoiceButton.setSelection(true);
-        mVoiceButton.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                doEnable(true);
-
-                if (mVoiceButton.getSelection()) {
-                    mCallButton.setText("Call");
-                } else {
-                    mCallButton.setText("Send");
-                }
-            }
-        });
-
-        mSmsButton = new Button(phoneComp, SWT.RADIO);
-        mSmsButton.setText("SMS");
-        gd = new GridData();
-        gd.horizontalSpan = 2;
-        mSmsButton.setLayoutData(gd);
-        mSmsButton.setEnabled(false);
-        // Since there are only 2 radio buttons, we can put a listener on only one (they
-        // are both called on select and unselect event.
-
-        mMessageLabel = new Label(phoneComp, SWT.NONE);
-        gd = new GridData();
-        gd.verticalAlignment = SWT.TOP;
-        mMessageLabel.setLayoutData(gd);
-        mMessageLabel.setText("Message:");
-        mMessageLabel.setEnabled(false);
-
-        mSmsMessage = new Text(phoneComp, SWT.BORDER | SWT.LEFT | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-        mSmsMessage.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.heightHint = 70;
-        mSmsMessage.setEnabled(false);
-
-        // composite to put the 2 buttons horizontally
-        Composite g2ButtonComp = new Composite(g2, SWT.NONE);
-        g2ButtonComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        gl = new GridLayout(2, false);
-        gl.marginWidth = gl.marginHeight = 0;
-        g2ButtonComp.setLayout(gl);
-
-        // now a button below the phone number
-        mCallButton = new Button(g2ButtonComp, SWT.PUSH);
-        mCallButton.setText("Call");
-        mCallButton.setEnabled(false);
-        mCallButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mEmulatorConsole != null) {
-                    if (mVoiceButton.getSelection()) {
-                        processCommandResult(mEmulatorConsole.call(mPhoneNumber.getText().trim()));
-                    } else {
-                        // we need to encode the message. We need to replace the carriage return
-                        // character by the 2 character string \n.
-                        // Because of this the \ character needs to be escaped as well.
-                        // ReplaceAll() expects regexp so \ char are escaped twice.
-                        String message = mSmsMessage.getText();
-                        message = message.replaceAll("\\\\", //$NON-NLS-1$
-                                "\\\\\\\\"); //$NON-NLS-1$
-
-                        // While the normal line delimiter is returned by Text.getLineDelimiter()
-                        // it seems copy pasting text coming from somewhere else could have another
-                        // delimited. For this reason, we'll replace is several steps
-
-                        // replace the dual CR-LF
-                        message = message.replaceAll("\r\n", "\\\\n"); //$NON-NLS-1$ //$NON-NLS-1$
-
-                        // replace remaining stand alone \n
-                        message = message.replaceAll("\n", "\\\\n"); //$NON-NLS-1$ //$NON-NLS-1$
-
-                        // replace remaining stand alone \r
-                        message = message.replaceAll("\r", "\\\\n"); //$NON-NLS-1$ //$NON-NLS-1$
-
-                        processCommandResult(mEmulatorConsole.sendSms(mPhoneNumber.getText().trim(),
-                                message));
-                    }
-                }
-            }
-        });
-
-        mCancelButton = new Button(g2ButtonComp, SWT.PUSH);
-        mCancelButton.setText("Hang Up");
-        mCancelButton.setEnabled(false);
-        mCancelButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mEmulatorConsole != null) {
-                    if (mVoiceButton.getSelection()) {
-                        processCommandResult(mEmulatorConsole.cancelCall(
-                                mPhoneNumber.getText().trim()));
-                    }
-                }
-            }
-        });
-    }
-
-    /**
-     * Create Location controls.
-     * @param top
-     */
-    private void createLocationControls(final Composite top) {
-        Label l = new Label(top, SWT.NONE);
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        l.setText("Location Controls");
-
-        mLocationFolders = new TabFolder(top, SWT.NONE);
-        mLocationFolders.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        Composite manualLocationComp = new Composite(mLocationFolders, SWT.NONE);
-        TabItem item = new TabItem(mLocationFolders, SWT.NONE);
-        item.setText("Manual");
-        item.setControl(manualLocationComp);
-
-        createManualLocationControl(manualLocationComp);
-
-        mPlayImage = mImageLoader.loadImage("play.png", mParent.getDisplay()); // $NON-NLS-1$
-        mPauseImage = mImageLoader.loadImage("pause.png", mParent.getDisplay()); // $NON-NLS-1$
-
-        Composite gpxLocationComp = new Composite(mLocationFolders, SWT.NONE);
-        item = new TabItem(mLocationFolders, SWT.NONE);
-        item.setText("GPX");
-        item.setControl(gpxLocationComp);
-
-        createGpxLocationControl(gpxLocationComp);
-
-        Composite kmlLocationComp = new Composite(mLocationFolders, SWT.NONE);
-        kmlLocationComp.setLayout(new FillLayout());
-        item = new TabItem(mLocationFolders, SWT.NONE);
-        item.setText("KML");
-        item.setControl(kmlLocationComp);
-
-        createKmlLocationControl(kmlLocationComp);
-    }
-
-    private void createManualLocationControl(Composite manualLocationComp) {
-        final StackLayout sl;
-        GridLayout gl;
-        Label label;
-
-        manualLocationComp.setLayout(new GridLayout(1, false));
-        mDecimalButton = new Button(manualLocationComp, SWT.RADIO);
-        mDecimalButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mDecimalButton.setText("Decimal");
-        mSexagesimalButton = new Button(manualLocationComp, SWT.RADIO);
-        mSexagesimalButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mSexagesimalButton.setText("Sexagesimal");
-
-        // composite to hold and switching between the 2 modes.
-        final Composite content = new Composite(manualLocationComp, SWT.NONE);
-        content.setLayout(sl = new StackLayout());
-
-        // decimal display
-        final Composite decimalContent = new Composite(content, SWT.NONE);
-        decimalContent.setLayout(gl = new GridLayout(2, false));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        mLongitudeControls = new CoordinateControls();
-        mLatitudeControls = new CoordinateControls();
-
-        label = new Label(decimalContent, SWT.NONE);
-        label.setText("Longitude");
-
-        mLongitudeControls.createDecimalText(decimalContent);
-
-        label = new Label(decimalContent, SWT.NONE);
-        label.setText("Latitude");
-
-        mLatitudeControls.createDecimalText(decimalContent);
-
-        // sexagesimal content
-        final Composite sexagesimalContent = new Composite(content, SWT.NONE);
-        sexagesimalContent.setLayout(gl = new GridLayout(7, false));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("Longitude");
-
-        mLongitudeControls.createSexagesimalDegreeText(sexagesimalContent);
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("\u00B0"); // degree character
-
-        mLongitudeControls.createSexagesimalMinuteText(sexagesimalContent);
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("'");
-
-        mLongitudeControls.createSexagesimalSecondText(sexagesimalContent);
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("\"");
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("Latitude");
-
-        mLatitudeControls.createSexagesimalDegreeText(sexagesimalContent);
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("\u00B0");
-
-        mLatitudeControls.createSexagesimalMinuteText(sexagesimalContent);
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("'");
-
-        mLatitudeControls.createSexagesimalSecondText(sexagesimalContent);
-
-        label = new Label(sexagesimalContent, SWT.NONE);
-        label.setText("\"");
-
-        // set the default display to decimal
-        sl.topControl = decimalContent;
-        mDecimalButton.setSelection(true);
-
-        mDecimalButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mDecimalButton.getSelection()) {
-                    sl.topControl = decimalContent;
-                } else {
-                    sl.topControl = sexagesimalContent;
-                }
-                content.layout();
-            }
-        });
-
-        Button sendButton = new Button(manualLocationComp, SWT.PUSH);
-        sendButton.setText("Send");
-        sendButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mEmulatorConsole != null) {
-                    processCommandResult(mEmulatorConsole.sendLocation(
-                            mLongitudeControls.getValue(), mLatitudeControls.getValue(), 0));
-                }
-            }
-        });
-
-        mLongitudeControls.setValue(DEFAULT_LONGITUDE);
-        mLatitudeControls.setValue(DEFAULT_LATITUDE);
-    }
-
-    private void createGpxLocationControl(Composite gpxLocationComp) {
-        GridData gd;
-
-        IPreferenceStore store = DdmUiPreferences.getStore();
-
-        gpxLocationComp.setLayout(new GridLayout(1, false));
-
-        mGpxUploadButton = new Button(gpxLocationComp, SWT.PUSH);
-        mGpxUploadButton.setText("Load GPX...");
-
-        // Table for way point
-        mGpxWayPointTable = new Table(gpxLocationComp,
-                SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION);
-        mGpxWayPointTable.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.heightHint = 100;
-        mGpxWayPointTable.setHeaderVisible(true);
-        mGpxWayPointTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mGpxWayPointTable, "Name", SWT.LEFT,
-                "Some Name",
-                PREFS_WAYPOINT_COL_NAME, store);
-        TableHelper.createTableColumn(mGpxWayPointTable, "Longitude", SWT.LEFT,
-                "-199.999999",
-                PREFS_WAYPOINT_COL_LONGITUDE, store);
-        TableHelper.createTableColumn(mGpxWayPointTable, "Latitude", SWT.LEFT,
-                "-199.999999",
-                PREFS_WAYPOINT_COL_LATITUDE, store);
-        TableHelper.createTableColumn(mGpxWayPointTable, "Elevation", SWT.LEFT,
-                "99999.9",
-                PREFS_WAYPOINT_COL_ELEVATION, store);
-        TableHelper.createTableColumn(mGpxWayPointTable, "Description", SWT.LEFT,
-                "Some Description",
-                PREFS_WAYPOINT_COL_DESCRIPTION, store);
-
-        final TableViewer gpxWayPointViewer = new TableViewer(mGpxWayPointTable);
-        gpxWayPointViewer.setContentProvider(new WayPointContentProvider());
-        gpxWayPointViewer.setLabelProvider(new WayPointLabelProvider());
-
-        gpxWayPointViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                ISelection selection = event.getSelection();
-                if (selection instanceof IStructuredSelection) {
-                    IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-                    Object selectedObject = structuredSelection.getFirstElement();
-                    if (selectedObject instanceof WayPoint) {
-                        WayPoint wayPoint = (WayPoint)selectedObject;
-
-                        if (mEmulatorConsole != null && mPlayingTrack == false) {
-                            processCommandResult(mEmulatorConsole.sendLocation(
-                                    wayPoint.getLongitude(), wayPoint.getLatitude(),
-                                    wayPoint.getElevation()));
-                        }
-                    }
-                }
-            }
-        });
-
-        // table for tracks.
-        mGpxTrackTable = new Table(gpxLocationComp,
-                SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION);
-        mGpxTrackTable.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.heightHint = 100;
-        mGpxTrackTable.setHeaderVisible(true);
-        mGpxTrackTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mGpxTrackTable, "Name", SWT.LEFT,
-                "Some very long name",
-                PREFS_TRACK_COL_NAME, store);
-        TableHelper.createTableColumn(mGpxTrackTable, "Point Count", SWT.RIGHT,
-                "9999",
-                PREFS_TRACK_COL_COUNT, store);
-        TableHelper.createTableColumn(mGpxTrackTable, "First Point Time", SWT.LEFT,
-                "999-99-99T99:99:99Z",
-                PREFS_TRACK_COL_FIRST, store);
-        TableHelper.createTableColumn(mGpxTrackTable, "Last Point Time", SWT.LEFT,
-                "999-99-99T99:99:99Z",
-                PREFS_TRACK_COL_LAST, store);
-        TableHelper.createTableColumn(mGpxTrackTable, "Comment", SWT.LEFT,
-                "-199.999999",
-                PREFS_TRACK_COL_COMMENT, store);
-
-        final TableViewer gpxTrackViewer = new TableViewer(mGpxTrackTable);
-        gpxTrackViewer.setContentProvider(new TrackContentProvider());
-        gpxTrackViewer.setLabelProvider(new TrackLabelProvider());
-
-        gpxTrackViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                ISelection selection = event.getSelection();
-                if (selection instanceof IStructuredSelection) {
-                    IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-                    Object selectedObject = structuredSelection.getFirstElement();
-                    if (selectedObject instanceof Track) {
-                        Track track = (Track)selectedObject;
-
-                        if (mEmulatorConsole != null && mPlayingTrack == false) {
-                            TrackPoint[] points = track.getPoints();
-                            processCommandResult(mEmulatorConsole.sendLocation(
-                                    points[0].getLongitude(), points[0].getLatitude(),
-                                    points[0].getElevation()));
-                        }
-
-                        mPlayGpxButton.setEnabled(true);
-                        mGpxBackwardButton.setEnabled(true);
-                        mGpxForwardButton.setEnabled(true);
-                        mGpxSpeedButton.setEnabled(true);
-
-                        return;
-                    }
-                }
-
-                mPlayGpxButton.setEnabled(false);
-                mGpxBackwardButton.setEnabled(false);
-                mGpxForwardButton.setEnabled(false);
-                mGpxSpeedButton.setEnabled(false);
-            }
-        });
-
-        mGpxUploadButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
-
-                fileDialog.setText("Load GPX File");
-                fileDialog.setFilterExtensions(new String[] { "*.gpx" } );
-
-                String fileName = fileDialog.open();
-                if (fileName != null) {
-                    GpxParser parser = new GpxParser(fileName);
-                    if (parser.parse()) {
-                        gpxWayPointViewer.setInput(parser.getWayPoints());
-                        gpxTrackViewer.setInput(parser.getTracks());
-                    }
-                }
-            }
-        });
-
-        mGpxPlayControls = new Composite(gpxLocationComp, SWT.NONE);
-        GridLayout gl;
-        mGpxPlayControls.setLayout(gl = new GridLayout(5, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        mGpxPlayControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mPlayGpxButton = new Button(mGpxPlayControls, SWT.PUSH | SWT.FLAT);
-        mPlayGpxButton.setImage(mPlayImage);
-        mPlayGpxButton.addSelectionListener(new SelectionAdapter() {
-           @Override
-            public void widgetSelected(SelectionEvent e) {
-               if (mPlayingTrack == false) {
-                   ISelection selection = gpxTrackViewer.getSelection();
-                   if (selection.isEmpty() == false && selection instanceof IStructuredSelection) {
-                       IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-                       Object selectedObject = structuredSelection.getFirstElement();
-                       if (selectedObject instanceof Track) {
-                           Track track = (Track)selectedObject;
-                           playTrack(track);
-                       }
-                   }
-               } else {
-                   // if we're playing, then we pause
-                   mPlayingTrack = false;
-                   if (mPlayingThread != null) {
-                       mPlayingThread.interrupt();
-                   }
-               }
-            }
-        });
-
-        Label separator = new Label(mGpxPlayControls, SWT.SEPARATOR | SWT.VERTICAL);
-        separator.setLayoutData(gd = new GridData(
-                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
-        gd.heightHint = 0;
-
-        mGpxBackwardButton = new Button(mGpxPlayControls, SWT.TOGGLE | SWT.FLAT);
-        mGpxBackwardButton.setImage(mImageLoader.loadImage("backward.png", mParent.getDisplay())); // $NON-NLS-1$
-        mGpxBackwardButton.setSelection(false);
-        mGpxBackwardButton.addSelectionListener(mDirectionButtonAdapter);
-        mGpxForwardButton = new Button(mGpxPlayControls, SWT.TOGGLE | SWT.FLAT);
-        mGpxForwardButton.setImage(mImageLoader.loadImage("forward.png", mParent.getDisplay())); // $NON-NLS-1$
-        mGpxForwardButton.setSelection(true);
-        mGpxForwardButton.addSelectionListener(mDirectionButtonAdapter);
-
-        mGpxSpeedButton = new Button(mGpxPlayControls, SWT.PUSH | SWT.FLAT);
-
-        mSpeedIndex = 0;
-        mSpeed = PLAY_SPEEDS[mSpeedIndex];
-
-        mGpxSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
-        mGpxSpeedButton.addSelectionListener(mSpeedButtonAdapter);
-
-        mPlayGpxButton.setEnabled(false);
-        mGpxBackwardButton.setEnabled(false);
-        mGpxForwardButton.setEnabled(false);
-        mGpxSpeedButton.setEnabled(false);
-
-    }
-
-    private void createKmlLocationControl(Composite kmlLocationComp) {
-        GridData gd;
-
-        IPreferenceStore store = DdmUiPreferences.getStore();
-
-        kmlLocationComp.setLayout(new GridLayout(1, false));
-
-        mKmlUploadButton = new Button(kmlLocationComp, SWT.PUSH);
-        mKmlUploadButton.setText("Load KML...");
-
-        // Table for way point
-        mKmlWayPointTable = new Table(kmlLocationComp,
-                SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION);
-        mKmlWayPointTable.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.heightHint = 200;
-        mKmlWayPointTable.setHeaderVisible(true);
-        mKmlWayPointTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mKmlWayPointTable, "Name", SWT.LEFT,
-                "Some Name",
-                PREFS_WAYPOINT_COL_NAME, store);
-        TableHelper.createTableColumn(mKmlWayPointTable, "Longitude", SWT.LEFT,
-                "-199.999999",
-                PREFS_WAYPOINT_COL_LONGITUDE, store);
-        TableHelper.createTableColumn(mKmlWayPointTable, "Latitude", SWT.LEFT,
-                "-199.999999",
-                PREFS_WAYPOINT_COL_LATITUDE, store);
-        TableHelper.createTableColumn(mKmlWayPointTable, "Elevation", SWT.LEFT,
-                "99999.9",
-                PREFS_WAYPOINT_COL_ELEVATION, store);
-        TableHelper.createTableColumn(mKmlWayPointTable, "Description", SWT.LEFT,
-                "Some Description",
-                PREFS_WAYPOINT_COL_DESCRIPTION, store);
-
-        final TableViewer kmlWayPointViewer = new TableViewer(mKmlWayPointTable);
-        kmlWayPointViewer.setContentProvider(new WayPointContentProvider());
-        kmlWayPointViewer.setLabelProvider(new WayPointLabelProvider());
-
-        mKmlUploadButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
-
-                fileDialog.setText("Load KML File");
-                fileDialog.setFilterExtensions(new String[] { "*.kml" } );
-
-                String fileName = fileDialog.open();
-                if (fileName != null) {
-                    KmlParser parser = new KmlParser(fileName);
-                    if (parser.parse()) {
-                        kmlWayPointViewer.setInput(parser.getWayPoints());
-
-                        mPlayKmlButton.setEnabled(true);
-                        mKmlBackwardButton.setEnabled(true);
-                        mKmlForwardButton.setEnabled(true);
-                        mKmlSpeedButton.setEnabled(true);
-                    }
-                }
-            }
-        });
-
-        kmlWayPointViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                ISelection selection = event.getSelection();
-                if (selection instanceof IStructuredSelection) {
-                    IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-                    Object selectedObject = structuredSelection.getFirstElement();
-                    if (selectedObject instanceof WayPoint) {
-                        WayPoint wayPoint = (WayPoint)selectedObject;
-
-                        if (mEmulatorConsole != null && mPlayingTrack == false) {
-                            processCommandResult(mEmulatorConsole.sendLocation(
-                                    wayPoint.getLongitude(), wayPoint.getLatitude(),
-                                    wayPoint.getElevation()));
-                        }
-                    }
-                }
-            }
-        });
-
-
-
-        mKmlPlayControls = new Composite(kmlLocationComp, SWT.NONE);
-        GridLayout gl;
-        mKmlPlayControls.setLayout(gl = new GridLayout(5, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        mKmlPlayControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mPlayKmlButton = new Button(mKmlPlayControls, SWT.PUSH | SWT.FLAT);
-        mPlayKmlButton.setImage(mPlayImage);
-        mPlayKmlButton.addSelectionListener(new SelectionAdapter() {
-           @Override
-            public void widgetSelected(SelectionEvent e) {
-               if (mPlayingTrack == false) {
-                   Object input = kmlWayPointViewer.getInput();
-                   if (input instanceof WayPoint[]) {
-                       playKml((WayPoint[])input);
-                   }
-               } else {
-                   // if we're playing, then we pause
-                   mPlayingTrack = false;
-                   if (mPlayingThread != null) {
-                       mPlayingThread.interrupt();
-                   }
-               }
-            }
-        });
-
-        Label separator = new Label(mKmlPlayControls, SWT.SEPARATOR | SWT.VERTICAL);
-        separator.setLayoutData(gd = new GridData(
-                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
-        gd.heightHint = 0;
-
-        mKmlBackwardButton = new Button(mKmlPlayControls, SWT.TOGGLE | SWT.FLAT);
-        mKmlBackwardButton.setImage(mImageLoader.loadImage("backward.png", mParent.getDisplay())); // $NON-NLS-1$
-        mKmlBackwardButton.setSelection(false);
-        mKmlBackwardButton.addSelectionListener(mDirectionButtonAdapter);
-        mKmlForwardButton = new Button(mKmlPlayControls, SWT.TOGGLE | SWT.FLAT);
-        mKmlForwardButton.setImage(mImageLoader.loadImage("forward.png", mParent.getDisplay())); // $NON-NLS-1$
-        mKmlForwardButton.setSelection(true);
-        mKmlForwardButton.addSelectionListener(mDirectionButtonAdapter);
-
-        mKmlSpeedButton = new Button(mKmlPlayControls, SWT.PUSH | SWT.FLAT);
-
-        mSpeedIndex = 0;
-        mSpeed = PLAY_SPEEDS[mSpeedIndex];
-
-        mKmlSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
-        mKmlSpeedButton.addSelectionListener(mSpeedButtonAdapter);
-
-        mPlayKmlButton.setEnabled(false);
-        mKmlBackwardButton.setEnabled(false);
-        mKmlForwardButton.setEnabled(false);
-        mKmlSpeedButton.setEnabled(false);
-    }
-
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-    }
-
-    @Override
-    protected void postCreation() {
-        // pass
-    }
-
-    private synchronized void setDataMode(int selectionIndex) {
-        if (mEmulatorConsole != null) {
-            processCommandResult(mEmulatorConsole.setGsmDataMode(
-                    GsmMode.getEnum(GSM_MODES[selectionIndex][1])));
-        }
-    }
-
-    private synchronized void setVoiceMode(int selectionIndex) {
-        if (mEmulatorConsole != null) {
-            processCommandResult(mEmulatorConsole.setGsmVoiceMode(
-                    GsmMode.getEnum(GSM_MODES[selectionIndex][1])));
-        }
-    }
-
-    private synchronized void setNetworkLatency(int selectionIndex) {
-        if (mEmulatorConsole != null) {
-            processCommandResult(mEmulatorConsole.setNetworkLatency(selectionIndex));
-        }
-    }
-
-    private synchronized void setNetworkSpeed(int selectionIndex) {
-        if (mEmulatorConsole != null) {
-            processCommandResult(mEmulatorConsole.setNetworkSpeed(selectionIndex));
-        }
-    }
-
-
-    /**
-     * Callback on device selection change.
-     * @param device the new selected device
-     */
-    public void handleNewDevice(IDevice device) {
-        if (mParent.isDisposed()) {
-            return;
-        }
-        // unlink to previous console.
-        synchronized (this) {
-            mEmulatorConsole = null;
-        }
-
-        try {
-            // get the emulator console for this device
-            // First we need the device itself
-            if (device != null) {
-                GsmStatus gsm = null;
-                NetworkStatus netstatus = null;
-
-                synchronized (this) {
-                    mEmulatorConsole = EmulatorConsole.getConsole(device);
-                    if (mEmulatorConsole != null) {
-                        // get the gsm status
-                        gsm = mEmulatorConsole.getGsmStatus();
-                        netstatus = mEmulatorConsole.getNetworkStatus();
-
-                        if (gsm == null || netstatus == null) {
-                            mEmulatorConsole = null;
-                        }
-                    }
-                }
-
-                if (gsm != null && netstatus != null) {
-                    Display d = mParent.getDisplay();
-                    if (d.isDisposed() == false) {
-                        final GsmStatus f_gsm = gsm;
-                        final NetworkStatus f_netstatus = netstatus;
-
-                        d.asyncExec(new Runnable() {
-                            public void run() {
-                                if (f_gsm.voice != GsmMode.UNKNOWN) {
-                                    mVoiceMode.select(getGsmComboIndex(f_gsm.voice));
-                                } else {
-                                    mVoiceMode.clearSelection();
-                                }
-                                if (f_gsm.data != GsmMode.UNKNOWN) {
-                                    mDataMode.select(getGsmComboIndex(f_gsm.data));
-                                } else {
-                                    mDataMode.clearSelection();
-                                }
-
-                                if (f_netstatus.speed != -1) {
-                                    mNetworkSpeed.select(f_netstatus.speed);
-                                } else {
-                                    mNetworkSpeed.clearSelection();
-                                }
-
-                                if (f_netstatus.latency != -1) {
-                                    mNetworkLatency.select(f_netstatus.latency);
-                                } else {
-                                    mNetworkLatency.clearSelection();
-                                }
-                            }
-                        });
-                    }
-                }
-            }
-        } finally {
-            // enable/disable the ui
-            boolean enable = false;
-            synchronized (this) {
-                enable = mEmulatorConsole != null;
-            }
-
-            enable(enable);
-        }
-    }
-
-    /**
-     * Enable or disable the ui. Can be called from non ui threads.
-     * @param enabled
-     */
-    private void enable(final boolean enabled) {
-        try {
-            Display d = mParent.getDisplay();
-            d.asyncExec(new Runnable() {
-                public void run() {
-                    if (mParent.isDisposed() == false) {
-                        doEnable(enabled);
-                    }
-                }
-            });
-        } catch (SWTException e) {
-            // disposed. do nothing
-        }
-    }
-
-    private boolean isValidPhoneNumber() {
-        String number = mPhoneNumber.getText().trim();
-
-        return number.matches(RE_PHONE_NUMBER);
-    }
-
-    /**
-     * Enable or disable the ui. Cannot be called from non ui threads.
-     * @param enabled
-     */
-    protected void doEnable(boolean enabled) {
-        mVoiceLabel.setEnabled(enabled);
-        mVoiceMode.setEnabled(enabled);
-
-        mDataLabel.setEnabled(enabled);
-        mDataMode.setEnabled(enabled);
-
-        mSpeedLabel.setEnabled(enabled);
-        mNetworkSpeed.setEnabled(enabled);
-
-        mLatencyLabel.setEnabled(enabled);
-        mNetworkLatency.setEnabled(enabled);
-
-        // Calling setEnabled on a text field will trigger a modifyText event, so we don't do it
-        // if we don't need to.
-        if (mPhoneNumber.isEnabled() != enabled) {
-            mNumberLabel.setEnabled(enabled);
-            mPhoneNumber.setEnabled(enabled);
-        }
-
-        boolean valid = isValidPhoneNumber();
-
-        mVoiceButton.setEnabled(enabled && valid);
-        mSmsButton.setEnabled(enabled && valid);
-
-        boolean smsValid = enabled && valid && mSmsButton.getSelection();
-
-        // Calling setEnabled on a text field will trigger a modifyText event, so we don't do it
-        // if we don't need to.
-        if (mSmsMessage.isEnabled() != smsValid) {
-            mMessageLabel.setEnabled(smsValid);
-            mSmsMessage.setEnabled(smsValid);
-        }
-        if (enabled == false) {
-            mSmsMessage.setText(""); //$NON-NLs-1$
-        }
-
-        mCallButton.setEnabled(enabled && valid);
-        mCancelButton.setEnabled(enabled && valid && mVoiceButton.getSelection());
-
-        if (enabled == false) {
-            mVoiceMode.clearSelection();
-            mDataMode.clearSelection();
-            mNetworkSpeed.clearSelection();
-            mNetworkLatency.clearSelection();
-            if (mPhoneNumber.getText().length() > 0) {
-                mPhoneNumber.setText(""); //$NON-NLS-1$
-            }
-        }
-
-        // location controls
-        mLocationFolders.setEnabled(enabled);
-
-        mDecimalButton.setEnabled(enabled);
-        mSexagesimalButton.setEnabled(enabled);
-        mLongitudeControls.setEnabled(enabled);
-        mLatitudeControls.setEnabled(enabled);
-
-        mGpxUploadButton.setEnabled(enabled);
-        mGpxWayPointTable.setEnabled(enabled);
-        mGpxTrackTable.setEnabled(enabled);
-        mKmlUploadButton.setEnabled(enabled);
-        mKmlWayPointTable.setEnabled(enabled);
-    }
-
-    /**
-     * Returns the index of the combo item matching a specific GsmMode.
-     * @param mode
-     */
-    private int getGsmComboIndex(GsmMode mode) {
-        for (int i = 0 ; i < GSM_MODES.length; i++) {
-            String[] modes = GSM_MODES[i];
-            if (mode.getTag().equals(modes[1])) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Processes the result of a command sent to the console.
-     * @param result the result of the command.
-     */
-    private boolean processCommandResult(final String result) {
-        if (result != EmulatorConsole.RESULT_OK) {
-            try {
-                mParent.getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        if (mParent.isDisposed() == false) {
-                            MessageDialog.openError(mParent.getShell(), "Emulator Console",
-                                    result);
-                        }
-                    }
-                });
-            } catch (SWTException e) {
-                // we're quitting, just ignore
-            }
-
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * @param track
-     */
-    private void playTrack(final Track track) {
-        // no need to synchronize this check, the worst that can happen, is we start the thread
-        // for nothing.
-        if (mEmulatorConsole != null) {
-            mPlayGpxButton.setImage(mPauseImage);
-            mPlayKmlButton.setImage(mPauseImage);
-            mPlayingTrack = true;
-
-            mPlayingThread = new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        TrackPoint[] trackPoints = track.getPoints();
-                        int count = trackPoints.length;
-
-                        // get the start index.
-                        int start = 0;
-                        if (mPlayDirection == -1) {
-                            start = count - 1;
-                        }
-
-                        for (int p = start; p >= 0 && p < count; p += mPlayDirection) {
-                            if (mPlayingTrack == false) {
-                                return;
-                            }
-
-                            // get the current point and send its location to
-                            // the emulator.
-                            final TrackPoint trackPoint = trackPoints[p];
-
-                            synchronized (EmulatorControlPanel.this) {
-                                if (mEmulatorConsole == null ||
-                                        processCommandResult(mEmulatorConsole.sendLocation(
-                                                trackPoint.getLongitude(), trackPoint.getLatitude(),
-                                                trackPoint.getElevation())) == false) {
-                                    return;
-                                }
-                            }
-
-                            // if this is not the final point, then get the next one and
-                            // compute the delta time
-                            int nextIndex = p + mPlayDirection;
-                            if (nextIndex >=0 && nextIndex < count) {
-                                TrackPoint nextPoint = trackPoints[nextIndex];
-
-                                long delta = nextPoint.getTime() - trackPoint.getTime();
-                                if (delta < 0) {
-                                    delta = -delta;
-                                }
-
-                                long startTime = System.currentTimeMillis();
-
-                                try {
-                                    sleep(delta / mSpeed);
-                                } catch (InterruptedException e) {
-                                    if (mPlayingTrack == false) {
-                                        return;
-                                    }
-
-                                    // we got interrupted, lets make sure we can play
-                                    do {
-                                        long waited = System.currentTimeMillis() - startTime;
-                                        long needToWait = delta / mSpeed;
-                                        if (waited < needToWait) {
-                                            try {
-                                                sleep(needToWait - waited);
-                                            } catch (InterruptedException e1) {
-                                                // we'll just loop and wait again if needed.
-                                                // unless we're supposed to stop
-                                                if (mPlayingTrack == false) {
-                                                    return;
-                                                }
-                                            }
-                                        } else {
-                                            break;
-                                        }
-                                    } while (true);
-                                }
-                            }
-                        }
-                    } finally {
-                        mPlayingTrack = false;
-                        try {
-                            mParent.getDisplay().asyncExec(new Runnable() {
-                                public void run() {
-                                    if (mPlayGpxButton.isDisposed() == false) {
-                                        mPlayGpxButton.setImage(mPlayImage);
-                                        mPlayKmlButton.setImage(mPlayImage);
-                                    }
-                                }
-                            });
-                        } catch (SWTException e) {
-                            // we're quitting, just ignore
-                        }
-                    }
-                }
-            };
-
-            mPlayingThread.start();
-        }
-    }
-
-    private void playKml(final WayPoint[] trackPoints) {
-        // no need to synchronize this check, the worst that can happen, is we start the thread
-        // for nothing.
-        if (mEmulatorConsole != null) {
-            mPlayGpxButton.setImage(mPauseImage);
-            mPlayKmlButton.setImage(mPauseImage);
-            mPlayingTrack = true;
-
-            mPlayingThread = new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        int count = trackPoints.length;
-
-                        // get the start index.
-                        int start = 0;
-                        if (mPlayDirection == -1) {
-                            start = count - 1;
-                        }
-
-                        for (int p = start; p >= 0 && p < count; p += mPlayDirection) {
-                            if (mPlayingTrack == false) {
-                                return;
-                            }
-
-                            // get the current point and send its location to
-                            // the emulator.
-                            WayPoint trackPoint = trackPoints[p];
-
-                            synchronized (EmulatorControlPanel.this) {
-                                if (mEmulatorConsole == null ||
-                                        processCommandResult(mEmulatorConsole.sendLocation(
-                                                trackPoint.getLongitude(), trackPoint.getLatitude(),
-                                                trackPoint.getElevation())) == false) {
-                                    return;
-                                }
-                            }
-
-                            // if this is not the final point, then get the next one and
-                            // compute the delta time
-                            int nextIndex = p + mPlayDirection;
-                            if (nextIndex >=0 && nextIndex < count) {
-
-                                long delta = 1000; // 1 second
-                                if (delta < 0) {
-                                    delta = -delta;
-                                }
-
-                                long startTime = System.currentTimeMillis();
-
-                                try {
-                                    sleep(delta / mSpeed);
-                                } catch (InterruptedException e) {
-                                    if (mPlayingTrack == false) {
-                                        return;
-                                    }
-
-                                    // we got interrupted, lets make sure we can play
-                                    do {
-                                        long waited = System.currentTimeMillis() - startTime;
-                                        long needToWait = delta / mSpeed;
-                                        if (waited < needToWait) {
-                                            try {
-                                                sleep(needToWait - waited);
-                                            } catch (InterruptedException e1) {
-                                                // we'll just loop and wait again if needed.
-                                                // unless we're supposed to stop
-                                                if (mPlayingTrack == false) {
-                                                    return;
-                                                }
-                                            }
-                                        } else {
-                                            break;
-                                        }
-                                    } while (true);
-                                }
-                            }
-                        }
-                    } finally {
-                        mPlayingTrack = false;
-                        try {
-                            mParent.getDisplay().asyncExec(new Runnable() {
-                                public void run() {
-                                    if (mPlayGpxButton.isDisposed() == false) {
-                                        mPlayGpxButton.setImage(mPlayImage);
-                                        mPlayKmlButton.setImage(mPlayImage);
-                                    }
-                                }
-                            });
-                        } catch (SWTException e) {
-                            // we're quitting, just ignore
-                        }
-                    }
-                }
-            };
-
-            mPlayingThread.start();
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/HeapPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/HeapPanel.java
deleted file mode 100644
index f5cf9b1..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/HeapPanel.java
+++ /dev/null
@@ -1,1294 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.HeapSegment.HeapSegmentElement;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.CategoryAxis;
-import org.jfree.chart.axis.CategoryLabelPositions;
-import org.jfree.chart.labels.CategoryToolTipGenerator;
-import org.jfree.chart.plot.CategoryPlot;
-import org.jfree.chart.plot.Plot;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.chart.renderer.category.CategoryItemRenderer;
-import org.jfree.chart.title.TextTitle;
-import org.jfree.data.category.CategoryDataset;
-import org.jfree.data.category.DefaultCategoryDataset;
-import org.jfree.experimental.chart.swt.ChartComposite;
-import org.jfree.experimental.swt.SWTUtils;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * Base class for our information panels.
- */
-public final class HeapPanel extends BaseHeapPanel {
-    private static final String PREFS_STATS_COL_TYPE = "heapPanel.col0"; //$NON-NLS-1$
-    private static final String PREFS_STATS_COL_COUNT = "heapPanel.col1"; //$NON-NLS-1$
-    private static final String PREFS_STATS_COL_SIZE = "heapPanel.col2"; //$NON-NLS-1$
-    private static final String PREFS_STATS_COL_SMALLEST = "heapPanel.col3"; //$NON-NLS-1$
-    private static final String PREFS_STATS_COL_LARGEST = "heapPanel.col4"; //$NON-NLS-1$
-    private static final String PREFS_STATS_COL_MEDIAN = "heapPanel.col5"; //$NON-NLS-1$
-    private static final String PREFS_STATS_COL_AVERAGE = "heapPanel.col6"; //$NON-NLS-1$
-
-    /* args to setUpdateStatus() */
-    private static final int NOT_SELECTED   = 0;
-    private static final int NOT_ENABLED    = 1;
-    private static final int ENABLED        = 2;
-
-    /** color palette and map legend. NATIVE is the last enum is a 0 based enum list, so we need
-     * Native+1 at least. We also need 2 more entries for free area and expansion area.  */
-    private static final int NUM_PALETTE_ENTRIES = HeapSegmentElement.KIND_NATIVE+2 +1;
-    private static final String[] mMapLegend = new String[NUM_PALETTE_ENTRIES];
-    private static final PaletteData mMapPalette = createPalette();
-
-    private static final boolean DISPLAY_HEAP_BITMAP = false;
-    private static final boolean DISPLAY_HILBERT_BITMAP = false;
-
-    private static final int PLACEHOLDER_HILBERT_SIZE = 200;
-    private static final int PLACEHOLDER_LINEAR_V_SIZE = 100;
-    private static final int PLACEHOLDER_LINEAR_H_SIZE = 300;
-
-    private static final int[] ZOOMS = {100, 50, 25};
-    
-    private static final NumberFormat sByteFormatter = NumberFormat.getInstance();
-    private static final NumberFormat sLargeByteFormatter = NumberFormat.getInstance();
-    private static final NumberFormat sCountFormatter = NumberFormat.getInstance();
-    
-    static {
-        sByteFormatter.setMinimumFractionDigits(0);
-        sByteFormatter.setMaximumFractionDigits(1);
-        sLargeByteFormatter.setMinimumFractionDigits(3);
-        sLargeByteFormatter.setMaximumFractionDigits(3);
-
-        sCountFormatter.setGroupingUsed(true);
-    }
-
-    private Display mDisplay;
-
-    private Composite mTop; // real top
-    private Label mUpdateStatus;
-    private Table mHeapSummary;
-    private Combo mDisplayMode;
-
-    //private ScrolledComposite mScrolledComposite;
-
-    private Composite mDisplayBase; // base of the displays.
-    private StackLayout mDisplayStack;
-
-    private Composite mStatisticsBase;
-    private Table mStatisticsTable;
-    private JFreeChart mChart;
-    private ChartComposite mChartComposite;
-    private Button mGcButton;
-    private DefaultCategoryDataset mAllocCountDataSet;
-
-    private Composite mLinearBase;
-    private Label mLinearHeapImage;
-
-    private Composite mHilbertBase;
-    private Label mHilbertHeapImage;
-    private Group mLegend;
-    private Combo mZoom;
-
-    /** Image used for the hilbert display. Since we recreate a new image every time, we
-     * keep this one around to dispose it. */
-    private Image mHilbertImage;
-    private Image mLinearImage;
-    private Composite[] mLayout;
-
-    /*
-     * Create color palette for map.  Set up titles for legend.
-     */
-    private static PaletteData createPalette() {
-        RGB colors[] = new RGB[NUM_PALETTE_ENTRIES];
-        colors[0]
-                = new RGB(192, 192, 192); // non-heap pixels are gray
-        mMapLegend[0]
-                = "(heap expansion area)";
-
-        colors[1]
-                = new RGB(0, 0, 0);       // free chunks are black
-        mMapLegend[1]
-                = "free";
-
-        colors[HeapSegmentElement.KIND_OBJECT + 2]
-                = new RGB(0, 0, 255);     // objects are blue
-        mMapLegend[HeapSegmentElement.KIND_OBJECT + 2]
-                = "data object";
-
-        colors[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
-                = new RGB(0, 255, 0);     // class objects are green
-        mMapLegend[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
-                = "class object";
-
-        colors[HeapSegmentElement.KIND_ARRAY_1 + 2]
-                = new RGB(255, 0, 0);     // byte/bool arrays are red
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_1 + 2]
-                = "1-byte array (byte[], boolean[])";
-
-        colors[HeapSegmentElement.KIND_ARRAY_2 + 2]
-                = new RGB(255, 128, 0);   // short/char arrays are orange
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_2 + 2]
-                = "2-byte array (short[], char[])";
-
-        colors[HeapSegmentElement.KIND_ARRAY_4 + 2]
-                = new RGB(255, 255, 0);   // obj/int/float arrays are yellow
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_4 + 2]
-                = "4-byte array (object[], int[], float[])";
-
-        colors[HeapSegmentElement.KIND_ARRAY_8 + 2]
-                = new RGB(255, 128, 128); // long/double arrays are pink
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_8 + 2]
-                = "8-byte array (long[], double[])";
-
-        colors[HeapSegmentElement.KIND_UNKNOWN + 2]
-                = new RGB(255, 0, 255);   // unknown objects are cyan
-        mMapLegend[HeapSegmentElement.KIND_UNKNOWN + 2]
-                = "unknown object";
-
-        colors[HeapSegmentElement.KIND_NATIVE + 2]
-                = new RGB(64, 64, 64);    // native objects are dark gray
-        mMapLegend[HeapSegmentElement.KIND_NATIVE + 2]
-                = "non-Java object";
-
-        return new PaletteData(colors);
-    }
-
-    /**
-     * Sent when an existing client information changed.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param client the updated client.
-     * @param changeMask the bit mask describing the changed properties. It can contain
-     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-     * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-     * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-     *
-     * @see IClientChangeListener#clientChanged(Client, int)
-     */
-    public void clientChanged(final Client client, int changeMask) {
-        if (client == getCurrentClient()) {
-            if ((changeMask & Client.CHANGE_HEAP_MODE) == Client.CHANGE_HEAP_MODE ||
-                    (changeMask & Client.CHANGE_HEAP_DATA) == Client.CHANGE_HEAP_DATA) {
-                try {
-                    mTop.getDisplay().asyncExec(new Runnable() {
-                        public void run() {
-                            clientSelected();
-                        }
-                    });
-                } catch (SWTException e) {
-                    // display is disposed (app is quitting most likely), we do nothing.
-                }
-            }
-        }
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}
-     */
-    @Override
-    public void deviceSelected() {
-        // pass
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}.
-     */
-    @Override
-    public void clientSelected() {
-        if (mTop.isDisposed())
-            return;
-
-        Client client = getCurrentClient();
-
-        Log.d("ddms", "HeapPanel: changed " + client);
-
-        if (client != null) {
-            ClientData cd = client.getClientData();
-
-            if (client.isHeapUpdateEnabled()) {
-                mGcButton.setEnabled(true);
-                mDisplayMode.setEnabled(true);
-                setUpdateStatus(ENABLED);
-            } else {
-                setUpdateStatus(NOT_ENABLED);
-                mGcButton.setEnabled(false);
-                mDisplayMode.setEnabled(false);
-            }
-
-            fillSummaryTable(cd);
-            
-            int mode = mDisplayMode.getSelectionIndex();
-            if (mode == 0) {
-                fillDetailedTable(client, false /* forceRedraw */);
-            } else {
-                if (DISPLAY_HEAP_BITMAP) {
-                    renderHeapData(cd, mode - 1, false /* forceRedraw */);
-                }
-            }
-        } else {
-            mGcButton.setEnabled(false);
-            mDisplayMode.setEnabled(false);
-            fillSummaryTable(null);
-            fillDetailedTable(null, true);
-            setUpdateStatus(NOT_SELECTED);
-        }
-
-        // sizes of things change frequently, so redo layout
-        //mScrolledComposite.setMinSize(mDisplayStack.topControl.computeSize(SWT.DEFAULT,
-        //        SWT.DEFAULT));
-        mDisplayBase.layout();
-        //mScrolledComposite.redraw();
-    }
-
-    /**
-     * Create our control(s).
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        mDisplay = parent.getDisplay();
-
-        GridLayout gl;
-
-        mTop = new Composite(parent, SWT.NONE);
-        mTop.setLayout(new GridLayout(1, false));
-        mTop.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        mUpdateStatus = new Label(mTop, SWT.NONE);
-        setUpdateStatus(NOT_SELECTED);
-
-        Composite summarySection = new Composite(mTop, SWT.NONE);
-        summarySection.setLayout(gl = new GridLayout(2, false));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        mHeapSummary = createSummaryTable(summarySection);
-        mGcButton = new Button(summarySection, SWT.PUSH);
-        mGcButton.setText("Cause GC");
-        mGcButton.setEnabled(false);
-        mGcButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                Client client = getCurrentClient();
-                if (client != null) {
-                    client.executeGarbageCollector();
-                }
-            }
-        });
-
-        Composite comboSection = new Composite(mTop, SWT.NONE);
-        gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        comboSection.setLayout(gl);
-
-        Label displayLabel = new Label(comboSection, SWT.NONE);
-        displayLabel.setText("Display: ");
-
-        mDisplayMode = new Combo(comboSection, SWT.READ_ONLY);
-        mDisplayMode.setEnabled(false);
-        mDisplayMode.add("Stats");
-        if (DISPLAY_HEAP_BITMAP) {
-            mDisplayMode.add("Linear");
-            if (DISPLAY_HILBERT_BITMAP) {
-                mDisplayMode.add("Hilbert");
-            }
-        }
-
-        // the base of the displays.
-        mDisplayBase = new Composite(mTop, SWT.NONE);
-        mDisplayBase.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mDisplayStack = new StackLayout();
-        mDisplayBase.setLayout(mDisplayStack);
-
-        // create the statistics display
-        mStatisticsBase = new Composite(mDisplayBase, SWT.NONE);
-        //mStatisticsBase.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mStatisticsBase.setLayout(gl = new GridLayout(1, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        mDisplayStack.topControl = mStatisticsBase;
-        
-        mStatisticsTable = createDetailedTable(mStatisticsBase);
-        mStatisticsTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        
-        createChart();
-
-        //create the linear composite
-        mLinearBase = new Composite(mDisplayBase, SWT.NONE);
-        //mLinearBase.setLayoutData(new GridData());
-        gl = new GridLayout(1, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        mLinearBase.setLayout(gl);
-
-        {
-            mLinearHeapImage = new Label(mLinearBase, SWT.NONE);
-            mLinearHeapImage.setLayoutData(new GridData());
-            mLinearHeapImage.setImage(ImageHelper.createPlaceHolderArt(mDisplay,
-                    PLACEHOLDER_LINEAR_H_SIZE, PLACEHOLDER_LINEAR_V_SIZE,
-                    mDisplay.getSystemColor(SWT.COLOR_BLUE)));
-
-            // create a composite to contain the bottom part (legend)
-            Composite bottomSection = new Composite(mLinearBase, SWT.NONE);
-            gl = new GridLayout(1, false);
-            gl.marginHeight = gl.marginWidth = 0;
-            bottomSection.setLayout(gl);
-
-            createLegend(bottomSection);
-        }
-
-/*        
-        mScrolledComposite = new ScrolledComposite(mTop, SWT.H_SCROLL | SWT.V_SCROLL);
-        mScrolledComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mScrolledComposite.setExpandHorizontal(true);
-        mScrolledComposite.setExpandVertical(true);
-        mScrolledComposite.setContent(mDisplayBase);
-*/
-
-
-        // create the hilbert display.
-        mHilbertBase = new Composite(mDisplayBase, SWT.NONE);
-        //mHilbertBase.setLayoutData(new GridData());
-        gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        mHilbertBase.setLayout(gl);
-
-        if (DISPLAY_HILBERT_BITMAP) {
-            mHilbertHeapImage = new Label(mHilbertBase, SWT.NONE);
-            mHilbertHeapImage.setLayoutData(new GridData());
-            mHilbertHeapImage.setImage(ImageHelper.createPlaceHolderArt(mDisplay,
-                    PLACEHOLDER_HILBERT_SIZE, PLACEHOLDER_HILBERT_SIZE,
-                    mDisplay.getSystemColor(SWT.COLOR_BLUE)));
-
-            // create a composite to contain the right part (legend + zoom)
-            Composite rightSection = new Composite(mHilbertBase, SWT.NONE);
-            gl = new GridLayout(1, false);
-            gl.marginHeight = gl.marginWidth = 0;
-            rightSection.setLayout(gl);
-
-            Composite zoomComposite = new Composite(rightSection, SWT.NONE);
-            gl = new GridLayout(2, false);
-            zoomComposite.setLayout(gl);
-
-            Label l = new Label(zoomComposite, SWT.NONE);
-            l.setText("Zoom:");
-            mZoom = new Combo(zoomComposite, SWT.READ_ONLY);
-            for (int z : ZOOMS) {
-                mZoom.add(String.format("%1$d%%", z)); // $NON-NLS-1$
-            }
-
-            mZoom.select(0);
-            mZoom.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    setLegendText(mZoom.getSelectionIndex());
-                    Client client = getCurrentClient();
-                    if (client != null) {
-                        renderHeapData(client.getClientData(), 1, true);
-                        mTop.pack();
-                    }
-                }
-            });
-
-            createLegend(rightSection);
-        }
-        mHilbertBase.pack();
-
-        mLayout = new Composite[] { mStatisticsBase, mLinearBase, mHilbertBase };
-        mDisplayMode.select(0);
-        mDisplayMode.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                int index = mDisplayMode.getSelectionIndex();
-                Client client = getCurrentClient();
-
-                if (client != null) {
-                    if (index == 0) {
-                        fillDetailedTable(client, true /* forceRedraw */);
-                    } else {
-                        renderHeapData(client.getClientData(), index-1, true /* forceRedraw */);
-                    }
-                }
-
-                mDisplayStack.topControl = mLayout[index];
-                //mScrolledComposite.setMinSize(mDisplayStack.topControl.computeSize(SWT.DEFAULT,
-                //        SWT.DEFAULT));
-                mDisplayBase.layout();
-                //mScrolledComposite.redraw();
-            }
-        });
-
-        //mScrolledComposite.setMinSize(mDisplayStack.topControl.computeSize(SWT.DEFAULT,
-        //        SWT.DEFAULT));
-        mDisplayBase.layout();
-        //mScrolledComposite.redraw();
-
-        return mTop;
-    }
-
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        mHeapSummary.setFocus();
-    }
-    
-
-    private Table createSummaryTable(Composite base) {
-        Table tab = new Table(base, SWT.SINGLE | SWT.FULL_SELECTION);
-        tab.setHeaderVisible(true);
-        tab.setLinesVisible(true);
-
-        TableColumn col;
-
-        col = new TableColumn(tab, SWT.RIGHT);
-        col.setText("ID");
-        col.pack();
-
-        col = new TableColumn(tab, SWT.RIGHT);
-        col.setText("000.000WW"); // $NON-NLS-1$
-        col.pack();
-        col.setText("Heap Size");
-
-        col = new TableColumn(tab, SWT.RIGHT);
-        col.setText("000.000WW"); // $NON-NLS-1$
-        col.pack();
-        col.setText("Allocated");
-
-        col = new TableColumn(tab, SWT.RIGHT);
-        col.setText("000.000WW"); // $NON-NLS-1$
-        col.pack();
-        col.setText("Free");
-
-        col = new TableColumn(tab, SWT.RIGHT);
-        col.setText("000.00%"); // $NON-NLS-1$
-        col.pack();
-        col.setText("% Used");
-
-        col = new TableColumn(tab, SWT.RIGHT);
-        col.setText("000,000,000"); // $NON-NLS-1$
-        col.pack();
-        col.setText("# Objects");
-
-        return tab;
-    }
-    
-    private Table createDetailedTable(Composite base) {
-        IPreferenceStore store = DdmUiPreferences.getStore();
-        
-        Table tab = new Table(base, SWT.SINGLE | SWT.FULL_SELECTION);
-        tab.setHeaderVisible(true);
-        tab.setLinesVisible(true);
-
-        TableHelper.createTableColumn(tab, "Type", SWT.LEFT,
-                "4-byte array (object[], int[], float[])", //$NON-NLS-1$
-                PREFS_STATS_COL_TYPE, store);
-
-        TableHelper.createTableColumn(tab, "Count", SWT.RIGHT,
-                "00,000", //$NON-NLS-1$
-                PREFS_STATS_COL_COUNT, store);
-
-        TableHelper.createTableColumn(tab, "Total Size", SWT.RIGHT,
-                "000.000 WW", //$NON-NLS-1$
-                PREFS_STATS_COL_SIZE, store);
-
-        TableHelper.createTableColumn(tab, "Smallest", SWT.RIGHT,
-                "000.000 WW", //$NON-NLS-1$
-                PREFS_STATS_COL_SMALLEST, store);
-
-        TableHelper.createTableColumn(tab, "Largest", SWT.RIGHT,
-                "000.000 WW", //$NON-NLS-1$
-                PREFS_STATS_COL_LARGEST, store);
-
-        TableHelper.createTableColumn(tab, "Median", SWT.RIGHT,
-                "000.000 WW", //$NON-NLS-1$
-                PREFS_STATS_COL_MEDIAN, store);
-
-        TableHelper.createTableColumn(tab, "Average", SWT.RIGHT,
-                "000.000 WW", //$NON-NLS-1$
-                PREFS_STATS_COL_AVERAGE, store);
-
-        tab.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                
-                Client client = getCurrentClient();
-                if (client != null) {
-                    int index = mStatisticsTable.getSelectionIndex();
-                    TableItem item = mStatisticsTable.getItem(index);
-                    
-                    if (item != null) {
-                        Map<Integer, ArrayList<HeapSegmentElement>> heapMap =
-                            client.getClientData().getVmHeapData().getProcessedHeapMap();
-                        
-                        ArrayList<HeapSegmentElement> list = heapMap.get(item.getData());
-                        if (list != null) {
-                            showChart(list);
-                        }
-                    }
-                }
-
-            }
-        });
-        
-        return tab;
-    }
-    
-    /**
-     * Creates the chart below the statistics table
-     */
-    private void createChart() {
-        mAllocCountDataSet = new DefaultCategoryDataset();
-        mChart = ChartFactory.createBarChart(null, "Size", "Count", mAllocCountDataSet,
-                PlotOrientation.VERTICAL, false, true, false);
-        
-        // get the font to make a proper title. We need to convert the swt font,
-        // into an awt font.
-        Font f = mStatisticsBase.getFont();
-        FontData[] fData = f.getFontData();
-        
-        // event though on Mac OS there could be more than one fontData, we'll only use
-        // the first one.
-        FontData firstFontData = fData[0];
-        
-        java.awt.Font awtFont = SWTUtils.toAwtFont(mStatisticsBase.getDisplay(),
-                firstFontData, true /* ensureSameSize */);
-
-        mChart.setTitle(new TextTitle("Allocation count per size", awtFont));
-        
-        Plot plot = mChart.getPlot();
-        if (plot instanceof CategoryPlot) {
-            // get the plot
-            CategoryPlot categoryPlot = (CategoryPlot)plot;
-            
-            // set the domain axis to draw labels that are displayed even with many values.
-            CategoryAxis domainAxis = categoryPlot.getDomainAxis();
-            domainAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_90);
-            
-            CategoryItemRenderer renderer = categoryPlot.getRenderer();
-            renderer.setBaseToolTipGenerator(new CategoryToolTipGenerator() {
-                public String generateToolTip(CategoryDataset dataset, int row, int column) {
-                    // get the key for the size of the allocation
-                    ByteLong columnKey = (ByteLong)dataset.getColumnKey(column);
-                    String rowKey = (String)dataset.getRowKey(row);
-                    Number value = dataset.getValue(rowKey, columnKey);
-                    
-                    return String.format("%1$d %2$s of %3$d bytes", value.intValue(), rowKey, 
-                            columnKey.getValue());
-                }
-            });
-        }
-        mChartComposite = new ChartComposite(mStatisticsBase, SWT.BORDER, mChart,
-                ChartComposite.DEFAULT_WIDTH,
-                ChartComposite.DEFAULT_HEIGHT,
-                ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
-                ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
-                3000, // max draw width. We don't want it to zoom, so we put a big number
-                3000, // max draw height. We don't want it to zoom, so we put a big number
-                true,  // off-screen buffer
-                true,  // properties
-                true,  // save
-                true,  // print
-                false,  // zoom
-                true);   // tooltips
-
-        mChartComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-    }
-
-    private static String prettyByteCount(long bytes) {
-        double fracBytes = bytes;
-        String units = " B";
-        if (fracBytes < 1024) {
-            return sByteFormatter.format(fracBytes) + units;
-        } else {
-            fracBytes /= 1024;
-            units = " KB";
-        }
-        if (fracBytes >= 1024) {
-            fracBytes /= 1024;
-            units = " MB";
-        }
-        if (fracBytes >= 1024) {
-            fracBytes /= 1024;
-            units = " GB";
-        }
-
-        return sLargeByteFormatter.format(fracBytes) + units;
-    }
-
-    private static String approximateByteCount(long bytes) {
-        double fracBytes = bytes;
-        String units = "";
-        if (fracBytes >= 1024) {
-            fracBytes /= 1024;
-            units = "K";
-        }
-        if (fracBytes >= 1024) {
-            fracBytes /= 1024;
-            units = "M";
-        }
-        if (fracBytes >= 1024) {
-            fracBytes /= 1024;
-            units = "G";
-        }
-
-        return sByteFormatter.format(fracBytes) + units;
-    }
-
-    private static String addCommasToNumber(long num) {
-        return sCountFormatter.format(num);
-    }
-
-    private static String fractionalPercent(long num, long denom) {
-        double val = (double)num / (double)denom;
-        val *= 100;
-
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMinimumFractionDigits(2);
-        nf.setMaximumFractionDigits(2);
-        return nf.format(val) + "%";
-    }
-
-    private void fillSummaryTable(ClientData cd) {
-        if (mHeapSummary.isDisposed()) {
-            return;
-        }
-
-        mHeapSummary.setRedraw(false);
-        mHeapSummary.removeAll();
-
-        if (cd != null) {
-            synchronized (cd) {
-                Iterator<Integer> iter = cd.getVmHeapIds();
-    
-                while (iter.hasNext()) {
-                    Integer id = iter.next();
-                    Map<String, Long> heapInfo = cd.getVmHeapInfo(id);
-                    if (heapInfo == null) {
-                        continue;
-                    }
-                    long sizeInBytes = heapInfo.get(ClientData.HEAP_SIZE_BYTES);
-                    long bytesAllocated = heapInfo.get(ClientData.HEAP_BYTES_ALLOCATED);
-                    long objectsAllocated = heapInfo.get(ClientData.HEAP_OBJECTS_ALLOCATED);
-    
-                    TableItem item = new TableItem(mHeapSummary, SWT.NONE);
-                    item.setText(0, id.toString());
-    
-                    item.setText(1, prettyByteCount(sizeInBytes));
-                    item.setText(2, prettyByteCount(bytesAllocated));
-                    item.setText(3, prettyByteCount(sizeInBytes - bytesAllocated));
-                    item.setText(4, fractionalPercent(bytesAllocated, sizeInBytes));
-                    item.setText(5, addCommasToNumber(objectsAllocated));
-                }
-            }
-        }
-
-        mHeapSummary.pack();
-        mHeapSummary.setRedraw(true);
-    }
-    
-    private void fillDetailedTable(Client client, boolean forceRedraw) {
-        // first check if the client is invalid or heap updates are not enabled.
-        if (client == null || client.isHeapUpdateEnabled() == false) {
-            mStatisticsTable.removeAll();
-            showChart(null);
-            return;
-        }
-        
-        ClientData cd = client.getClientData();
-
-        Map<Integer, ArrayList<HeapSegmentElement>> heapMap;
-
-        // Atomically get and clear the heap data.
-        synchronized (cd) {
-            if (serializeHeapData(cd.getVmHeapData()) == false && forceRedraw == false) {
-                // no change, we return.
-                return;
-            }
-            
-            heapMap = cd.getVmHeapData().getProcessedHeapMap();
-        }
-        
-        // we have new data, lets display it.
-        
-        // First, get the current selection, and its key.
-        int index = mStatisticsTable.getSelectionIndex();
-        Integer selectedKey = null;
-        if (index != -1) {
-            selectedKey = (Integer)mStatisticsTable.getItem(index).getData();
-        }
-
-        // disable redraws and remove all from the table.
-        mStatisticsTable.setRedraw(false);
-        mStatisticsTable.removeAll();
-        
-        if (heapMap != null) {
-            int selectedIndex = -1;
-            ArrayList<HeapSegmentElement> selectedList = null;
-            
-            // get the keys
-            Set<Integer> keys = heapMap.keySet();
-            int iter = 0; // use a manual iter int because Set<?> doesn't have an index
-            // based accessor.
-            for (Integer key : keys) {
-                ArrayList<HeapSegmentElement> list = heapMap.get(key);
-
-                // check if this is the key that is supposed to be selected
-                if (key.equals(selectedKey)) {
-                    selectedIndex = iter;
-                    selectedList = list;
-                }
-                iter++;
-
-                TableItem item = new TableItem(mStatisticsTable, SWT.NONE);
-                item.setData(key);
-
-                // get the type
-                item.setText(0, mMapLegend[key]);
-                
-                // set the count, smallest, largest
-                int count = list.size();
-                item.setText(1, addCommasToNumber(count));
-                
-                if (count > 0) {
-                    item.setText(3, prettyByteCount(list.get(0).getLength()));
-                    item.setText(4, prettyByteCount(list.get(count-1).getLength()));
-
-                    int median = count / 2;
-                    HeapSegmentElement element = list.get(median);
-                    long size = element.getLength();
-                    item.setText(5, prettyByteCount(size));
-
-                    long totalSize = 0;
-                    for (int i = 0 ; i < count; i++) {
-                        element = list.get(i);
-                        
-                        size = element.getLength();
-                        totalSize += size;
-                    }
-                    
-                    // set the average and total
-                    item.setText(2, prettyByteCount(totalSize));
-                    item.setText(6, prettyByteCount(totalSize / count));
-                }
-            }
-
-            mStatisticsTable.setRedraw(true);
-            
-            if (selectedIndex != -1) {
-                mStatisticsTable.setSelection(selectedIndex);
-                showChart(selectedList);
-            } else {
-                showChart(null);
-            }
-        } else {
-            mStatisticsTable.setRedraw(true);
-        }
-    }
-    
-    private static class ByteLong implements Comparable<ByteLong> {
-        private long mValue;
-        
-        private ByteLong(long value) {
-            mValue = value;
-        }
-        
-        public long getValue() {
-            return mValue;
-        }
-
-        @Override
-        public String toString() {
-            return approximateByteCount(mValue);
-        }
-
-        public int compareTo(ByteLong other) {
-            if (mValue != other.mValue) {
-                return mValue < other.mValue ? -1 : 1;
-            }
-            return 0;
-        }
-        
-    }
-    
-    /**
-     * Fills the chart with the content of the list of {@link HeapSegmentElement}.
-     */
-    private void showChart(ArrayList<HeapSegmentElement> list) {
-        mAllocCountDataSet.clear();
-
-        if (list != null) {
-            String rowKey = "Alloc Count";
-    
-            long currentSize = -1;
-            int currentCount = 0;
-            for (HeapSegmentElement element : list) {
-                if (element.getLength() != currentSize) {
-                    if (currentSize != -1) {
-                        ByteLong columnKey = new ByteLong(currentSize);
-                        mAllocCountDataSet.addValue(currentCount, rowKey, columnKey);
-                    }
-                    
-                    currentSize = element.getLength();
-                    currentCount = 1;
-                } else {
-                    currentCount++;
-                }
-            }
-            
-            // add the last item
-            if (currentSize != -1) {
-                ByteLong columnKey = new ByteLong(currentSize);
-                mAllocCountDataSet.addValue(currentCount, rowKey, columnKey);
-            }
-        }
-    }
-
-    /*
-     * Add a color legend to the specified table.
-     */
-    private void createLegend(Composite parent) {
-        mLegend = new Group(parent, SWT.NONE);
-        mLegend.setText(getLegendText(0));
-
-        mLegend.setLayout(new GridLayout(2, false));
-
-        RGB[] colors = mMapPalette.colors;
-
-        for (int i = 0; i < NUM_PALETTE_ENTRIES; i++) {
-            Image tmpImage = createColorRect(parent.getDisplay(), colors[i]);
-
-            Label l = new Label(mLegend, SWT.NONE);
-            l.setImage(tmpImage);
-
-            l = new Label(mLegend, SWT.NONE);
-            l.setText(mMapLegend[i]);
-        }
-    }
-
-    private String getLegendText(int level) {
-        int bytes = 8 * (100 / ZOOMS[level]);
-
-        return String.format("Key (1 pixel = %1$d bytes)", bytes);
-    }
-
-    private void setLegendText(int level) {
-        mLegend.setText(getLegendText(level));
-
-    }
-
-    /*
-     * Create a nice rectangle in the specified color.
-     */
-    private Image createColorRect(Display display, RGB color) {
-        int width = 32;
-        int height = 16;
-
-        Image img = new Image(display, width, height);
-        GC gc = new GC(img);
-        gc.setBackground(new Color(display, color));
-        gc.fillRectangle(0, 0, width, height);
-        gc.dispose();
-        return img;
-    }
-
-
-    /*
-     * Are updates enabled?
-     */
-    private void setUpdateStatus(int status) {
-        switch (status) {
-            case NOT_SELECTED:
-                mUpdateStatus.setText("Select a client to see heap updates");
-                break;
-            case NOT_ENABLED:
-                mUpdateStatus.setText("Heap updates are " +
-                                      "NOT ENABLED for this client");
-                break;
-            case ENABLED:
-                mUpdateStatus.setText("Heap updates will happen after " +
-                                      "every GC for this client");
-                break;
-            default:
-                throw new RuntimeException();
-        }
-
-        mUpdateStatus.pack();
-    }
-
-
-    /**
-     * Return the closest power of two greater than or equal to value.
-     *
-     * @param value the return value will be >= value
-     * @return a power of two >= value.  If value > 2^31, 2^31 is returned.
-     */
-//xxx use Integer.highestOneBit() or numberOfLeadingZeros().
-    private int nextPow2(int value) {
-        for (int i = 31; i >= 0; --i) {
-            if ((value & (1<<i)) != 0) {
-                if (i < 31) {
-                    return 1<<(i + 1);
-                } else {
-                    return 1<<31;
-                }
-            }
-        }
-        return 0;
-    }
-
-    private int zOrderData(ImageData id, byte pixData[]) {
-        int maxX = 0;
-        for (int i = 0; i < pixData.length; i++) {
-            /* Tread the pixData index as a z-order curve index and
-             * decompose into Cartesian coordinates.
-             */
-            int x = (i & 1) |
-                    ((i >>> 2) & 1) << 1 |
-                    ((i >>> 4) & 1) << 2 |
-                    ((i >>> 6) & 1) << 3 |
-                    ((i >>> 8) & 1) << 4 |
-                    ((i >>> 10) & 1) << 5 |
-                    ((i >>> 12) & 1) << 6 |
-                    ((i >>> 14) & 1) << 7 |
-                    ((i >>> 16) & 1) << 8 |
-                    ((i >>> 18) & 1) << 9 |
-                    ((i >>> 20) & 1) << 10 |
-                    ((i >>> 22) & 1) << 11 |
-                    ((i >>> 24) & 1) << 12 |
-                    ((i >>> 26) & 1) << 13 |
-                    ((i >>> 28) & 1) << 14 |
-                    ((i >>> 30) & 1) << 15;
-            int y = ((i >>> 1) & 1) << 0 |
-                    ((i >>> 3) & 1) << 1 |
-                    ((i >>> 5) & 1) << 2 |
-                    ((i >>> 7) & 1) << 3 |
-                    ((i >>> 9) & 1) << 4 |
-                    ((i >>> 11) & 1) << 5 |
-                    ((i >>> 13) & 1) << 6 |
-                    ((i >>> 15) & 1) << 7 |
-                    ((i >>> 17) & 1) << 8 |
-                    ((i >>> 19) & 1) << 9 |
-                    ((i >>> 21) & 1) << 10 |
-                    ((i >>> 23) & 1) << 11 |
-                    ((i >>> 25) & 1) << 12 |
-                    ((i >>> 27) & 1) << 13 |
-                    ((i >>> 29) & 1) << 14 |
-                    ((i >>> 31) & 1) << 15;
-            try {
-                id.setPixel(x, y, pixData[i]);
-                if (x > maxX) {
-                    maxX = x;
-                }
-            } catch (IllegalArgumentException ex) {
-                System.out.println("bad pixels: i " + i +
-                        ", w " + id.width +
-                        ", h " + id.height +
-                        ", x " + x +
-                        ", y " + y);
-                throw ex;
-            }
-        }
-        return maxX;
-    }
-
-    private final static int HILBERT_DIR_N = 0;
-    private final static int HILBERT_DIR_S = 1;
-    private final static int HILBERT_DIR_E = 2;
-    private final static int HILBERT_DIR_W = 3;
-
-    private void hilbertWalk(ImageData id, InputStream pixData,
-                             int order, int x, int y, int dir)
-                             throws IOException {
-        if (x >= id.width || y >= id.height) {
-            return;
-        } else if (order == 0) {
-            try {
-                int p = pixData.read();
-                if (p >= 0) {
-                    // flip along x=y axis;  assume width == height
-                    id.setPixel(y, x, p);
-
-                    /* Skanky; use an otherwise-unused ImageData field
-                     * to keep track of the max x,y used. Note that x and y are inverted.
-                     */
-                    if (y > id.x) {
-                        id.x = y;
-                    }
-                    if (x > id.y) {
-                        id.y = x;
-                    }
-                }
-//xxx just give up; don't bother walking the rest of the image
-            } catch (IllegalArgumentException ex) {
-                System.out.println("bad pixels: order " + order +
-                        ", dir " + dir +
-                        ", w " + id.width +
-                        ", h " + id.height +
-                        ", x " + x +
-                        ", y " + y);
-                throw ex;
-            }
-        } else {
-            order--;
-            int delta = 1 << order;
-            int nextX = x + delta;
-            int nextY = y + delta;
-
-            switch (dir) {
-            case HILBERT_DIR_E:
-                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_N);
-                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_E);
-                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_E);
-                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_S);
-                break;
-            case HILBERT_DIR_N:
-                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_E);
-                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_N);
-                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_N);
-                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_W);
-                break;
-            case HILBERT_DIR_S:
-                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_W);
-                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_S);
-                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_S);
-                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_E);
-                break;
-            case HILBERT_DIR_W:
-                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_S);
-                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_W);
-                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_W);
-                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_N);
-                break;
-            default:
-                throw new RuntimeException("Unexpected Hilbert direction " +
-                                           dir);
-            }
-        }
-    }
-
-    private Point hilbertOrderData(ImageData id, byte pixData[]) {
-
-        int order = 0;
-        for (int n = 1; n < id.width; n *= 2) {
-            order++;
-        }
-        /* Skanky; use an otherwise-unused ImageData field
-         * to keep track of maxX.
-         */
-        Point p = new Point(0,0);
-        int oldIdX = id.x;
-        int oldIdY = id.y;
-        id.x = id.y = 0;
-        try {
-            hilbertWalk(id, new ByteArrayInputStream(pixData),
-                        order, 0, 0, HILBERT_DIR_E);
-            p.x = id.x;
-            p.y = id.y;
-        } catch (IOException ex) {
-            System.err.println("Exception during hilbertWalk()");
-            p.x = id.height;
-            p.y = id.width;
-        }
-        id.x = oldIdX;
-        id.y = oldIdY;
-        return p;
-    }
-
-    private ImageData createHilbertHeapImage(byte pixData[]) {
-        int w, h;
-
-        // Pick an image size that the largest of heaps will fit into.
-        w = (int)Math.sqrt((double)((16 * 1024 * 1024)/8));
-
-        // Space-filling curves require a power-of-2 width.
-        w = nextPow2(w);
-        h = w;
-
-        // Create the heap image.
-        ImageData id = new ImageData(w, h, 8, mMapPalette);
-
-        // Copy the data into the image
-        //int maxX = zOrderData(id, pixData);
-        Point maxP = hilbertOrderData(id, pixData);
-
-        // update the max size to make it a round number once the zoom is applied
-        int factor = 100 / ZOOMS[mZoom.getSelectionIndex()];
-        if (factor != 1) {
-            int tmp = maxP.x % factor;
-            if (tmp != 0) {
-                maxP.x += factor - tmp;
-            }
-
-            tmp = maxP.y % factor;
-            if (tmp != 0) {
-                maxP.y += factor - tmp;
-            }
-        }
-
-        if (maxP.y < id.height) {
-            // Crop the image down to the interesting part.
-            id = new ImageData(id.width, maxP.y, id.depth, id.palette,
-                               id.scanlinePad, id.data);
-        }
-
-        if (maxP.x < id.width) {
-            // crop the image again. A bit trickier this time.
-           ImageData croppedId = new ImageData(maxP.x, id.height, id.depth, id.palette);
-
-           int[] buffer = new int[maxP.x];
-           for (int l = 0 ; l < id.height; l++) {
-               id.getPixels(0, l, maxP.x, buffer, 0);
-               croppedId.setPixels(0, l, maxP.x, buffer, 0);
-           }
-
-           id = croppedId;
-        }
-
-        // apply the zoom
-        if (factor != 1) {
-            id = id.scaledTo(id.width / factor, id.height / factor);
-        }
-
-        return id;
-    }
-
-    /**
-     * Convert the raw heap data to an image.  We know we're running in
-     * the UI thread, so we can issue graphics commands directly.
-     *
-     * http://help.eclipse.org/help31/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html
-     *
-     * @param cd The client data
-     * @param mode The display mode. 0 = linear, 1 = hilbert.
-     * @param forceRedraw
-     */
-    private void renderHeapData(ClientData cd, int mode, boolean forceRedraw) {
-        Image image;
-
-        byte[] pixData;
-
-        // Atomically get and clear the heap data.
-        synchronized (cd) {
-            if (serializeHeapData(cd.getVmHeapData()) == false && forceRedraw == false) {
-                // no change, we return.
-                return;
-            }
-
-            pixData = getSerializedData();
-        }
-
-        if (pixData != null) {
-            ImageData id;
-            if (mode == 1) {
-                id = createHilbertHeapImage(pixData);
-            } else {
-                id = createLinearHeapImage(pixData, 200, mMapPalette);
-            }
-
-            image = new Image(mDisplay, id);
-        } else {
-            // Render a placeholder image.
-            int width, height;
-            if (mode == 1) {
-                width = height = PLACEHOLDER_HILBERT_SIZE;
-            } else {
-                width = PLACEHOLDER_LINEAR_H_SIZE;
-                height = PLACEHOLDER_LINEAR_V_SIZE;
-            }
-            image = new Image(mDisplay, width, height);
-            GC gc = new GC(image);
-            gc.setForeground(mDisplay.getSystemColor(SWT.COLOR_RED));
-            gc.drawLine(0, 0, width-1, height-1);
-            gc.dispose();
-            gc = null;
-        }
-
-        // set the new image
-
-        if (mode == 1) {
-            if (mHilbertImage != null) {
-                mHilbertImage.dispose();
-            }
-
-            mHilbertImage = image;
-            mHilbertHeapImage.setImage(mHilbertImage);
-            mHilbertHeapImage.pack(true);
-            mHilbertBase.layout();
-            mHilbertBase.pack(true);
-        } else {
-            if (mLinearImage != null) {
-                mLinearImage.dispose();
-            }
-
-            mLinearImage = image;
-            mLinearHeapImage.setImage(mLinearImage);
-            mLinearHeapImage.pack(true);
-            mLinearBase.layout();
-            mLinearBase.pack(true);
-        }
-    }
-
-    @Override
-    protected void setTableFocusListener() {
-        addTableToFocusListener(mHeapSummary);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/IImageLoader.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/IImageLoader.java
deleted file mode 100644
index bcbf612..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/IImageLoader.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * Interface defining an image loader. jar app/lib and plugin have different packaging method
- * so each implementation will be different.
- * The implementation should implement at least one of the methods, and preferably both if possible.
- *
- */
-public interface IImageLoader {
-
-    /**
-     * Load an image from the resource from a filename
-     * @param filename
-     * @param display
-     */
-    public Image loadImage(String filename, Display display);
-
-    /**
-     * Load an ImageDescriptor from the resource from a filename
-     * @param filename
-     * @param display
-     */
-    public ImageDescriptor loadDescriptor(String filename, Display display);
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ITableFocusListener.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ITableFocusListener.java
deleted file mode 100644
index bf425d9..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ITableFocusListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import org.eclipse.swt.dnd.Clipboard;
-
-/**
- * An object listening to focus change in Table objects.<br>
- * For application not relying on a RCP to provide menu changes based on focus,
- * this class allows to get monitor the focus change of several Table widget
- * and update the menu action accordingly.
- */
-public interface ITableFocusListener {
-
-	public interface IFocusedTableActivator {
-		public void copy(Clipboard clipboard);
-
-		public void selectAll();
-	}
-
-	public void focusGained(IFocusedTableActivator activator);
-
-	public void focusLost(IFocusedTableActivator activator);
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageHelper.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageHelper.java
deleted file mode 100644
index d65978b..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageHelper.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Log;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-public class ImageHelper {
-
-    /**
-     * Loads an image from a resource. This method used a class to locate the
-     * resources, and then load the filename from /images inside the resources.<br>
-     * Extra parameters allows for creation of a replacement image of the
-     * loading failed.
-     *
-     * @param loader the image loader used.
-     * @param display the Display object
-     * @param fileName the file name
-     * @param width optional width to create replacement Image. If -1, null be
-     *            be returned if the loading fails.
-     * @param height optional height to create replacement Image. If -1, null be
-     *            be returned if the loading fails.
-     * @param phColor optional color to create replacement Image. If null, Blue
-     *            color will be used.
-     * @return a new Image or null if the loading failed and the optional
-     *         replacement size was -1
-     */
-    public static Image loadImage(IImageLoader loader, Display display,
-            String fileName, int width, int height, Color phColor) {
-
-        Image img = null;
-        if (loader != null) {
-            img = loader.loadImage(fileName, display);
-        }
-
-        if (img == null) {
-            Log.w("ddms", "Couldn't load " + fileName);
-            // if we had the extra parameter to create replacement image then we
-            // create and return it.
-            if (width != -1 && height != -1) {
-                return createPlaceHolderArt(display, width, height,
-                        phColor != null ? phColor : display
-                                .getSystemColor(SWT.COLOR_BLUE));
-            }
-
-            // otherwise, just return null
-            return null;
-        }
-
-        return img;
-    }
-
-    /**
-     * Create place-holder art with the specified color.
-     */
-    public static Image createPlaceHolderArt(Display display, int width,
-            int height, Color color) {
-        Image img = new Image(display, width, height);
-        GC gc = new GC(img);
-        gc.setForeground(color);
-        gc.drawLine(0, 0, width, height);
-        gc.drawLine(0, height - 1, width, -1);
-        gc.dispose();
-        return img;
-    }
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageLoader.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageLoader.java
deleted file mode 100644
index 76f2285..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageLoader.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-import java.io.InputStream;
-
-/**
- * Image loader for an normal standalone app.
- */
-public class ImageLoader implements IImageLoader {
-
-    /** class used as reference to get the reources */
-    private Class<?> mClass;
-
-    /**
-     * Creates a loader for a specific class. The class allows java to figure
-     * out which .jar file to search for the image.
-     *
-     * @param theClass
-     */
-    public ImageLoader(Class<?> theClass) {
-        mClass = theClass;
-    }
-
-    public ImageDescriptor loadDescriptor(String filename, Display display) {
-        // we don't support ImageDescriptor
-        return null;
-    }
-
-    public Image loadImage(String filename, Display display) {
-
-        String tmp = "/images/" + filename;
-        InputStream imageStream = mClass.getResourceAsStream(tmp);
-
-        if (imageStream != null) {
-            Image img = new Image(display, imageStream);
-            if (img == null)
-                throw new NullPointerException("couldn't load " + tmp);
-            return img;
-        }
-
-        return null;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java
deleted file mode 100644
index 6cbb999..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-
-/**
- * Display client info in a two-column format.
- */
-public class InfoPanel extends TablePanel {
-    private Table mTable;
-    private TableColumn mCol2;
-
-    private static final String mLabels[] = {
-        "DDM-aware?",
-        "App description:",
-        "VM version:",
-        "Process ID:",
-        "Supports Profiling Control:",
-        "Supports HPROF Control:",
-    };
-    private static final int ENT_DDM_AWARE          = 0;
-    private static final int ENT_APP_DESCR          = 1;
-    private static final int ENT_VM_VERSION         = 2;
-    private static final int ENT_PROCESS_ID         = 3;
-    private static final int ENT_SUPPORTS_PROFILING = 4;
-    private static final int ENT_SUPPORTS_HPROF     = 5;
-
-    /**
-     * Create our control(s).
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        mTable = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION);
-        mTable.setHeaderVisible(false);
-        mTable.setLinesVisible(false);
-
-        TableColumn col1 = new TableColumn(mTable, SWT.RIGHT);
-        col1.setText("name");
-        mCol2 = new TableColumn(mTable, SWT.LEFT);
-        mCol2.setText("PlaceHolderContentForWidth");
-
-        TableItem item;
-        for (int i = 0; i < mLabels.length; i++) {
-            item = new TableItem(mTable, SWT.NONE);
-            item.setText(0, mLabels[i]);
-            item.setText(1, "-");
-        }
-
-        col1.pack();
-        mCol2.pack();
-
-        return mTable;
-    }
-
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        mTable.setFocus();
-    }
-
-
-    /**
-     * Sent when an existing client information changed.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param client the updated client.
-     * @param changeMask the bit mask describing the changed properties. It can contain
-     * any of the following values: {@link Client#CHANGE_PORT}, {@link Client#CHANGE_NAME}
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-     * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-     * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-     *
-     * @see IClientChangeListener#clientChanged(Client, int)
-     */
-    public void clientChanged(final Client client, int changeMask) {
-        if (client == getCurrentClient()) {
-            if ((changeMask & Client.CHANGE_INFO) == Client.CHANGE_INFO) {
-                if (mTable.isDisposed())
-                    return;
-
-                mTable.getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        clientSelected();
-                    }
-                });
-            }
-        }
-    }
-
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}
-     */
-    @Override
-    public void deviceSelected() {
-        // pass
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}
-     */
-    @Override
-    public void clientSelected() {
-        if (mTable.isDisposed())
-            return;
-
-        Client client = getCurrentClient();
-
-        if (client == null) {
-            for (int i = 0; i < mLabels.length; i++) {
-                TableItem item = mTable.getItem(i);
-                item.setText(1, "-");
-            }
-        } else {
-            TableItem item;
-            String clientDescription, vmIdentifier, isDdmAware,
-                pid;
-
-            ClientData cd = client.getClientData();
-            synchronized (cd) {
-                clientDescription = (cd.getClientDescription() != null) ?
-                        cd.getClientDescription() : "?";
-                vmIdentifier = (cd.getVmIdentifier() != null) ?
-                        cd.getVmIdentifier() : "?";
-                isDdmAware = cd.isDdmAware() ?
-                        "yes" : "no";
-                pid = (cd.getPid() != 0) ?
-                        String.valueOf(cd.getPid()) : "?";
-            }
-
-            item = mTable.getItem(ENT_APP_DESCR);
-            item.setText(1, clientDescription);
-            item = mTable.getItem(ENT_VM_VERSION);
-            item.setText(1, vmIdentifier);
-            item = mTable.getItem(ENT_DDM_AWARE);
-            item.setText(1, isDdmAware);
-            item = mTable.getItem(ENT_PROCESS_ID);
-            item.setText(1, pid);
-            item = mTable.getItem(ENT_SUPPORTS_PROFILING);
-            item.setText(1, Boolean.toString(cd.hasFeature(ClientData.FEATURE_PROFILING)));
-            item = mTable.getItem(ENT_SUPPORTS_HPROF);
-            item.setText(1, Boolean.toString(cd.hasFeature(ClientData.FEATURE_HPROF)));
-        }
-
-        mCol2.pack();
-
-        //Log.i("ddms", "InfoPanel: changed " + client);
-    }
-
-    @Override
-    protected void setTableFocusListener() {
-        addTableToFocusListener(mTable);
-    }
-}
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java
deleted file mode 100644
index 0b2460b..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java
+++ /dev/null
@@ -1,1633 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.NativeAllocationInfo;
-import com.android.ddmlib.NativeLibraryMapInfo;
-import com.android.ddmlib.NativeStackCallInfo;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.HeapSegment.HeapSegmentElement;
-import com.android.ddmuilib.annotation.WorkerThread;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Sash;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * Panel with native heap information.
- */
-public final class NativeHeapPanel extends BaseHeapPanel {
-
-    /** color palette and map legend. NATIVE is the last enum is a 0 based enum list, so we need
-     * Native+1 at least. We also need 2 more entries for free area and expansion area.  */
-    private static final int NUM_PALETTE_ENTRIES = HeapSegmentElement.KIND_NATIVE+2 +1;
-    private static final String[] mMapLegend = new String[NUM_PALETTE_ENTRIES];
-    private static final PaletteData mMapPalette = createPalette();
-    
-    private static final int ALLOC_DISPLAY_ALL = 0;
-    private static final int ALLOC_DISPLAY_PRE_ZYGOTE = 1;
-    private static final int ALLOC_DISPLAY_POST_ZYGOTE = 2;
-
-    private Display mDisplay;
-
-    private Composite mBase;
-
-    private Label mUpdateStatus;
-
-    /** combo giving choice of what to display: all, pre-zygote, post-zygote */
-    private Combo mAllocDisplayCombo;
-
-    private Button mFullUpdateButton;
-
-    // see CreateControl()
-    //private Button mDiffUpdateButton;
-
-    private Combo mDisplayModeCombo;
-
-    /** stack composite for mode (1-2) & 3 */
-    private Composite mTopStackComposite;
-
-    private StackLayout mTopStackLayout;
-
-    /** stack composite for mode 1 & 2 */
-    private Composite mAllocationStackComposite;
-
-    private StackLayout mAllocationStackLayout;
-
-    /** top level container for mode 1 & 2 */
-    private Composite mTableModeControl;
-
-    /** top level object for the allocation mode */
-    private Control mAllocationModeTop;
-
-    /** top level for the library mode */
-    private Control mLibraryModeTopControl;
-
-    /** composite for page UI and total memory display */
-    private Composite mPageUIComposite;
-
-    private Label mTotalMemoryLabel;
-
-    private Label mPageLabel;
-
-    private Button mPageNextButton;
-
-    private Button mPagePreviousButton;
-
-    private Table mAllocationTable;
-
-    private Table mLibraryTable;
-
-    private Table mLibraryAllocationTable;
-
-    private Table mDetailTable;
-
-    private Label mImage;
-    
-    private int mAllocDisplayMode = ALLOC_DISPLAY_ALL;
-
-    /**
-     * pointer to current stackcall thread computation in order to quit it if
-     * required (new update requested)
-     */
-    private StackCallThread mStackCallThread;
-
-    /** Current Library Allocation table fill thread. killed if selection changes */
-    private FillTableThread mFillTableThread;
-
-    /**
-     * current client data. Used to access the malloc info when switching pages
-     * or selecting allocation to show stack call
-     */
-    private ClientData mClientData;
-
-    /**
-     * client data from a previous display. used when asking for an "update & diff"
-     */
-    private ClientData mBackUpClientData;
-
-    /** list of NativeAllocationInfo objects filled with the list from ClientData */
-    private final ArrayList<NativeAllocationInfo> mAllocations =
-        new ArrayList<NativeAllocationInfo>();
-    
-    /** list of the {@link NativeAllocationInfo} being displayed based on the selection
-     * of {@link #mAllocDisplayCombo}.
-     */
-    private final ArrayList<NativeAllocationInfo> mDisplayedAllocations =
-        new ArrayList<NativeAllocationInfo>();
-
-    /** list of NativeAllocationInfo object kept as backup when doing an "update & diff" */
-    private final ArrayList<NativeAllocationInfo> mBackUpAllocations =
-        new ArrayList<NativeAllocationInfo>();
-
-    /** back up of the total memory, used when doing an "update & diff" */
-    private int mBackUpTotalMemory;
-
-    private int mCurrentPage = 0;
-
-    private int mPageCount = 0;
-
-    /**
-     * list of allocation per Library. This is created from the list of
-     * NativeAllocationInfo objects that is stored in the ClientData object. Since we
-     * don't keep this list around, it is recomputed everytime the client
-     * changes.
-     */
-    private final ArrayList<LibraryAllocations> mLibraryAllocations =
-        new ArrayList<LibraryAllocations>();
-
-    /* args to setUpdateStatus() */
-    private static final int NOT_SELECTED = 0;
-
-    private static final int NOT_ENABLED = 1;
-
-    private static final int ENABLED = 2;
-
-    private static final int DISPLAY_PER_PAGE = 20;
-
-    private static final String PREFS_ALLOCATION_SASH = "NHallocSash"; //$NON-NLS-1$
-    private static final String PREFS_LIBRARY_SASH = "NHlibrarySash"; //$NON-NLS-1$
-    private static final String PREFS_DETAIL_ADDRESS = "NHdetailAddress"; //$NON-NLS-1$
-    private static final String PREFS_DETAIL_LIBRARY = "NHdetailLibrary"; //$NON-NLS-1$
-    private static final String PREFS_DETAIL_METHOD = "NHdetailMethod"; //$NON-NLS-1$
-    private static final String PREFS_DETAIL_FILE = "NHdetailFile"; //$NON-NLS-1$
-    private static final String PREFS_DETAIL_LINE = "NHdetailLine"; //$NON-NLS-1$
-    private static final String PREFS_ALLOC_TOTAL = "NHallocTotal"; //$NON-NLS-1$
-    private static final String PREFS_ALLOC_COUNT = "NHallocCount"; //$NON-NLS-1$
-    private static final String PREFS_ALLOC_SIZE = "NHallocSize"; //$NON-NLS-1$
-    private static final String PREFS_ALLOC_LIBRARY = "NHallocLib"; //$NON-NLS-1$
-    private static final String PREFS_ALLOC_METHOD = "NHallocMethod"; //$NON-NLS-1$
-    private static final String PREFS_ALLOC_FILE = "NHallocFile"; //$NON-NLS-1$
-    private static final String PREFS_LIB_LIBRARY = "NHlibLibrary"; //$NON-NLS-1$
-    private static final String PREFS_LIB_SIZE = "NHlibSize"; //$NON-NLS-1$
-    private static final String PREFS_LIB_COUNT = "NHlibCount"; //$NON-NLS-1$
-    private static final String PREFS_LIBALLOC_TOTAL = "NHlibAllocTotal"; //$NON-NLS-1$
-    private static final String PREFS_LIBALLOC_COUNT = "NHlibAllocCount"; //$NON-NLS-1$
-    private static final String PREFS_LIBALLOC_SIZE = "NHlibAllocSize"; //$NON-NLS-1$
-    private static final String PREFS_LIBALLOC_METHOD = "NHlibAllocMethod"; //$NON-NLS-1$
-
-    /** static formatter object to format all numbers as #,### */
-    private static DecimalFormat sFormatter;
-    static {
-        sFormatter = (DecimalFormat)NumberFormat.getInstance();
-        if (sFormatter != null)
-            sFormatter = new DecimalFormat("#,###");
-        else
-            sFormatter.applyPattern("#,###");
-    }
-
-
-    /**
-     * caching mechanism to avoid recomputing the backtrace for a particular
-     * address several times.
-     */
-    private HashMap<Long, NativeStackCallInfo> mSourceCache =
-        new HashMap<Long,NativeStackCallInfo>();
-    private long mTotalSize;
-    private Button mSaveButton;
-    private Button mSymbolsButton;
-
-    /**
-     * thread class to convert the address call into method, file and line
-     * number in the background.
-     */
-    private class StackCallThread extends BackgroundThread {
-        private ClientData mClientData;
-
-        public StackCallThread(ClientData cd) {
-            mClientData = cd;
-        }
-
-        public ClientData getClientData() {
-            return mClientData;
-        }
-
-        @Override
-        public void run() {
-            // loop through all the NativeAllocationInfo and init them
-            Iterator<NativeAllocationInfo> iter = mAllocations.iterator();
-            int total = mAllocations.size();
-            int count = 0;
-            while (iter.hasNext()) {
-
-                if (isQuitting())
-                    return;
-
-                NativeAllocationInfo info = iter.next();
-                if (info.isStackCallResolved() == false) {
-                    final Long[] list = info.getStackCallAddresses();
-                    final int size = list.length;
-                    
-                    ArrayList<NativeStackCallInfo> resolvedStackCall =
-                        new ArrayList<NativeStackCallInfo>(); 
-
-                    for (int i = 0; i < size; i++) {
-                        long addr = list[i];
-
-                        // first check if the addr has already been converted.
-                        NativeStackCallInfo source = mSourceCache.get(addr);
-
-                        // if not we convert it
-                        if (source == null) {
-                            source = sourceForAddr(addr);
-                            mSourceCache.put(addr, source);
-                        }
-
-                        resolvedStackCall.add(source);
-                    }
-                    
-                    info.setResolvedStackCall(resolvedStackCall);
-                }
-                // after every DISPLAY_PER_PAGE we ask for a ui refresh, unless
-                // we reach total, since we also do it after the loop
-                // (only an issue in case we have a perfect number of page)
-                count++;
-                if ((count % DISPLAY_PER_PAGE) == 0 && count != total) {
-                    if (updateNHAllocationStackCalls(mClientData, count) == false) {
-                        // looks like the app is quitting, so we just
-                        // stopped the thread
-                        return;
-                    }
-                }
-            }
-
-            updateNHAllocationStackCalls(mClientData, count);
-        }
-
-        private NativeStackCallInfo sourceForAddr(long addr) {
-            NativeLibraryMapInfo library = getLibraryFor(addr);
-
-            if (library != null) {
-
-                Addr2Line process = Addr2Line.getProcess(library.getLibraryName());
-                if (process != null) {
-                    // remove the base of the library address
-                    long value = addr - library.getStartAddress();
-                    NativeStackCallInfo info = process.getAddress(value);
-                    if (info != null) {
-                        return info;
-                    }
-                }
-            }
-
-            return new NativeStackCallInfo(library != null ? library.getLibraryName() : null,
-                    Long.toHexString(addr), "");
-        }
-
-        private NativeLibraryMapInfo getLibraryFor(long addr) {
-            Iterator<NativeLibraryMapInfo> it = mClientData.getNativeLibraryMapInfo();
-
-            while (it.hasNext()) {
-                NativeLibraryMapInfo info = it.next();
-
-                if (info.isWithinLibrary(addr)) {
-                    return info;
-                }
-            }
-
-            Log.d("ddm-nativeheap", "Failed finding Library for " + Long.toHexString(addr));
-            return null;
-        }
-
-        /**
-         * update the Native Heap panel with the amount of allocation for which the
-         * stack call has been computed. This is called from a non UI thread, but
-         * will be executed in the UI thread.
-         *
-         * @param count the amount of allocation
-         * @return false if the display was disposed and the update couldn't happen
-         */
-        private boolean updateNHAllocationStackCalls(final ClientData clientData, final int count) {
-            if (mDisplay.isDisposed() == false) {
-                mDisplay.asyncExec(new Runnable() {
-                    public void run() {
-                        updateAllocationStackCalls(clientData, count);
-                    }
-                });
-                return true;
-            }
-            return false;
-        }
-    }
-
-    private class FillTableThread extends BackgroundThread {
-        private LibraryAllocations mLibAlloc;
-
-        private int mMax;
-
-        public FillTableThread(LibraryAllocations liballoc, int m) {
-            mLibAlloc = liballoc;
-            mMax = m;
-        }
-
-        @Override
-        public void run() {
-            for (int i = mMax; i > 0 && isQuitting() == false; i -= 10) {
-                updateNHLibraryAllocationTable(mLibAlloc, mMax - i, mMax - i + 10);
-            }
-        }
-
-        /**
-         * updates the library allocation table in the Native Heap panel. This is
-         * called from a non UI thread, but will be executed in the UI thread.
-         *
-         * @param liballoc the current library allocation object being displayed
-         * @param start start index of items that need to be displayed
-         * @param end end index of the items that need to be displayed
-         */
-        private void updateNHLibraryAllocationTable(final LibraryAllocations libAlloc,
-                final int start, final int end) {
-            if (mDisplay.isDisposed() == false) {
-                mDisplay.asyncExec(new Runnable() {
-                    public void run() {
-                        updateLibraryAllocationTable(libAlloc, start, end);
-                    }
-                });
-            }
-
-        }
-    }
-
-    /** class to aggregate allocations per library */
-    public static class LibraryAllocations {
-        private String mLibrary;
-
-        private final ArrayList<NativeAllocationInfo> mLibAllocations =
-            new ArrayList<NativeAllocationInfo>();
-
-        private int mSize;
-
-        private int mCount;
-
-        /** construct the aggregate object for a library */
-        public LibraryAllocations(final String lib) {
-            mLibrary = lib;
-        }
-
-        /** get the library name */
-        public String getLibrary() {
-            return mLibrary;
-        }
-
-        /** add a NativeAllocationInfo object to this aggregate object */
-        public void addAllocation(NativeAllocationInfo info) {
-            mLibAllocations.add(info);
-        }
-
-        /** get an iterator on the NativeAllocationInfo objects */
-        public Iterator<NativeAllocationInfo> getAllocations() {
-            return mLibAllocations.iterator();
-        }
-
-        /** get a NativeAllocationInfo object by index */
-        public NativeAllocationInfo getAllocation(int index) {
-            return mLibAllocations.get(index);
-        }
-
-        /** returns the NativeAllocationInfo object count */
-        public int getAllocationSize() {
-            return mLibAllocations.size();
-        }
-
-        /** returns the total allocation size */
-        public int getSize() {
-            return mSize;
-        }
-
-        /** returns the number of allocations */
-        public int getCount() {
-            return mCount;
-        }
-
-        /**
-         * compute the allocation count and size for allocation objects added
-         * through <code>addAllocation()</code>, and sort the objects by
-         * total allocation size.
-         */
-        public void computeAllocationSizeAndCount() {
-            mSize = 0;
-            mCount = 0;
-            for (NativeAllocationInfo info : mLibAllocations) {
-                mCount += info.getAllocationCount();
-                mSize += info.getAllocationCount() * info.getSize();
-            }
-            Collections.sort(mLibAllocations, new Comparator<NativeAllocationInfo>() {
-                public int compare(NativeAllocationInfo o1, NativeAllocationInfo o2) {
-                    return o2.getAllocationCount() * o2.getSize() -
-                        o1.getAllocationCount() * o1.getSize();
-                }
-            });
-        }
-    }
-
-    /**
-     * Create our control(s).
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-
-        mDisplay = parent.getDisplay();
-
-        mBase = new Composite(parent, SWT.NONE);
-        GridLayout gl = new GridLayout(1, false);
-        gl.horizontalSpacing = 0;
-        gl.verticalSpacing = 0;
-        mBase.setLayout(gl);
-        mBase.setLayoutData(new GridData(GridData.FILL_BOTH));
-        
-        // composite for <update btn> <status>
-        Composite tmp = new Composite(mBase, SWT.NONE);
-        tmp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        tmp.setLayout(gl = new GridLayout(2, false));
-        gl.marginWidth = gl.marginHeight = 0;
-
-        mFullUpdateButton = new Button(tmp, SWT.NONE);
-        mFullUpdateButton.setText("Full Update");
-        mFullUpdateButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mBackUpClientData = null;
-                mDisplayModeCombo.setEnabled(false);
-                mSaveButton.setEnabled(false);
-                emptyTables();
-                // if we already have a stack call computation for this
-                // client
-                // we stop it
-                if (mStackCallThread != null &&
-                        mStackCallThread.getClientData() == mClientData) {
-                    mStackCallThread.quit();
-                    mStackCallThread = null;
-                }
-                mLibraryAllocations.clear();
-                Client client = getCurrentClient();
-                if (client != null) {
-                    client.requestNativeHeapInformation();
-                }
-            }
-        });
-
-        mUpdateStatus = new Label(tmp, SWT.NONE);
-        mUpdateStatus.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        // top layout for the combos and oter controls on the right.
-        Composite top_layout = new Composite(mBase, SWT.NONE);
-        top_layout.setLayout(gl = new GridLayout(4, false));
-        gl.marginWidth = gl.marginHeight = 0;
-        
-        new Label(top_layout, SWT.NONE).setText("Show:");
-        
-        mAllocDisplayCombo = new Combo(top_layout, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mAllocDisplayCombo.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mAllocDisplayCombo.add("All Allocations");
-        mAllocDisplayCombo.add("Pre-Zygote Allocations");
-        mAllocDisplayCombo.add("Zygote Child Allocations (Z)");
-        mAllocDisplayCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onAllocDisplayChange();
-            }
-        });
-        mAllocDisplayCombo.select(0);
-        
-        // separator
-        Label separator = new Label(top_layout, SWT.SEPARATOR | SWT.VERTICAL);
-        GridData gd;
-        separator.setLayoutData(gd = new GridData(
-                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
-        gd.heightHint = 0;
-        gd.verticalSpan = 2;
-
-        mSaveButton = new Button(top_layout, SWT.PUSH);
-        mSaveButton.setText("Save...");
-        mSaveButton.setEnabled(false);
-        mSaveButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                FileDialog fileDialog = new FileDialog(mBase.getShell(), SWT.SAVE);
-
-                fileDialog.setText("Save Allocations");
-                fileDialog.setFileName("allocations.txt");
-
-                String fileName = fileDialog.open();
-                if (fileName != null) {
-                    saveAllocations(fileName);
-                }
-            }
-        });
-        
-        /*
-         * TODO: either fix the diff mechanism or remove it altogether.
-        mDiffUpdateButton = new Button(top_layout, SWT.NONE);
-        mDiffUpdateButton.setText("Update && Diff");
-        mDiffUpdateButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // since this is an update and diff, we need to store the
-                // current list
-                // of mallocs
-                mBackUpAllocations.clear();
-                mBackUpAllocations.addAll(mAllocations);
-                mBackUpClientData = mClientData;
-                mBackUpTotalMemory = mClientData.getTotalNativeMemory();
-
-                mDisplayModeCombo.setEnabled(false);
-                emptyTables();
-                // if we already have a stack call computation for this
-                // client
-                // we stop it
-                if (mStackCallThread != null &&
-                        mStackCallThread.getClientData() == mClientData) {
-                    mStackCallThread.quit();
-                    mStackCallThread = null;
-                }
-                mLibraryAllocations.clear();
-                Client client = getCurrentClient();
-                if (client != null) {
-                    client.requestNativeHeapInformation();
-                }
-            }
-        });
-        */
-
-        Label l = new Label(top_layout, SWT.NONE);
-        l.setText("Display:");
-
-        mDisplayModeCombo = new Combo(top_layout, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mDisplayModeCombo.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mDisplayModeCombo.setItems(new String[] { "Allocation List", "By Libraries" });
-        mDisplayModeCombo.select(0);
-        mDisplayModeCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                switchDisplayMode();
-            }
-        });
-        mDisplayModeCombo.setEnabled(false);
-        
-        mSymbolsButton = new Button(top_layout, SWT.PUSH);
-        mSymbolsButton.setText("Load Symbols");
-        mSymbolsButton.setEnabled(false);
-
-
-        // create a composite that will contains the actual content composites,
-        // in stack mode layout.
-        // This top level composite contains 2 other composites.
-        // * one for both Allocations and Libraries mode
-        // * one for flat mode (which is gone for now)
-
-        mTopStackComposite = new Composite(mBase, SWT.NONE);
-        mTopStackComposite.setLayout(mTopStackLayout = new StackLayout());
-        mTopStackComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        // create 1st and 2nd modes
-        createTableDisplay(mTopStackComposite);
-
-        mTopStackLayout.topControl = mTableModeControl;
-        mTopStackComposite.layout();
-
-        setUpdateStatus(NOT_SELECTED);
-
-        // Work in progress
-        // TODO add image display of native heap.
-        //mImage = new Label(mBase, SWT.NONE);
-
-        mBase.pack();
-
-        return mBase;
-    }
-    
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        // TODO
-    }
-
-
-    /**
-     * Sent when an existing client information changed.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param client the updated client.
-     * @param changeMask the bit mask describing the changed properties. It can contain
-     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-     * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-     * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-     *
-     * @see IClientChangeListener#clientChanged(Client, int)
-     */
-    public void clientChanged(final Client client, int changeMask) {
-        if (client == getCurrentClient()) {
-            if ((changeMask & Client.CHANGE_NATIVE_HEAP_DATA) == Client.CHANGE_NATIVE_HEAP_DATA) {
-                if (mBase.isDisposed())
-                    return;
-
-                mBase.getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        clientSelected();
-                    }
-                });
-            }
-        }
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}.
-     */
-    @Override
-    public void deviceSelected() {
-        // pass
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}.
-     */
-    @Override
-    public void clientSelected() {
-        if (mBase.isDisposed())
-            return;
-
-        Client client = getCurrentClient();
-
-        mDisplayModeCombo.setEnabled(false);
-        emptyTables();
-
-        Log.d("ddms", "NativeHeapPanel: changed " + client);
-
-        if (client != null) {
-            ClientData cd = client.getClientData();
-            mClientData = cd;
-
-            // if (cd.getShowHeapUpdates())
-            setUpdateStatus(ENABLED);
-            // else
-            // setUpdateStatus(NOT_ENABLED);
-
-            initAllocationDisplay();
-
-            //renderBitmap(cd);
-        } else {
-            mClientData = null;
-            setUpdateStatus(NOT_SELECTED);
-        }
-
-        mBase.pack();
-    }
-
-    /**
-     * Update the UI with the newly compute stack calls, unless the UI switched
-     * to a different client.
-     *
-     * @param cd the ClientData for which the stack call are being computed.
-     * @param count the current count of allocations for which the stack calls
-     *            have been computed.
-     */
-    @WorkerThread
-    public void updateAllocationStackCalls(ClientData cd, int count) {
-        // we have to check that the panel still shows the same clientdata than
-        // the thread is computing for.
-        if (cd == mClientData) {
-
-            int total = mAllocations.size();
-
-            if (count == total) {
-                // we're done: do something
-                mDisplayModeCombo.setEnabled(true);
-                mSaveButton.setEnabled(true);
-                
-                mStackCallThread = null;
-            } else {
-                // work in progress, update the progress bar.
-//                mUiThread.setStatusLine("Computing stack call: " + count
-//                        + "/" + total);
-            }
-
-            // FIXME: attempt to only update when needed.
-            // Because the number of pages is not related to mAllocations.size() anymore
-            // due to pre-zygote/post-zygote display, update all the time.
-            // At some point we should remove the pages anyway, since it's getting computed
-            // really fast now.
-//            if ((mCurrentPage + 1) * DISPLAY_PER_PAGE == count
-//                    || (count == total && mCurrentPage == mPageCount - 1)) {
-            try {
-                // get the current selection of the allocation
-                int index = mAllocationTable.getSelectionIndex();
-                NativeAllocationInfo info = null;
-                
-                if (index != -1) {
-                    info = (NativeAllocationInfo)mAllocationTable.getItem(index).getData();
-                }
-
-                // empty the table
-                emptyTables();
-
-                // fill it again
-                fillAllocationTable();
-
-                // reselect
-                mAllocationTable.setSelection(index);
-
-                // display detail table if needed
-                if (info != null) {
-                    fillDetailTable(info);
-                }
-            } catch (SWTException e) {
-                if (mAllocationTable.isDisposed()) {
-                    // looks like the table is disposed. Let's ignore it.
-                } else {
-                    throw e;
-                }
-            }
-
-        } else {
-            // old client still running. doesn't really matter.
-        }
-    }
-
-    @Override
-    protected void setTableFocusListener() {
-        addTableToFocusListener(mAllocationTable);
-        addTableToFocusListener(mLibraryTable);
-        addTableToFocusListener(mLibraryAllocationTable);
-        addTableToFocusListener(mDetailTable);
-    }
-    
-    protected void onAllocDisplayChange() {
-        mAllocDisplayMode = mAllocDisplayCombo.getSelectionIndex();
-        
-        // create the new list
-        updateAllocDisplayList();
-        
-        updateTotalMemoryDisplay();
-
-        // reset the ui.
-        mCurrentPage = 0;
-        updatePageUI();
-        switchDisplayMode();
-    }
-    
-    private void updateAllocDisplayList() {
-        mTotalSize = 0;
-        mDisplayedAllocations.clear();
-        for (NativeAllocationInfo info : mAllocations) {
-            if (mAllocDisplayMode == ALLOC_DISPLAY_ALL ||
-                    (mAllocDisplayMode == ALLOC_DISPLAY_PRE_ZYGOTE ^ info.isZygoteChild())) {
-                mDisplayedAllocations.add(info);
-                mTotalSize += info.getSize() * info.getAllocationCount();
-            } else {
-                // skip this item
-                continue;
-            }
-        }
-        
-        int count = mDisplayedAllocations.size();
-        
-        mPageCount = count / DISPLAY_PER_PAGE;
-
-        // need to add a page for the rest of the div
-        if ((count % DISPLAY_PER_PAGE) > 0) {
-            mPageCount++;
-        }
-    }
-    
-    private void updateTotalMemoryDisplay() {
-        switch (mAllocDisplayMode) {
-            case ALLOC_DISPLAY_ALL:
-                mTotalMemoryLabel.setText(String.format("Total Memory: %1$s Bytes",
-                        sFormatter.format(mTotalSize)));
-                break;
-            case ALLOC_DISPLAY_PRE_ZYGOTE:
-                mTotalMemoryLabel.setText(String.format("Zygote Memory: %1$s Bytes",
-                        sFormatter.format(mTotalSize)));
-                break;
-            case ALLOC_DISPLAY_POST_ZYGOTE:
-                mTotalMemoryLabel.setText(String.format("Post-zygote Memory: %1$s Bytes",
-                        sFormatter.format(mTotalSize)));
-                break;
-        }
-    }
-
-
-    private void switchDisplayMode() {
-        switch (mDisplayModeCombo.getSelectionIndex()) {
-            case 0: {// allocations
-                mTopStackLayout.topControl = mTableModeControl;
-                mAllocationStackLayout.topControl = mAllocationModeTop;
-                mAllocationStackComposite.layout();
-                mTopStackComposite.layout();
-                emptyTables();
-                fillAllocationTable();
-            }
-                break;
-            case 1: {// libraries
-                mTopStackLayout.topControl = mTableModeControl;
-                mAllocationStackLayout.topControl = mLibraryModeTopControl;
-                mAllocationStackComposite.layout();
-                mTopStackComposite.layout();
-                emptyTables();
-                fillLibraryTable();
-            }
-                break;
-        }
-    }
-
-    private void initAllocationDisplay() {
-        mAllocations.clear();
-        mAllocations.addAll(mClientData.getNativeAllocationList());
-        
-        updateAllocDisplayList();
-
-        // if we have a previous clientdata and it matches the current one. we
-        // do a diff between the new list and the old one.
-        if (mBackUpClientData != null && mBackUpClientData == mClientData) {
-
-            ArrayList<NativeAllocationInfo> add = new ArrayList<NativeAllocationInfo>();
-
-            // we go through the list of NativeAllocationInfo in the new list and check if
-            // there's one with the same exact data (size, allocation, count and
-            // stackcall addresses) in the old list.
-            // if we don't find any, we add it to the "add" list
-            for (NativeAllocationInfo mi : mAllocations) {
-                boolean found = false;
-                for (NativeAllocationInfo old_mi : mBackUpAllocations) {
-                    if (mi.equals(old_mi)) {
-                        found = true;
-                        break;
-                    }
-                }
-                if (found == false) {
-                    add.add(mi);
-                }
-            }
-
-            // put the result in mAllocations
-            mAllocations.clear();
-            mAllocations.addAll(add);
-
-            // display the difference in memory usage. This is computed
-            // calculating the memory usage of the objects in mAllocations.
-            int count = 0;
-            for (NativeAllocationInfo allocInfo : mAllocations) {
-                count += allocInfo.getSize() * allocInfo.getAllocationCount();
-            }
-
-            mTotalMemoryLabel.setText(String.format("Memory Difference: %1$s Bytes",
-                    sFormatter.format(count)));
-        }
-        else {
-            // display the full memory usage
-            updateTotalMemoryDisplay();
-            //mDiffUpdateButton.setEnabled(mClientData.getTotalNativeMemory() > 0);
-        }
-        mTotalMemoryLabel.pack();
-
-        // update the page ui
-        mDisplayModeCombo.select(0);
-
-        mLibraryAllocations.clear();
-
-        // reset to first page
-        mCurrentPage = 0;
-
-        // update the label
-        updatePageUI();
-
-        // now fill the allocation Table with the current page
-        switchDisplayMode();
-
-        // start the thread to compute the stack calls
-        if (mAllocations.size() > 0) {
-            mStackCallThread = new StackCallThread(mClientData);
-            mStackCallThread.start();
-        }
-    }
-
-    private void updatePageUI() {
-
-        // set the label and pack to update the layout, otherwise
-        // the label will be cut off if the new size is bigger
-        if (mPageCount == 0) {
-            mPageLabel.setText("0 of 0 allocations.");
-        } else {
-            StringBuffer buffer = new StringBuffer();
-            // get our starting index
-            int start = (mCurrentPage * DISPLAY_PER_PAGE) + 1;
-            // end index, taking into account the last page can be half full
-            int count = mDisplayedAllocations.size();
-            int end = Math.min(start + DISPLAY_PER_PAGE - 1, count);
-            buffer.append(sFormatter.format(start));
-            buffer.append(" - ");
-            buffer.append(sFormatter.format(end));
-            buffer.append(" of ");
-            buffer.append(sFormatter.format(count));
-            buffer.append(" allocations.");
-            mPageLabel.setText(buffer.toString());
-        }
-
-        // handle the button enabled state.
-        mPagePreviousButton.setEnabled(mCurrentPage > 0);
-        // reminder: mCurrentPage starts at 0.
-        mPageNextButton.setEnabled(mCurrentPage < mPageCount - 1);
-
-        mPageLabel.pack();
-        mPageUIComposite.pack();
-
-    }
-
-    private void fillAllocationTable() {
-        // get the count
-        int count = mDisplayedAllocations.size();
-
-        // get our starting index
-        int start = mCurrentPage * DISPLAY_PER_PAGE;
-
-        // loop for DISPLAY_PER_PAGE or till we reach count
-        int end = start + DISPLAY_PER_PAGE;
-
-        for (int i = start; i < end && i < count; i++) {
-            NativeAllocationInfo info = mDisplayedAllocations.get(i);
-
-            TableItem item = null;
-
-            if (mAllocDisplayMode == ALLOC_DISPLAY_ALL)  {
-                item = new TableItem(mAllocationTable, SWT.NONE);
-                item.setText(0, (info.isZygoteChild() ? "Z " : "") +
-                        sFormatter.format(info.getSize() * info.getAllocationCount()));
-                item.setText(1, sFormatter.format(info.getAllocationCount()));
-                item.setText(2, sFormatter.format(info.getSize()));
-            } else if (mAllocDisplayMode == ALLOC_DISPLAY_PRE_ZYGOTE ^ info.isZygoteChild()) {
-                item = new TableItem(mAllocationTable, SWT.NONE);
-                item.setText(0, sFormatter.format(info.getSize() * info.getAllocationCount()));
-                item.setText(1, sFormatter.format(info.getAllocationCount()));
-                item.setText(2, sFormatter.format(info.getSize()));
-            } else {
-                // skip this item
-                continue;
-            }
-
-            item.setData(info);
-
-            NativeStackCallInfo bti = info.getRelevantStackCallInfo();
-            if (bti != null) {
-                String lib = bti.getLibraryName();
-                String method = bti.getMethodName();
-                String source = bti.getSourceFile();
-                if (lib != null)
-                    item.setText(3, lib);
-                if (method != null)
-                    item.setText(4, method);
-                if (source != null)
-                    item.setText(5, source);
-            }
-        }
-    }
-
-    private void fillLibraryTable() {
-        // fill the library table
-        sortAllocationsPerLibrary();
-
-        for (LibraryAllocations liballoc : mLibraryAllocations) {
-            if (liballoc != null) {
-                TableItem item = new TableItem(mLibraryTable, SWT.NONE);
-                String lib = liballoc.getLibrary();
-                item.setText(0, lib != null ? lib : "");
-                item.setText(1, sFormatter.format(liballoc.getSize()));
-                item.setText(2, sFormatter.format(liballoc.getCount()));
-            }
-        }
-    }
-
-    private void fillLibraryAllocationTable() {
-        mLibraryAllocationTable.removeAll();
-        mDetailTable.removeAll();
-        int index = mLibraryTable.getSelectionIndex();
-        if (index != -1) {
-            LibraryAllocations liballoc = mLibraryAllocations.get(index);
-            // start a thread that will fill table 10 at a time to keep the ui
-            // responsive, but first we kill the previous one if there was one
-            if (mFillTableThread != null) {
-                mFillTableThread.quit();
-            }
-            mFillTableThread = new FillTableThread(liballoc,
-                    liballoc.getAllocationSize());
-            mFillTableThread.start();
-        }
-    }
-
-    public void updateLibraryAllocationTable(LibraryAllocations liballoc,
-            int start, int end) {
-        try {
-            if (mLibraryTable.isDisposed() == false) {
-                int index = mLibraryTable.getSelectionIndex();
-                if (index != -1) {
-                    LibraryAllocations newliballoc = mLibraryAllocations.get(
-                            index);
-                    if (newliballoc == liballoc) {
-                        int count = liballoc.getAllocationSize();
-                        for (int i = start; i < end && i < count; i++) {
-                            NativeAllocationInfo info = liballoc.getAllocation(i);
-
-                            TableItem item = new TableItem(
-                                    mLibraryAllocationTable, SWT.NONE);
-                            item.setText(0, sFormatter.format(
-                                    info.getSize() * info.getAllocationCount()));
-                            item.setText(1, sFormatter.format(info.getAllocationCount()));
-                            item.setText(2, sFormatter.format(info.getSize()));
-
-                            NativeStackCallInfo stackCallInfo = info.getRelevantStackCallInfo();
-                            if (stackCallInfo != null) {
-                                item.setText(3, stackCallInfo.getMethodName());
-                            }
-                        }
-                    } else {
-                        // we should quit the thread
-                        if (mFillTableThread != null) {
-                            mFillTableThread.quit();
-                            mFillTableThread = null;
-                        }
-                    }
-                }
-            }
-        } catch (SWTException e) {
-            Log.e("ddms", "error when updating the library allocation table");
-        }
-    }
-
-    private void fillDetailTable(final NativeAllocationInfo mi) {
-        mDetailTable.removeAll();
-        mDetailTable.setRedraw(false);
-        
-        try {
-            // populate the detail Table with the back trace
-            Long[] addresses = mi.getStackCallAddresses();
-            NativeStackCallInfo[] resolvedStackCall = mi.getResolvedStackCall();
-            
-            if (resolvedStackCall == null) {
-                return;
-            }
-
-            for (int i = 0 ; i < resolvedStackCall.length ; i++) {
-                if (addresses[i] == null || addresses[i].longValue() == 0) {
-                    continue;
-                }
-                
-                long addr = addresses[i].longValue();
-                NativeStackCallInfo source = resolvedStackCall[i];
-                
-                TableItem item = new TableItem(mDetailTable, SWT.NONE);
-                item.setText(0, String.format("%08x", addr)); //$NON-NLS-1$
-    
-                String libraryName = source.getLibraryName();
-                String methodName = source.getMethodName();
-                String sourceFile = source.getSourceFile();
-                int lineNumber = source.getLineNumber();
-                
-                if (libraryName != null)
-                    item.setText(1, libraryName);
-                if (methodName != null)
-                    item.setText(2, methodName);
-                if (sourceFile != null)
-                    item.setText(3, sourceFile);
-                if (lineNumber != -1)
-                    item.setText(4, Integer.toString(lineNumber));
-            }
-        } finally {
-            mDetailTable.setRedraw(true);
-        }
-    }
-
-    /*
-     * Are updates enabled?
-     */
-    private void setUpdateStatus(int status) {
-        switch (status) {
-            case NOT_SELECTED:
-                mUpdateStatus.setText("Select a client to see heap info");
-                mAllocDisplayCombo.setEnabled(false);
-                mFullUpdateButton.setEnabled(false);
-                //mDiffUpdateButton.setEnabled(false);
-                break;
-            case NOT_ENABLED:
-                mUpdateStatus.setText("Heap updates are " + "NOT ENABLED for this client");
-                mAllocDisplayCombo.setEnabled(false);
-                mFullUpdateButton.setEnabled(false);
-                //mDiffUpdateButton.setEnabled(false);
-                break;
-            case ENABLED:
-                mUpdateStatus.setText("Press 'Full Update' to retrieve " + "latest data");
-                mAllocDisplayCombo.setEnabled(true);
-                mFullUpdateButton.setEnabled(true);
-                //mDiffUpdateButton.setEnabled(true);
-                break;
-            default:
-                throw new RuntimeException();
-        }
-
-        mUpdateStatus.pack();
-    }
-
-    /**
-     * Create the Table display. This includes a "detail" Table in the bottom
-     * half and 2 modes in the top half: allocation Table and
-     * library+allocations Tables.
-     *
-     * @param base the top parent to create the display into
-     */
-    private void createTableDisplay(Composite base) {
-        final int minPanelWidth = 60;
-
-        final IPreferenceStore prefs = DdmUiPreferences.getStore();
-
-        // top level composite for mode 1 & 2
-        mTableModeControl = new Composite(base, SWT.NONE);
-        GridLayout gl = new GridLayout(1, false);
-        gl.marginLeft = gl.marginRight = gl.marginTop = gl.marginBottom = 0;
-        mTableModeControl.setLayout(gl);
-        mTableModeControl.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        mTotalMemoryLabel = new Label(mTableModeControl, SWT.NONE);
-        mTotalMemoryLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mTotalMemoryLabel.setText("Total Memory: 0 Bytes");
-
-        // the top half of these modes is dynamic
-
-        final Composite sash_composite = new Composite(mTableModeControl,
-                SWT.NONE);
-        sash_composite.setLayout(new FormLayout());
-        sash_composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        // create the stacked composite
-        mAllocationStackComposite = new Composite(sash_composite, SWT.NONE);
-        mAllocationStackLayout = new StackLayout();
-        mAllocationStackComposite.setLayout(mAllocationStackLayout);
-        mAllocationStackComposite.setLayoutData(new GridData(
-                GridData.FILL_BOTH));
-
-        // create the top half for mode 1
-        createAllocationTopHalf(mAllocationStackComposite);
-
-        // create the top half for mode 2
-        createLibraryTopHalf(mAllocationStackComposite);
-
-        final Sash sash = new Sash(sash_composite, SWT.HORIZONTAL);
-
-        // bottom half of these modes is the same: detail table
-        createDetailTable(sash_composite);
-
-        // init value for stack
-        mAllocationStackLayout.topControl = mAllocationModeTop;
-
-        // form layout data
-        FormData data = new FormData();
-        data.top = new FormAttachment(mTotalMemoryLabel, 0);
-        data.bottom = new FormAttachment(sash, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        mAllocationStackComposite.setLayoutData(data);
-
-        final FormData sashData = new FormData();
-        if (prefs != null && prefs.contains(PREFS_ALLOCATION_SASH)) {
-            sashData.top = new FormAttachment(0,
-                    prefs.getInt(PREFS_ALLOCATION_SASH));
-        } else {
-            sashData.top = new FormAttachment(50, 0); // 50% across
-        }
-        sashData.left = new FormAttachment(0, 0);
-        sashData.right = new FormAttachment(100, 0);
-        sash.setLayoutData(sashData);
-
-        data = new FormData();
-        data.top = new FormAttachment(sash, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        mDetailTable.setLayoutData(data);
-
-        // allow resizes, but cap at minPanelWidth
-        sash.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                Rectangle sashRect = sash.getBounds();
-                Rectangle panelRect = sash_composite.getClientArea();
-                int bottom = panelRect.height - sashRect.height - minPanelWidth;
-                e.y = Math.max(Math.min(e.y, bottom), minPanelWidth);
-                if (e.y != sashRect.y) {
-                    sashData.top = new FormAttachment(0, e.y);
-                    prefs.setValue(PREFS_ALLOCATION_SASH, e.y);
-                    sash_composite.layout();
-                }
-            }
-        });
-    }
-
-    private void createDetailTable(Composite base) {
-
-        final IPreferenceStore prefs = DdmUiPreferences.getStore();
-
-        mDetailTable = new Table(base, SWT.MULTI | SWT.FULL_SELECTION);
-        mDetailTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mDetailTable.setHeaderVisible(true);
-        mDetailTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mDetailTable, "Address", SWT.RIGHT,
-                "00000000", PREFS_DETAIL_ADDRESS, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mDetailTable, "Library", SWT.LEFT,
-                "abcdefghijklmnopqrst", PREFS_DETAIL_LIBRARY, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mDetailTable, "Method", SWT.LEFT,
-                "abcdefghijklmnopqrst", PREFS_DETAIL_METHOD, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mDetailTable, "File", SWT.LEFT,
-                "abcdefghijklmnopqrstuvwxyz", PREFS_DETAIL_FILE, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mDetailTable, "Line", SWT.RIGHT,
-                "9,999", PREFS_DETAIL_LINE, prefs); //$NON-NLS-1$
-    }
-
-    private void createAllocationTopHalf(Composite b) {
-        final IPreferenceStore prefs = DdmUiPreferences.getStore();
-
-        Composite base = new Composite(b, SWT.NONE);
-        mAllocationModeTop = base;
-        GridLayout gl = new GridLayout(1, false);
-        gl.marginLeft = gl.marginRight = gl.marginTop = gl.marginBottom = 0;
-        gl.verticalSpacing = 0;
-        base.setLayout(gl);
-        base.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        // horizontal layout for memory total and pages UI
-        mPageUIComposite = new Composite(base, SWT.NONE);
-        mPageUIComposite.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_BEGINNING));
-        gl = new GridLayout(3, false);
-        gl.marginLeft = gl.marginRight = gl.marginTop = gl.marginBottom = 0;
-        gl.horizontalSpacing = 0;
-        mPageUIComposite.setLayout(gl);
-
-        // Page UI
-        mPagePreviousButton = new Button(mPageUIComposite, SWT.NONE);
-        mPagePreviousButton.setText("<");
-        mPagePreviousButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mCurrentPage--;
-                updatePageUI();
-                emptyTables();
-                fillAllocationTable();
-            }
-        });
-
-        mPageNextButton = new Button(mPageUIComposite, SWT.NONE);
-        mPageNextButton.setText(">");
-        mPageNextButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mCurrentPage++;
-                updatePageUI();
-                emptyTables();
-                fillAllocationTable();
-            }
-        });
-
-        mPageLabel = new Label(mPageUIComposite, SWT.NONE);
-        mPageLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        updatePageUI();
-
-        mAllocationTable = new Table(base, SWT.MULTI | SWT.FULL_SELECTION);
-        mAllocationTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mAllocationTable.setHeaderVisible(true);
-        mAllocationTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mAllocationTable, "Total", SWT.RIGHT,
-                "9,999,999", PREFS_ALLOC_TOTAL, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mAllocationTable, "Count", SWT.RIGHT,
-                "9,999", PREFS_ALLOC_COUNT, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mAllocationTable, "Size", SWT.RIGHT,
-                "999,999", PREFS_ALLOC_SIZE, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mAllocationTable, "Library", SWT.LEFT,
-                "abcdefghijklmnopqrst", PREFS_ALLOC_LIBRARY, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mAllocationTable, "Method", SWT.LEFT,
-                "abcdefghijklmnopqrst", PREFS_ALLOC_METHOD, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mAllocationTable, "File", SWT.LEFT,
-                "abcdefghijklmnopqrstuvwxyz", PREFS_ALLOC_FILE, prefs); //$NON-NLS-1$
-
-        mAllocationTable.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // get the selection index
-                int index = mAllocationTable.getSelectionIndex();
-                TableItem item = mAllocationTable.getItem(index);
-                if (item != null && item.getData() instanceof NativeAllocationInfo) {
-                    fillDetailTable((NativeAllocationInfo)item.getData());
-                }
-            }
-        });
-    }
-
-    private void createLibraryTopHalf(Composite base) {
-        final int minPanelWidth = 60;
-
-        final IPreferenceStore prefs = DdmUiPreferences.getStore();
-
-        // create a composite that'll contain 2 tables horizontally
-        final Composite top = new Composite(base, SWT.NONE);
-        mLibraryModeTopControl = top;
-        top.setLayout(new FormLayout());
-        top.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        // first table: library
-        mLibraryTable = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
-        mLibraryTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mLibraryTable.setHeaderVisible(true);
-        mLibraryTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mLibraryTable, "Library", SWT.LEFT,
-                "abcdefghijklmnopqrstuvwxyz", PREFS_LIB_LIBRARY, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mLibraryTable, "Size", SWT.RIGHT,
-                "9,999,999", PREFS_LIB_SIZE, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mLibraryTable, "Count", SWT.RIGHT,
-                "9,999", PREFS_LIB_COUNT, prefs); //$NON-NLS-1$
-
-        mLibraryTable.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                fillLibraryAllocationTable();
-            }
-        });
-
-        final Sash sash = new Sash(top, SWT.VERTICAL);
-
-        // 2nd table: allocation per library
-        mLibraryAllocationTable = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
-        mLibraryAllocationTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mLibraryAllocationTable.setHeaderVisible(true);
-        mLibraryAllocationTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mLibraryAllocationTable, "Total",
-                SWT.RIGHT, "9,999,999", PREFS_LIBALLOC_TOTAL, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mLibraryAllocationTable, "Count",
-                SWT.RIGHT, "9,999", PREFS_LIBALLOC_COUNT, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mLibraryAllocationTable, "Size",
-                SWT.RIGHT, "999,999", PREFS_LIBALLOC_SIZE, prefs); //$NON-NLS-1$
-        TableHelper.createTableColumn(mLibraryAllocationTable, "Method",
-                SWT.LEFT, "abcdefghijklmnopqrst", PREFS_LIBALLOC_METHOD, prefs); //$NON-NLS-1$
-
-        mLibraryAllocationTable.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // get the index of the selection in the library table
-                int index1 = mLibraryTable.getSelectionIndex();
-                // get the index in the library allocation table
-                int index2 = mLibraryAllocationTable.getSelectionIndex();
-                // get the MallocInfo object
-                LibraryAllocations liballoc = mLibraryAllocations.get(index1);
-                NativeAllocationInfo info = liballoc.getAllocation(index2);
-                fillDetailTable(info);
-            }
-        });
-
-        // form layout data
-        FormData data = new FormData();
-        data.top = new FormAttachment(0, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(sash, 0);
-        mLibraryTable.setLayoutData(data);
-
-        final FormData sashData = new FormData();
-        if (prefs != null && prefs.contains(PREFS_LIBRARY_SASH)) {
-            sashData.left = new FormAttachment(0,
-                    prefs.getInt(PREFS_LIBRARY_SASH));
-        } else {
-            sashData.left = new FormAttachment(50, 0);
-        }
-        sashData.bottom = new FormAttachment(100, 0);
-        sashData.top = new FormAttachment(0, 0); // 50% across
-        sash.setLayoutData(sashData);
-
-        data = new FormData();
-        data.top = new FormAttachment(0, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(sash, 0);
-        data.right = new FormAttachment(100, 0);
-        mLibraryAllocationTable.setLayoutData(data);
-
-        // allow resizes, but cap at minPanelWidth
-        sash.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                Rectangle sashRect = sash.getBounds();
-                Rectangle panelRect = top.getClientArea();
-                int right = panelRect.width - sashRect.width - minPanelWidth;
-                e.x = Math.max(Math.min(e.x, right), minPanelWidth);
-                if (e.x != sashRect.x) {
-                    sashData.left = new FormAttachment(0, e.x);
-                    prefs.setValue(PREFS_LIBRARY_SASH, e.y);
-                    top.layout();
-                }
-            }
-        });
-    }
-
-    private void emptyTables() {
-        mAllocationTable.removeAll();
-        mLibraryTable.removeAll();
-        mLibraryAllocationTable.removeAll();
-        mDetailTable.removeAll();
-    }
-
-    private void sortAllocationsPerLibrary() {
-        if (mClientData != null) {
-            mLibraryAllocations.clear();
-            
-            // create a hash map of LibraryAllocations to access aggregate
-            // objects already created
-            HashMap<String, LibraryAllocations> libcache =
-                new HashMap<String, LibraryAllocations>();
-
-            // get the allocation count
-            int count = mDisplayedAllocations.size();
-            for (int i = 0; i < count; i++) {
-                NativeAllocationInfo allocInfo = mDisplayedAllocations.get(i);
-
-                NativeStackCallInfo stackCallInfo = allocInfo.getRelevantStackCallInfo();
-                if (stackCallInfo != null) {
-                    String libraryName = stackCallInfo.getLibraryName();
-                    LibraryAllocations liballoc = libcache.get(libraryName);
-                    if (liballoc == null) {
-                        // didn't find a library allocation object already
-                        // created so we create one
-                        liballoc = new LibraryAllocations(libraryName);
-                        // add it to the cache
-                        libcache.put(libraryName, liballoc);
-                        // add it to the list
-                        mLibraryAllocations.add(liballoc);
-                    }
-                    // add the MallocInfo object to it.
-                    liballoc.addAllocation(allocInfo);
-                }
-            }
-            // now that the list is created, we need to compute the size and
-            // sort it by size. This will also sort the MallocInfo objects
-            // inside each LibraryAllocation objects.
-            for (LibraryAllocations liballoc : mLibraryAllocations) {
-                liballoc.computeAllocationSizeAndCount();
-            }
-
-            // now we sort it
-            Collections.sort(mLibraryAllocations,
-                    new Comparator<LibraryAllocations>() {
-                public int compare(LibraryAllocations o1,
-                        LibraryAllocations o2) {
-                    return o2.getSize() - o1.getSize();
-                }
-            });
-        }
-    }
-
-    private void renderBitmap(ClientData cd) {
-        byte[] pixData;
-
-        // Atomically get and clear the heap data.
-        synchronized (cd) {
-            if (serializeHeapData(cd.getVmHeapData()) == false) {
-                // no change, we return.
-                return;
-            }
-
-            pixData = getSerializedData();
-
-            ImageData id = createLinearHeapImage(pixData, 200, mMapPalette);
-            Image image = new Image(mBase.getDisplay(), id);
-            mImage.setImage(image);
-            mImage.pack(true);
-        }
-    }
-
-    /*
-     * Create color palette for map.  Set up titles for legend.
-     */
-    private static PaletteData createPalette() {
-        RGB colors[] = new RGB[NUM_PALETTE_ENTRIES];
-        colors[0]
-                = new RGB(192, 192, 192); // non-heap pixels are gray
-        mMapLegend[0]
-                = "(heap expansion area)";
-
-        colors[1]
-                = new RGB(0, 0, 0);       // free chunks are black
-        mMapLegend[1]
-                = "free";
-
-        colors[HeapSegmentElement.KIND_OBJECT + 2]
-                = new RGB(0, 0, 255);     // objects are blue
-        mMapLegend[HeapSegmentElement.KIND_OBJECT + 2]
-                = "data object";
-
-        colors[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
-                = new RGB(0, 255, 0);     // class objects are green
-        mMapLegend[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
-                = "class object";
-
-        colors[HeapSegmentElement.KIND_ARRAY_1 + 2]
-                = new RGB(255, 0, 0);     // byte/bool arrays are red
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_1 + 2]
-                = "1-byte array (byte[], boolean[])";
-
-        colors[HeapSegmentElement.KIND_ARRAY_2 + 2]
-                = new RGB(255, 128, 0);   // short/char arrays are orange
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_2 + 2]
-                = "2-byte array (short[], char[])";
-
-        colors[HeapSegmentElement.KIND_ARRAY_4 + 2]
-                = new RGB(255, 255, 0);   // obj/int/float arrays are yellow
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_4 + 2]
-                = "4-byte array (object[], int[], float[])";
-
-        colors[HeapSegmentElement.KIND_ARRAY_8 + 2]
-                = new RGB(255, 128, 128); // long/double arrays are pink
-        mMapLegend[HeapSegmentElement.KIND_ARRAY_8 + 2]
-                = "8-byte array (long[], double[])";
-
-        colors[HeapSegmentElement.KIND_UNKNOWN + 2]
-                = new RGB(255, 0, 255);   // unknown objects are cyan
-        mMapLegend[HeapSegmentElement.KIND_UNKNOWN + 2]
-                = "unknown object";
-
-        colors[HeapSegmentElement.KIND_NATIVE + 2]
-                = new RGB(64, 64, 64);    // native objects are dark gray
-        mMapLegend[HeapSegmentElement.KIND_NATIVE + 2]
-                = "non-Java object";
-
-        return new PaletteData(colors);
-    }
-    
-    private void saveAllocations(String fileName) {
-        try {
-            PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
-    
-            for (NativeAllocationInfo alloc : mAllocations) {
-                out.println(alloc.toString());
-            }
-            out.close();
-        } catch (IOException e) {
-            Log.e("Native", e);
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Panel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Panel.java
deleted file mode 100644
index d910cc7..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Panel.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-
-/**
- * Base class for our information panels.
- */
-public abstract class Panel {
-
-    public final Control createPanel(Composite parent) {
-        Control panelControl = createControl(parent);
-
-        postCreation();
-
-        return panelControl;
-    }
-
-    protected abstract void postCreation();
-
-    /**
-     * Creates a control capable of displaying some information.  This is
-     * called once, when the application is initializing, from the UI thread.
-     */
-    protected abstract Control createControl(Composite parent);
-    
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    public abstract void setFocus();
-}
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/PortFieldEditor.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/PortFieldEditor.java
deleted file mode 100644
index 533372e..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/PortFieldEditor.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import org.eclipse.jface.preference.IntegerFieldEditor;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * Edit an integer field, validating it as a port number.
- */
-public class PortFieldEditor extends IntegerFieldEditor {
-
-    public boolean mRecursiveCheck = false;
-
-    public PortFieldEditor(String name, String label, Composite parent) {
-        super(name, label, parent);
-        setValidateStrategy(VALIDATE_ON_KEY_STROKE);
-    }
-
-    /*
-     * Get the current value of the field, as an integer.
-     */
-    public int getCurrentValue() {
-        int val;
-        try {
-            val = Integer.parseInt(getStringValue());
-        }
-        catch (NumberFormatException nfe) {
-            val = -1;
-        }
-        return val;
-    }
-
-    /*
-     * Check the validity of the field.
-     */
-    @Override
-    protected boolean checkState() {
-        if (super.checkState() == false) {
-            return false;
-        }
-        //Log.i("ddms", "check state " + getStringValue());
-        boolean err = false;
-        int val = getCurrentValue();
-        if (val < 1024 || val > 32767) {
-            setErrorMessage("Port must be between 1024 and 32767");
-            err = true;
-        } else {
-            setErrorMessage(null);
-            err = false;
-        }
-        showErrorMessage();
-        return !err;
-    }
-
-    protected void updateCheckState(PortFieldEditor pfe) {
-        pfe.refreshValidState();
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
deleted file mode 100644
index 3a108f6..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.RawImage;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.ImageTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.ImageLoader;
-import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.IOException;
-
-
-/**
- * Gather a screen shot from the device and save it to a file.
- */
-public class ScreenShotDialog extends Dialog {
-
-    private Label mBusyLabel;
-    private Label mImageLabel;
-    private Button mSave;
-    private IDevice mDevice;
-    private RawImage mRawImage;
-    private Clipboard mClipboard;
-
-
-    /**
-     * Create with default style.
-     */
-    public ScreenShotDialog(Shell parent) {
-        this(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-        mClipboard = new Clipboard(parent.getDisplay());
-    }
-
-    /**
-     * Create with app-defined style.
-     */
-    public ScreenShotDialog(Shell parent, int style) {
-        super(parent, style);
-    }
-
-    /**
-     * Prepare and display the dialog.
-     * @param device The {@link IDevice} from which to get the screenshot.
-     */
-    public void open(IDevice device) {
-        mDevice = device;
-
-        Shell parent = getParent();
-        Shell shell = new Shell(parent, getStyle());
-        shell.setText("Device Screen Capture");
-
-        createContents(shell);
-        shell.pack();
-        shell.open();
-
-        updateDeviceImage(shell);
-
-        Display display = parent.getDisplay();
-        while (!shell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-
-    }
-
-    /*
-     * Create the screen capture dialog contents.
-     */
-    private void createContents(final Shell shell) {
-        GridData data;
-
-        final int colCount = 5;
-
-        shell.setLayout(new GridLayout(colCount, true));
-
-        // "refresh" button
-        Button refresh = new Button(shell, SWT.PUSH);
-        refresh.setText("Refresh");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.widthHint = 80;
-        refresh.setLayoutData(data);
-        refresh.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateDeviceImage(shell);
-            }
-        });
-
-        // "rotate" button
-        Button rotate = new Button(shell, SWT.PUSH);
-        rotate.setText("Rotate");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.widthHint = 80;
-        rotate.setLayoutData(data);
-        rotate.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mRawImage != null) {
-                    mRawImage = mRawImage.getRotated();
-                    updateImageDisplay(shell);
-                }
-            }
-        });
-
-        // "save" button
-        mSave = new Button(shell, SWT.PUSH);
-        mSave.setText("Save");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.widthHint = 80;
-        mSave.setLayoutData(data);
-        mSave.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                saveImage(shell);
-            }
-        });
-
-        Button copy = new Button(shell, SWT.PUSH);
-        copy.setText("Copy");
-        copy.setToolTipText("Copy the screenshot to the clipboard");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.widthHint = 80;
-        copy.setLayoutData(data);
-        copy.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                copy();
-            }
-        });
-
-
-        // "done" button
-        Button done = new Button(shell, SWT.PUSH);
-        done.setText("Done");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.widthHint = 80;
-        done.setLayoutData(data);
-        done.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                shell.close();
-            }
-        });
-
-        // title/"capturing" label
-        mBusyLabel = new Label(shell, SWT.NONE);
-        mBusyLabel.setText("Preparing...");
-        data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-        data.horizontalSpan = colCount;
-        mBusyLabel.setLayoutData(data);
-
-        // space for the image
-        mImageLabel = new Label(shell, SWT.BORDER);
-        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-        data.horizontalSpan = colCount;
-        mImageLabel.setLayoutData(data);
-        Display display = shell.getDisplay();
-        mImageLabel.setImage(ImageHelper.createPlaceHolderArt(
-                display, 50, 50, display.getSystemColor(SWT.COLOR_BLUE)));
-
-
-        shell.setDefaultButton(done);
-    }
-
-    /**
-     * Copies the content of {@link #mImageLabel} to the clipboard.
-     */
-    private void copy() {
-        mClipboard.setContents(
-                new Object[] {
-                        mImageLabel.getImage().getImageData()
-                }, new Transfer[] {
-                        ImageTransfer.getInstance()
-                });
-    }
-
-    /**
-     * Captures a new image from the device, and display it.
-     */
-    private void updateDeviceImage(Shell shell) {
-        mBusyLabel.setText("Capturing...");     // no effect
-
-        shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
-
-        mRawImage = getDeviceImage();
-
-        updateImageDisplay(shell);
-    }
-
-    /**
-     * Updates the display with {@link #mRawImage}.
-     * @param shell
-     */
-    private void updateImageDisplay(Shell shell) {
-        Image image;
-        if (mRawImage == null) {
-            Display display = shell.getDisplay();
-            image = ImageHelper.createPlaceHolderArt(
-                    display, 320, 240, display.getSystemColor(SWT.COLOR_BLUE));
-
-            mSave.setEnabled(false);
-            mBusyLabel.setText("Screen not available");
-        } else {
-            // convert raw data to an Image.
-            PaletteData palette = new PaletteData(
-                    mRawImage.getRedMask(),
-                    mRawImage.getGreenMask(),
-                    mRawImage.getBlueMask());
-
-            ImageData imageData = new ImageData(mRawImage.width, mRawImage.height,
-                    mRawImage.bpp, palette, 1, mRawImage.data);
-            image = new Image(getParent().getDisplay(), imageData);
-
-            mSave.setEnabled(true);
-            mBusyLabel.setText("Captured image:");
-        }
-
-        mImageLabel.setImage(image);
-        mImageLabel.pack();
-        shell.pack();
-
-        // there's no way to restore old cursor; assume it's ARROW
-        shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_ARROW));
-    }
-
-    /**
-     * Grabs an image from an ADB-connected device and returns it as a {@link RawImage}.
-     */
-    private RawImage getDeviceImage() {
-        try {
-            return mDevice.getScreenshot();
-        }
-        catch (IOException ioe) {
-            Log.w("ddms", "Unable to get frame buffer: " + ioe.getMessage());
-            return null;
-        }
-    }
-
-    /*
-     * Prompt the user to save the image to disk.
-     */
-    private void saveImage(Shell shell) {
-        FileDialog dlg = new FileDialog(shell, SWT.SAVE);
-        String fileName;
-
-        dlg.setText("Save image...");
-        dlg.setFileName("device.png");
-        dlg.setFilterPath(DdmUiPreferences.getStore().getString("lastImageSaveDir"));
-        dlg.setFilterNames(new String[] {
-            "PNG Files (*.png)"
-        });
-        dlg.setFilterExtensions(new String[] {
-            "*.png" //$NON-NLS-1$
-        });
-
-        fileName = dlg.open();
-        if (fileName != null) {
-            DdmUiPreferences.getStore().setValue("lastImageSaveDir", dlg.getFilterPath());
-
-            Log.d("ddms", "Saving image to " + fileName);
-            ImageData imageData = mImageLabel.getImage().getImageData();
-
-            try {
-                ImageLoader loader = new ImageLoader();
-                loader.data = new ImageData[] { imageData };
-                loader.save(fileName, SWT.IMAGE_PNG);
-            }
-            catch (SWTException e) {
-                Log.w("ddms", "Unable to save " + fileName + ": " + e.getMessage());
-            }
-        }
-    }
-
-}
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java
deleted file mode 100644
index e6d2211..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-
-/**
- * A Panel that requires {@link Device}/{@link Client} selection notifications.
- */
-public abstract class SelectionDependentPanel extends Panel {
-    private IDevice mCurrentDevice = null;
-    private Client mCurrentClient = null;
-
-    /**
-     * Returns the current {@link Device}.
-     * @return the current device or null if none are selected.
-     */
-    protected final IDevice getCurrentDevice() {
-        return mCurrentDevice;
-    }
-
-    /**
-     * Returns the current {@link Client}.
-     * @return the current client or null if none are selected.
-     */
-    protected final Client getCurrentClient() {
-        return mCurrentClient;
-    }
-
-    /**
-     * Sent when a new device is selected.
-     * @param selectedDevice the selected device.
-     */
-    public final void deviceSelected(IDevice selectedDevice) {
-        if (selectedDevice != mCurrentDevice) {
-            mCurrentDevice = selectedDevice;
-            deviceSelected();
-        }
-    }
-
-    /**
-     * Sent when a new client is selected.
-     * @param selectedClient the selected client.
-     */
-    public final void clientSelected(Client selectedClient) {
-        if (selectedClient != mCurrentClient) {
-            mCurrentClient = selectedClient;
-            clientSelected();
-        }
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}.
-     */
-    public abstract void deviceSelected();
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}.
-     */
-    public abstract void clientSelected();
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/StackTracePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/StackTracePanel.java
deleted file mode 100644
index 3358962..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/StackTracePanel.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IStackTraceInfo;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-
-/**
- * Stack Trace Panel.
- * <p/>This is not a panel in the regular sense. Instead this is just an object around the creation
- * and management of a Stack Trace display.
- * <p/>UI creation is done through
- * {@link #createPanel(Composite, String, String, String, String, String, IPreferenceStore)}.
- *
- */
-public final class StackTracePanel {
-
-    private static ISourceRevealer sSourceRevealer;
-
-    private Table mStackTraceTable;
-    private TableViewer mStackTraceViewer;
-
-    private Client mCurrentClient;
-    
-    
-    /**
-     * Content Provider to display the stack trace of a thread.
-     * Expected input is a {@link IStackTraceInfo} object.
-     */
-    private static class StackTraceContentProvider implements IStructuredContentProvider {
-        public Object[] getElements(Object inputElement) {
-            if (inputElement instanceof IStackTraceInfo) {
-                // getElement cannot return null, so we return an empty array
-                // if there's no stack trace
-                StackTraceElement trace[] = ((IStackTraceInfo)inputElement).getStackTrace();
-                if (trace != null) {
-                    return trace;
-                }
-            }
-
-            return new Object[0];
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            // pass
-        }
-    }
-    
-
-    /**
-     * A Label Provider to use with {@link StackTraceContentProvider}. It expects the elements to be
-     * of type {@link StackTraceElement}.
-     */
-    private static class StackTraceLabelProvider implements ITableLabelProvider {
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            return null;
-        }
-
-        public String getColumnText(Object element, int columnIndex) {
-            if (element instanceof StackTraceElement) {
-                StackTraceElement traceElement = (StackTraceElement)element;
-                switch (columnIndex) {
-                    case 0:
-                        return traceElement.getClassName();
-                    case 1:
-                        return traceElement.getMethodName();
-                    case 2:
-                        return traceElement.getFileName();
-                    case 3:
-                        return Integer.toString(traceElement.getLineNumber());
-                    case 4:
-                        return Boolean.toString(traceElement.isNativeMethod());
-                }
-            }
-
-            return null;
-        }
-
-        public void addListener(ILabelProviderListener listener) {
-            // pass
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public boolean isLabelProperty(Object element, String property) {
-            // pass
-            return false;
-        }
-
-        public void removeListener(ILabelProviderListener listener) {
-            // pass
-        }
-    }
-    
-    /**
-     * Classes which implement this interface provide a method that is able to reveal a method
-     * in a source editor
-     */
-    public interface ISourceRevealer {
-        /**
-         * Sent to reveal a particular line in a source editor
-         * @param applicationName the name of the application running the source.
-         * @param className the fully qualified class name
-         * @param line the line to reveal
-         */
-        public void reveal(String applicationName, String className, int line);
-    }
-    
-    
-    /**
-     * Sets the {@link ISourceRevealer} object able to reveal source code in a source editor.
-     * @param revealer
-     */
-    public static void setSourceRevealer(ISourceRevealer revealer) {
-        sSourceRevealer = revealer;
-    }
-    
-    /**
-     * Creates the controls for the StrackTrace display.
-     * <p/>This method will set the parent {@link Composite} to use a {@link GridLayout} with
-     * 2 columns.
-     * @param parent the parent composite.
-     * @param prefs_stack_col_class 
-     * @param prefs_stack_col_method 
-     * @param prefs_stack_col_file 
-     * @param prefs_stack_col_line 
-     * @param prefs_stack_col_native 
-     * @param store
-     */
-    public Table createPanel(Composite parent, String prefs_stack_col_class,
-            String prefs_stack_col_method, String prefs_stack_col_file, String prefs_stack_col_line,
-            String prefs_stack_col_native, IPreferenceStore store) {
-        
-        mStackTraceTable = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION);
-        mStackTraceTable.setHeaderVisible(true);
-        mStackTraceTable.setLinesVisible(true);
-        
-        TableHelper.createTableColumn(
-                mStackTraceTable,
-                "Class",
-                SWT.LEFT,
-                "SomeLongClassName", //$NON-NLS-1$
-                prefs_stack_col_class, store);
-
-        TableHelper.createTableColumn(
-                mStackTraceTable,
-                "Method",
-                SWT.LEFT,
-                "someLongMethod", //$NON-NLS-1$
-                prefs_stack_col_method, store);
-
-        TableHelper.createTableColumn(
-                mStackTraceTable,
-                "File",
-                SWT.LEFT,
-                "android/somepackage/someotherpackage/somefile.class", //$NON-NLS-1$
-                prefs_stack_col_file, store);
-
-        TableHelper.createTableColumn(
-                mStackTraceTable,
-                "Line",
-                SWT.RIGHT,
-                "99999", //$NON-NLS-1$
-                prefs_stack_col_line, store);
-
-        TableHelper.createTableColumn(
-                mStackTraceTable,
-                "Native",
-                SWT.LEFT,
-                "Native", //$NON-NLS-1$
-                prefs_stack_col_native, store);
-        
-        mStackTraceViewer = new TableViewer(mStackTraceTable);
-        mStackTraceViewer.setContentProvider(new StackTraceContentProvider());
-        mStackTraceViewer.setLabelProvider(new StackTraceLabelProvider());
-        
-        mStackTraceViewer.addDoubleClickListener(new IDoubleClickListener() {
-            public void doubleClick(DoubleClickEvent event) {
-                if (sSourceRevealer != null && mCurrentClient != null) {
-                    // get the selected stack trace element
-                    ISelection selection = mStackTraceViewer.getSelection();
-                    
-                    if (selection instanceof IStructuredSelection) {
-                        IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-                        Object object = structuredSelection.getFirstElement();
-                        if (object instanceof StackTraceElement) {
-                            StackTraceElement traceElement = (StackTraceElement)object;
-                            
-                            if (traceElement.isNativeMethod() == false) {
-                                sSourceRevealer.reveal(
-                                        mCurrentClient.getClientData().getClientDescription(), 
-                                        traceElement.getClassName(),
-                                        traceElement.getLineNumber());
-                            }
-                        }
-                    }
-                }
-            }
-        });
-
-        return mStackTraceTable;
-    }
-    
-    /**
-     * Sets the input for the {@link TableViewer}.
-     * @param input the {@link IStackTraceInfo} that will provide the viewer with the list of
-     * {@link StackTraceElement}
-     */
-    public void setViewerInput(IStackTraceInfo input) {
-        mStackTraceViewer.setInput(input);
-        mStackTraceViewer.refresh();
-    }
-    
-    /**
-     * Sets the current client running the stack trace.
-     * @param currentClient the {@link Client}.
-     */
-    public void setCurrentClient(Client currentClient) {
-        mCurrentClient = currentClient;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SyncProgressMonitor.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SyncProgressMonitor.java
deleted file mode 100644
index 5925984..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SyncProgressMonitor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmuilib;
-
-import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-
-/**
- * Implementation of the {@link ISyncProgressMonitor} wrapping an Eclipse {@link IProgressMonitor}.
- */
-public class SyncProgressMonitor implements ISyncProgressMonitor {
-
-    private IProgressMonitor mMonitor;
-    private String mName;
-
-    public SyncProgressMonitor(IProgressMonitor monitor, String name) {
-        mMonitor = monitor;
-        mName = name;
-    }
-
-    public void start(int totalWork) {
-        mMonitor.beginTask(mName, totalWork);
-    }
-
-    public void stop() {
-        mMonitor.done();
-    }
-
-    public void advance(int work) {
-        mMonitor.worked(work);
-    }
-
-    public boolean isCanceled() {
-        return mMonitor.isCanceled();
-    }
-
-    public void startSubTask(String name) {
-        mMonitor.subTask(name);
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java
deleted file mode 100644
index 8ef237c..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.Log;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.data.general.DefaultPieDataset;
-import org.jfree.experimental.chart.swt.ChartComposite;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Displays system information graphs obtained from a bugreport file or device.
- */
-public class SysinfoPanel extends TablePanel implements IShellOutputReceiver {
-
-    // UI components
-    private Label mLabel;
-    private Button mFetchButton;
-    private Combo mDisplayMode;
-
-    private DefaultPieDataset mDataset;
-
-    // The bugreport file to process
-    private File mDataFile;
-
-    // To get output from adb commands
-    private FileOutputStream mTempStream;
-
-    // Selects the current display: MODE_CPU, etc.
-    private int mMode = 0;
-
-    private static final int MODE_CPU = 0;
-    private static final int MODE_ALARM = 1;
-    private static final int MODE_WAKELOCK = 2;
-    private static final int MODE_MEMINFO = 3;
-    private static final int MODE_SYNC = 4;
-
-    // argument to dumpsys; section in the bugreport holding the data
-    private static final String BUGREPORT_SECTION[] = {"cpuinfo", "alarm",
-            "batteryinfo", "MEMORY INFO", "content"};
-
-    private static final String DUMP_COMMAND[] = {"dumpsys cpuinfo",
-            "dumpsys alarm", "dumpsys batteryinfo", "cat /proc/meminfo ; procrank",
-            "dumpsys content"};
-
-    private static final String CAPTIONS[] = {"CPU load", "Alarms",
-            "Wakelocks", "Memory usage", "Sync"};
-
-    /**
-     * Generates the dataset to display.
-     *
-     * @param file The bugreport file to process.
-     */
-    public void generateDataset(File file) {
-        mDataset.clear();
-        mLabel.setText("");
-        if (file == null) {
-            return;
-        }
-        try {
-            BufferedReader br = getBugreportReader(file);
-            if (mMode == MODE_CPU) {
-                readCpuDataset(br);
-            } else if (mMode == MODE_ALARM) {
-                readAlarmDataset(br);
-            } else if (mMode == MODE_WAKELOCK) {
-                readWakelockDataset(br);
-            } else if (mMode == MODE_MEMINFO) {
-                readMeminfoDataset(br);
-            } else if (mMode == MODE_SYNC) {
-                readSyncDataset(br);
-            }
-        } catch (IOException e) {
-            Log.e("DDMS", e);
-        }
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed with
-     * {@link #getCurrentDevice()}
-     */
-    @Override
-    public void deviceSelected() {
-        if (getCurrentDevice() != null) {
-            mFetchButton.setEnabled(true);
-            loadFromDevice();
-        } else {
-            mFetchButton.setEnabled(false);
-        }
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed with
-     * {@link #getCurrentClient()}.
-     */
-    @Override
-    public void clientSelected() {
-    }
-
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        mDisplayMode.setFocus();
-    }
-
-    /**
-     * Fetches a new bugreport from the device and updates the display.
-     * Fetching is asynchronous.  See also addOutput, flush, and isCancelled.
-     */
-    private void loadFromDevice() {
-        try {
-            initShellOutputBuffer();
-            if (mMode == MODE_MEMINFO) {
-                // Hack to add bugreport-style section header for meminfo
-                mTempStream.write("------ MEMORY INFO ------\n".getBytes());
-            }
-            getCurrentDevice().executeShellCommand(
-                    DUMP_COMMAND[mMode], this);
-        } catch (IOException e) {
-            Log.e("DDMS", e);
-        }
-    }
-
-    /**
-     * Initializes temporary output file for executeShellCommand().
-     *
-     * @throws IOException on file error
-     */
-    void initShellOutputBuffer() throws IOException {
-        mDataFile = File.createTempFile("ddmsfile", ".txt");
-        mDataFile.deleteOnExit();
-        mTempStream = new FileOutputStream(mDataFile);
-    }
-
-    /**
-     * Adds output to the temp file. IShellOutputReceiver method. Called by
-     * executeShellCommand().
-     */
-    public void addOutput(byte[] data, int offset, int length) {
-        try {
-            mTempStream.write(data, offset, length);
-        }
-        catch (IOException e) {
-            Log.e("DDMS", e);
-        }
-    }
-
-    /**
-     * Processes output from shell command. IShellOutputReceiver method. The
-     * output is passed to generateDataset(). Called by executeShellCommand() on
-     * completion.
-     */
-    public void flush() {
-        if (mTempStream != null) {
-            try {
-                mTempStream.close();
-                generateDataset(mDataFile);
-                mTempStream = null;
-                mDataFile = null;
-            } catch (IOException e) {
-                Log.e("DDMS", e);
-            }
-        }
-    }
-
-    /**
-     * IShellOutputReceiver method.
-     *
-     * @return false - don't cancel
-     */
-    public boolean isCancelled() {
-        return false;
-    }
-
-    /**
-     * Create our controls for the UI panel.
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        Composite top = new Composite(parent, SWT.NONE);
-        top.setLayout(new GridLayout(1, false));
-        top.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        Composite buttons = new Composite(top, SWT.NONE);
-        buttons.setLayout(new RowLayout());
-
-        mDisplayMode = new Combo(buttons, SWT.PUSH);
-        for (String mode : CAPTIONS) {
-            mDisplayMode.add(mode);
-        }
-        mDisplayMode.select(mMode);
-        mDisplayMode.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mMode = mDisplayMode.getSelectionIndex();
-                if (mDataFile != null) {
-                    generateDataset(mDataFile);
-                } else if (getCurrentDevice() != null) {
-                    loadFromDevice();
-                }
-            }
-        });
-
-        final Button loadButton = new Button(buttons, SWT.PUSH);
-        loadButton.setText("Load from File");
-        loadButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                FileDialog fileDialog = new FileDialog(loadButton.getShell(),
-                        SWT.OPEN);
-                fileDialog.setText("Load bugreport");
-                String filename = fileDialog.open();
-                if (filename != null) {
-                    mDataFile = new File(filename);
-                    generateDataset(mDataFile);
-                }
-            }
-        });
-
-        mFetchButton = new Button(buttons, SWT.PUSH);
-        mFetchButton.setText("Update from Device");
-        mFetchButton.setEnabled(false);
-        mFetchButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                loadFromDevice();
-            }
-        });
-
-        mLabel = new Label(top, SWT.NONE);
-        mLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mDataset = new DefaultPieDataset();
-        JFreeChart chart = ChartFactory.createPieChart("", mDataset, false
-                /* legend */, true/* tooltips */, false /* urls */);
-
-        ChartComposite chartComposite = new ChartComposite(top,
-                SWT.BORDER, chart,
-                ChartComposite.DEFAULT_HEIGHT,
-                ChartComposite.DEFAULT_HEIGHT,
-                ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
-                ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
-                3000,
-                // max draw width. We don't want it to zoom, so we put a big number
-                3000,
-                // max draw height. We don't want it to zoom, so we put a big number
-                true,  // off-screen buffer
-                true,  // properties
-                true,  // save
-                true,  // print
-                false,  // zoom
-                true);
-        chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        return top;
-    }
-
-    public void clientChanged(final Client client, int changeMask) {
-        // Don't care
-    }
-
-    /**
-     * Helper to open a bugreport and skip to the specified section.
-     *
-     * @param file File to open
-     * @return Reader to bugreport file
-     * @throws java.io.IOException on file error
-     */
-    private BufferedReader getBugreportReader(File file) throws
-            IOException {
-        BufferedReader br = new BufferedReader(new FileReader(file));
-        // Skip over the unwanted bugreport sections
-        while (true) {
-            String line = br.readLine();
-            if (line == null) {
-                Log.d("DDMS", "Service not found " + line);
-                break;
-            }
-            if ((line.startsWith("DUMP OF SERVICE ") || line.startsWith("-----")) &&
-                    line.indexOf(BUGREPORT_SECTION[mMode]) > 0) {
-                break;
-            }
-        }
-        return br;
-    }
-
-    /**
-     * Parse the time string generated by BatteryStats.
-     * A typical new-format string is "11d 13h 45m 39s 999ms".
-     * A typical old-format string is "12.3 sec".
-     * @return time in ms
-     */
-    private static long parseTimeMs(String s) {
-        long total = 0;
-        // Matches a single component e.g. "12.3 sec" or "45ms"
-        Pattern p = Pattern.compile("([\\d\\.]+)\\s*([a-z]+)");
-        Matcher m = p.matcher(s);
-        while (m.find()) {
-            String label = m.group(2);
-            if ("sec".equals(label)) {
-                // Backwards compatibility with old time format
-                total += (long) (Double.parseDouble(m.group(1)) * 1000);
-                continue;
-            }
-            long value = Integer.parseInt(m.group(1));
-            if ("d".equals(label)) {
-                total += value * 24 * 60 * 60 * 1000;
-            } else if ("h".equals(label)) {
-                total += value * 60 * 60 * 1000;
-            } else if ("m".equals(label)) {
-                total += value * 60 * 1000;
-            } else if ("s".equals(label)) {
-                total += value * 1000;
-            } else if ("ms".equals(label)) {
-                total += value;
-            }
-        }
-        return total;
-    }
-    /**
-     * Processes wakelock information from bugreport. Updates mDataset with the
-     * new data.
-     *
-     * @param br Reader providing the content
-     * @throws IOException if error reading file
-     */
-    void readWakelockDataset(BufferedReader br) throws IOException {
-        Pattern lockPattern = Pattern.compile("Wake lock (\\S+): (.+) partial");
-        Pattern totalPattern = Pattern.compile("Total: (.+) uptime");
-        double total = 0;
-        boolean inCurrent = false;
-
-        while (true) {
-            String line = br.readLine();
-            if (line == null || line.startsWith("DUMP OF SERVICE")) {
-                // Done, or moved on to the next service
-                break;
-            }
-            if (line.startsWith("Current Battery Usage Statistics")) {
-                inCurrent = true;
-            } else if (inCurrent) {
-                Matcher m = lockPattern.matcher(line);
-                if (m.find()) {
-                    double value = parseTimeMs(m.group(2)) / 1000.;
-                    mDataset.setValue(m.group(1), value);
-                    total -= value;
-                } else {
-                    m = totalPattern.matcher(line);
-                    if (m.find()) {
-                        total += parseTimeMs(m.group(1)) / 1000.;
-                    }
-                }
-            }
-        }
-        if (total > 0) {
-            mDataset.setValue("Unlocked", total);
-        }
-    }
-
-    /**
-     * Processes alarm information from bugreport. Updates mDataset with the new
-     * data.
-     *
-     * @param br Reader providing the content
-     * @throws IOException if error reading file
-     */
-    void readAlarmDataset(BufferedReader br) throws IOException {
-        Pattern pattern = Pattern
-                .compile("(\\d+) alarms: Intent .*\\.([^. ]+) flags");
-
-        while (true) {
-            String line = br.readLine();
-            if (line == null || line.startsWith("DUMP OF SERVICE")) {
-                // Done, or moved on to the next service
-                break;
-            }
-            Matcher m = pattern.matcher(line);
-            if (m.find()) {
-                long count = Long.parseLong(m.group(1));
-                String name = m.group(2);
-                mDataset.setValue(name, count);
-            }
-        }
-    }
-
-    /**
-     * Processes cpu load information from bugreport. Updates mDataset with the
-     * new data.
-     *
-     * @param br Reader providing the content
-     * @throws IOException if error reading file
-     */
-    void readCpuDataset(BufferedReader br) throws IOException {
-        Pattern pattern = Pattern
-                .compile("(\\S+): (\\S+)% = (.+)% user . (.+)% kernel");
-
-        while (true) {
-            String line = br.readLine();
-            if (line == null || line.startsWith("DUMP OF SERVICE")) {
-                // Done, or moved on to the next service
-                break;
-            }
-            if (line.startsWith("Load:")) {
-                mLabel.setText(line);
-                continue;
-            }
-            Matcher m = pattern.matcher(line);
-            if (m.find()) {
-                String name = m.group(1);
-                long both = Long.parseLong(m.group(2));
-                long user = Long.parseLong(m.group(3));
-                long kernel = Long.parseLong(m.group(4));
-                if ("TOTAL".equals(name)) {
-                    if (both < 100) {
-                        mDataset.setValue("Idle", (100 - both));
-                    }
-                } else {
-                    // Try to make graphs more useful even with rounding;
-                    // log often has 0% user + 0% kernel = 1% total
-                    // We arbitrarily give extra to kernel
-                    if (user > 0) {
-                        mDataset.setValue(name + " (user)", user);
-                    }
-                    if (kernel > 0) {
-                        mDataset.setValue(name + " (kernel)" , both - user);
-                    }
-                    if (user == 0 && kernel == 0 && both > 0) {
-                        mDataset.setValue(name, both);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Processes meminfo information from bugreport. Updates mDataset with the
-     * new data.
-     *
-     * @param br Reader providing the content
-     * @throws IOException if error reading file
-     */
-    void readMeminfoDataset(BufferedReader br) throws IOException {
-        Pattern valuePattern = Pattern.compile("(\\d+) kB");
-        long total = 0;
-        long other = 0;
-        mLabel.setText("PSS in kB");        
-
-        // Scan meminfo
-        while (true) {
-            String line = br.readLine();
-            if (line == null) {
-                // End of file
-                break;
-            }
-            Matcher m = valuePattern.matcher(line);
-            if (m.find()) {
-                long kb = Long.parseLong(m.group(1));
-                if (line.startsWith("MemTotal")) {
-                    total = kb;
-                } else if (line.startsWith("MemFree")) {
-                    mDataset.setValue("Free", kb);
-                    total -= kb;
-                } else if (line.startsWith("Slab")) {
-                    mDataset.setValue("Slab", kb);
-                    total -= kb;
-                } else if (line.startsWith("PageTables")) {
-                    mDataset.setValue("PageTables", kb);
-                    total -= kb;
-                } else if (line.startsWith("Buffers") && kb > 0) {
-                    mDataset.setValue("Buffers", kb);
-                    total -= kb;
-                } else if (line.startsWith("Inactive")) {
-                    mDataset.setValue("Inactive", kb);
-                    total -= kb;
-                } else if (line.startsWith("MemFree")) {
-                    mDataset.setValue("Free", kb);
-                    total -= kb;
-                }
-            } else {
-                break;
-            }
-        }
-        // Scan procrank
-        while (true) {
-            String line = br.readLine();
-            if (line == null) {
-                break;
-            }
-            if (line.indexOf("PROCRANK") >= 0 || line.indexOf("PID") >= 0) {
-                // procrank header
-                continue;
-            }
-            if  (line.indexOf("----") >= 0) {
-                //end of procrank section
-                break;
-            }
-            // Extract pss field from procrank output
-            long pss = Long.parseLong(line.substring(23, 31).trim());
-            String cmdline = line.substring(43).trim().replace("/system/bin/", "");
-            // Arbitrary minimum size to display
-            if (pss > 2000) {
-                mDataset.setValue(cmdline, pss);
-            } else {
-                other += pss;
-            }
-            total -= pss;
-        }
-        mDataset.setValue("Other", other);
-        mDataset.setValue("Unknown", total);
-    }
-
-    /**
-     * Processes sync information from bugreport. Updates mDataset with the new
-     * data.
-     *
-     * @param br Reader providing the content
-     * @throws IOException if error reading file
-     */
-    void readSyncDataset(BufferedReader br) throws IOException {
-        while (true) {
-            String line = br.readLine();
-            if (line == null || line.startsWith("DUMP OF SERVICE")) {
-                // Done, or moved on to the next service
-                break;
-            }
-            if (line.startsWith(" |") && line.length() > 70) {
-                String authority = line.substring(3, 18).trim();
-                String duration = line.substring(61, 70).trim();
-                // Duration is MM:SS or HH:MM:SS (DateUtils.formatElapsedTime)
-                String durParts[] = duration.split(":");
-                if (durParts.length == 2) {
-                    long dur = Long.parseLong(durParts[0]) * 60 + Long
-                            .parseLong(durParts[1]);
-                    mDataset.setValue(authority, dur);
-                } else if (duration.length() == 3) {
-                    long dur = Long.parseLong(durParts[0]) * 3600
-                            + Long.parseLong(durParts[1]) * 60 + Long
-                            .parseLong(durParts[2]);
-                    mDataset.setValue(authority, dur);
-                }
-            }
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TableHelper.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TableHelper.java
deleted file mode 100644
index 9d557e0..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TableHelper.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-
-/**
- * Utility class to help using Table objects.
- *
- */
-public final class TableHelper {
-    /**
-     * Create a TableColumn with the specified parameters. If a
-     * <code>PreferenceStore</code> object and a preference entry name String
-     * object are provided then the column will listen to change in its width
-     * and update the preference store accordingly.
-     *
-     * @param parent The Table parent object
-     * @param header The header string
-     * @param style The column style
-     * @param sample_text A sample text to figure out column width if preference
-     *            value is missing
-     * @param pref_name The preference entry name for column width
-     * @param prefs The preference store
-     * @return The TableColumn object that was created
-     */
-    public static TableColumn createTableColumn(Table parent, String header,
-            int style, String sample_text, final String pref_name,
-            final IPreferenceStore prefs) {
-
-        // create the column
-        TableColumn col = new TableColumn(parent, style);
-
-        // if there is no pref store or the entry is missing, we use the sample
-        // text and pack the column.
-        // Otherwise we just read the width from the prefs and apply it.
-        if (prefs == null || prefs.contains(pref_name) == false) {
-            col.setText(sample_text);
-            col.pack();
-
-            // init the prefs store with the current value
-            if (prefs != null) {
-                prefs.setValue(pref_name, col.getWidth());
-            }
-        } else {
-            col.setWidth(prefs.getInt(pref_name));
-        }
-
-        // set the header
-        col.setText(header);
-
-        // if there is a pref store and a pref entry name, then we setup a
-        // listener to catch column resize to put store the new width value.
-        if (prefs != null && pref_name != null) {
-            col.addControlListener(new ControlListener() {
-                public void controlMoved(ControlEvent e) {
-                }
-
-                public void controlResized(ControlEvent e) {
-                    // get the new width
-                    int w = ((TableColumn)e.widget).getWidth();
-
-                    // store in pref store
-                    prefs.setValue(pref_name, w);
-                }
-            });
-        }
-
-        return col;
-    }
-
-    /**
-     * Create a TreeColumn with the specified parameters. If a
-     * <code>PreferenceStore</code> object and a preference entry name String
-     * object are provided then the column will listen to change in its width
-     * and update the preference store accordingly.
-     *
-     * @param parent The Table parent object
-     * @param header The header string
-     * @param style The column style
-     * @param sample_text A sample text to figure out column width if preference
-     *            value is missing
-     * @param pref_name The preference entry name for column width
-     * @param prefs The preference store
-     */
-    public static void createTreeColumn(Tree parent, String header, int style,
-            String sample_text, final String pref_name,
-            final IPreferenceStore prefs) {
-
-        // create the column
-        TreeColumn col = new TreeColumn(parent, style);
-
-        // if there is no pref store or the entry is missing, we use the sample
-        // text and pack the column.
-        // Otherwise we just read the width from the prefs and apply it.
-        if (prefs == null || prefs.contains(pref_name) == false) {
-            col.setText(sample_text);
-            col.pack();
-
-            // init the prefs store with the current value
-            if (prefs != null) {
-                prefs.setValue(pref_name, col.getWidth());
-            }
-        } else {
-            col.setWidth(prefs.getInt(pref_name));
-        }
-
-        // set the header
-        col.setText(header);
-
-        // if there is a pref store and a pref entry name, then we setup a
-        // listener to catch column resize to put store the new width value.
-        if (prefs != null && pref_name != null) {
-            col.addControlListener(new ControlListener() {
-                public void controlMoved(ControlEvent e) {
-                }
-
-                public void controlResized(ControlEvent e) {
-                    // get the new width
-                    int w = ((TreeColumn)e.widget).getWidth();
-
-                    // store in pref store
-                    prefs.setValue(pref_name, w);
-                }
-            });
-        }
-    }
-
-    /**
-     * Create a TreeColumn with the specified parameters. If a
-     * <code>PreferenceStore</code> object and a preference entry name String
-     * object are provided then the column will listen to change in its width
-     * and update the preference store accordingly.
-     *
-     * @param parent The Table parent object
-     * @param header The header string
-     * @param style The column style
-     * @param width the width of the column if the preference value is missing
-     * @param pref_name The preference entry name for column width
-     * @param prefs The preference store
-     */
-    public static void createTreeColumn(Tree parent, String header, int style,
-            int width, final String pref_name,
-            final IPreferenceStore prefs) {
-
-        // create the column
-        TreeColumn col = new TreeColumn(parent, style);
-
-        // if there is no pref store or the entry is missing, we use the sample
-        // text and pack the column.
-        // Otherwise we just read the width from the prefs and apply it.
-        if (prefs == null || prefs.contains(pref_name) == false) {
-            col.setWidth(width);
-
-            // init the prefs store with the current value
-            if (prefs != null) {
-                prefs.setValue(pref_name, width);
-            }
-        } else {
-            col.setWidth(prefs.getInt(pref_name));
-        }
-
-        // set the header
-        col.setText(header);
-
-        // if there is a pref store and a pref entry name, then we setup a
-        // listener to catch column resize to put store the new width value.
-        if (prefs != null && pref_name != null) {
-            col.addControlListener(new ControlListener() {
-                public void controlMoved(ControlEvent e) {
-                }
-
-                public void controlResized(ControlEvent e) {
-                    // get the new width
-                    int w = ((TreeColumn)e.widget).getWidth();
-
-                    // store in pref store
-                    prefs.setValue(pref_name, w);
-                }
-            });
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TablePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TablePanel.java
deleted file mode 100644
index b037193..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TablePanel.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator;
-
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-import java.util.Arrays;
-
-/**
- * Base class for panel containing Table that need to support copy-paste-selectAll
- */
-public abstract class TablePanel extends ClientDisplayPanel {
-    private ITableFocusListener mGlobalListener;
-
-    /**
-     * Sets a TableFocusListener which will be notified when one of the tables
-     * gets or loses focus.
-     *
-     * @param listener
-     */
-    public final void setTableFocusListener(ITableFocusListener listener) {
-        // record the global listener, to make sure table created after
-        // this call will still be setup.
-        mGlobalListener = listener;
-
-        setTableFocusListener();
-    }
-
-    /**
-     * Sets up the Table of object of the panel to work with the global listener.<br>
-     * Default implementation does nothing.
-     */
-    protected void setTableFocusListener() {
-
-    }
-
-    /**
-     * Sets up a Table object to notify the global Table Focus listener when it
-     * gets or loses the focus.
-     *
-     * @param table the Table object.
-     * @param colStart
-     * @param colEnd
-     */
-    protected final void addTableToFocusListener(final Table table,
-            final int colStart, final int colEnd) {
-        // create the activator for this table
-        final IFocusedTableActivator activator = new IFocusedTableActivator() {
-            public void copy(Clipboard clipboard) {
-                int[] selection = table.getSelectionIndices();
-
-                // we need to sort the items to be sure.
-                Arrays.sort(selection);
-
-                // all lines must be concatenated.
-                StringBuilder sb = new StringBuilder();
-
-                // loop on the selection and output the file.
-                for (int i : selection) {
-                    TableItem item = table.getItem(i);
-                    for (int c = colStart ; c <= colEnd ; c++) {
-                        sb.append(item.getText(c));
-                        sb.append('\t');
-                    }
-                    sb.append('\n');
-                }
-
-                // now add that to the clipboard if the string has content
-                String data = sb.toString();
-                if (data != null || data.length() > 0) {
-                    clipboard.setContents(
-                            new Object[] { data },
-                            new Transfer[] { TextTransfer.getInstance() });
-                }
-            }
-
-            public void selectAll() {
-                table.selectAll();
-            }
-        };
-
-        // add the focus listener on the table to notify the global listener
-        table.addFocusListener(new FocusListener() {
-            public void focusGained(FocusEvent e) {
-                mGlobalListener.focusGained(activator);
-            }
-
-            public void focusLost(FocusEvent e) {
-                mGlobalListener.focusLost(activator);
-            }
-        });
-    }
-
-    /**
-     * Sets up a Table object to notify the global Table Focus listener when it
-     * gets or loses the focus.<br>
-     * When the copy method is invoked, all columns are put in the clipboard, separated
-     * by tabs
-     *
-     * @param table the Table object.
-     */
-    protected final void addTableToFocusListener(final Table table) {
-        addTableToFocusListener(table, 0, table.getColumnCount()-1);
-    }
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ThreadPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ThreadPanel.java
deleted file mode 100644
index d94d4f3..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ThreadPanel.java
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * 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.android.ddmuilib;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ThreadInfo;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Sash;
-import org.eclipse.swt.widgets.Table;
-
-import java.util.Date;
-
-/**
- * Base class for our information panels.
- */
-public class ThreadPanel extends TablePanel {
-    
-    private final static String PREFS_THREAD_COL_ID = "threadPanel.Col0"; //$NON-NLS-1$
-    private final static String PREFS_THREAD_COL_TID = "threadPanel.Col1"; //$NON-NLS-1$
-    private final static String PREFS_THREAD_COL_STATUS = "threadPanel.Col2"; //$NON-NLS-1$
-    private final static String PREFS_THREAD_COL_UTIME = "threadPanel.Col3"; //$NON-NLS-1$
-    private final static String PREFS_THREAD_COL_STIME = "threadPanel.Col4"; //$NON-NLS-1$
-    private final static String PREFS_THREAD_COL_NAME = "threadPanel.Col5"; //$NON-NLS-1$
-    
-    private final static String PREFS_THREAD_SASH = "threadPanel.sash"; //$NON-NLS-1$
-
-    private static final String PREFS_STACK_COL_CLASS = "threadPanel.stack.col0"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_METHOD = "threadPanel.stack.col1"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_FILE = "threadPanel.stack.col2"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_LINE = "threadPanel.stack.col3"; //$NON-NLS-1$
-    private static final String PREFS_STACK_COL_NATIVE = "threadPanel.stack.col4"; //$NON-NLS-1$
-    
-    private Display mDisplay;
-    private Composite mBase;
-    private Label mNotEnabled;
-    private Label mNotSelected;
-    
-    private Composite mThreadBase;
-    private Table mThreadTable;
-    private TableViewer mThreadViewer;
-
-    private Composite mStackTraceBase;
-    private Button mRefreshStackTraceButton;
-    private Label mStackTraceTimeLabel;
-    private StackTracePanel mStackTracePanel;
-    private Table mStackTraceTable;
-
-    /** Indicates if a timer-based Runnable is current requesting thread updates regularly. */
-    private boolean mMustStopRecurringThreadUpdate = false;
-    /** Flag to tell the recurring thread update to stop running */
-    private boolean mRecurringThreadUpdateRunning = false;
-
-    private Object mLock = new Object();
-
-    private static final String[] THREAD_STATUS = {
-        "zombie", "running", "timed-wait", "monitor",
-        "wait", "init", "start", "native", "vmwait"
-    };
-    
-    /**
-     * Content Provider to display the threads of a client.
-     * Expected input is a {@link Client} object.
-     */
-    private static class ThreadContentProvider implements IStructuredContentProvider {
-        public Object[] getElements(Object inputElement) {
-            if (inputElement instanceof Client) {
-                return ((Client)inputElement).getClientData().getThreads();
-            }
-
-            return new Object[0];
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            // pass
-        }
-    }
-    
-
-    /**
-     * A Label Provider to use with {@link ThreadContentProvider}. It expects the elements to be
-     * of type {@link ThreadInfo}.
-     */
-    private static class ThreadLabelProvider implements ITableLabelProvider {
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            return null;
-        }
-
-        public String getColumnText(Object element, int columnIndex) {
-            if (element instanceof ThreadInfo) {
-                ThreadInfo thread = (ThreadInfo)element;
-                switch (columnIndex) {
-                    case 0:
-                        return (thread.isDaemon() ? "*" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                            String.valueOf(thread.getThreadId());
-                    case 1:
-                        return String.valueOf(thread.getTid());
-                    case 2:
-                        if (thread.getStatus() >= 0 && thread.getStatus() < THREAD_STATUS.length)
-                            return THREAD_STATUS[thread.getStatus()];
-                        return "unknown";
-                    case 3:
-                        return String.valueOf(thread.getUtime());
-                    case 4:
-                        return String.valueOf(thread.getStime());
-                    case 5:
-                        return thread.getThreadName();
-                }
-            }
-
-            return null;
-        }
-
-        public void addListener(ILabelProviderListener listener) {
-            // pass
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public boolean isLabelProperty(Object element, String property) {
-            // pass
-            return false;
-        }
-
-        public void removeListener(ILabelProviderListener listener) {
-            // pass
-        }
-    }
-
-    /**
-     * Create our control(s).
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        mDisplay = parent.getDisplay();
-
-        final IPreferenceStore store = DdmUiPreferences.getStore();
-
-        mBase = new Composite(parent, SWT.NONE);
-        mBase.setLayout(new StackLayout());
-
-        // UI for thread not enabled
-        mNotEnabled = new Label(mBase, SWT.CENTER | SWT.WRAP);
-        mNotEnabled.setText("Thread updates not enabled for selected client\n"
-            + "(use toolbar button to enable)");
-
-        // UI for not client selected
-        mNotSelected = new Label(mBase, SWT.CENTER | SWT.WRAP);
-        mNotSelected.setText("no client is selected");
-
-        // base composite for selected client with enabled thread update.
-        mThreadBase = new Composite(mBase, SWT.NONE);
-        mThreadBase.setLayout(new FormLayout());
-        
-        // table above the sash
-        mThreadTable = new Table(mThreadBase, SWT.MULTI | SWT.FULL_SELECTION);
-        mThreadTable.setHeaderVisible(true);
-        mThreadTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(
-                mThreadTable,
-                "ID",
-                SWT.RIGHT,
-                "888", //$NON-NLS-1$
-                PREFS_THREAD_COL_ID, store);
-
-        TableHelper.createTableColumn(
-                mThreadTable,
-                "Tid",
-                SWT.RIGHT,
-                "88888", //$NON-NLS-1$
-                PREFS_THREAD_COL_TID, store);
-
-        TableHelper.createTableColumn(
-                mThreadTable,
-                "Status",
-                SWT.LEFT,
-                "timed-wait", //$NON-NLS-1$
-                PREFS_THREAD_COL_STATUS, store);
-
-        TableHelper.createTableColumn(
-                mThreadTable,
-                "utime",
-                SWT.RIGHT,
-                "utime", //$NON-NLS-1$
-                PREFS_THREAD_COL_UTIME, store);
-
-        TableHelper.createTableColumn(
-                mThreadTable,
-                "stime",
-                SWT.RIGHT,
-                "utime", //$NON-NLS-1$
-                PREFS_THREAD_COL_STIME, store);
-
-        TableHelper.createTableColumn(
-                mThreadTable,
-                "Name",
-                SWT.LEFT,
-                "android.class.ReallyLongClassName.MethodName", //$NON-NLS-1$
-                PREFS_THREAD_COL_NAME, store);
-        
-        mThreadViewer = new TableViewer(mThreadTable);
-        mThreadViewer.setContentProvider(new ThreadContentProvider());
-        mThreadViewer.setLabelProvider(new ThreadLabelProvider());
-
-        mThreadViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                ThreadInfo selectedThread = getThreadSelection(event.getSelection());
-                updateThreadStackTrace(selectedThread);
-            }
-        });
-        mThreadViewer.addDoubleClickListener(new IDoubleClickListener() {
-            public void doubleClick(DoubleClickEvent event) {
-                ThreadInfo selectedThread = getThreadSelection(event.getSelection());
-                if (selectedThread != null) {
-                    Client client = (Client)mThreadViewer.getInput();
-                    
-                    if (client != null) {
-                        client.requestThreadStackTrace(selectedThread.getThreadId());
-                    }
-                }
-            }
-        });
-        
-        // the separating sash
-        final Sash sash = new Sash(mThreadBase, SWT.HORIZONTAL);
-        Color darkGray = parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
-        sash.setBackground(darkGray);
-        
-        // the UI below the sash
-        mStackTraceBase = new Composite(mThreadBase, SWT.NONE);
-        mStackTraceBase.setLayout(new GridLayout(2, false));
-
-        mRefreshStackTraceButton = new Button(mStackTraceBase, SWT.PUSH);
-        mRefreshStackTraceButton.setText("Refresh");
-        mRefreshStackTraceButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                ThreadInfo selectedThread = getThreadSelection(null);
-                if (selectedThread != null) {
-                    Client currentClient = getCurrentClient();
-                    if (currentClient != null) {
-                        currentClient.requestThreadStackTrace(selectedThread.getThreadId());
-                    }
-                }
-            }
-        });
-        
-        mStackTraceTimeLabel = new Label(mStackTraceBase, SWT.NONE);
-        mStackTraceTimeLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mStackTracePanel = new StackTracePanel();
-        mStackTraceTable = mStackTracePanel.createPanel(mStackTraceBase,
-                PREFS_STACK_COL_CLASS,
-                PREFS_STACK_COL_METHOD,
-                PREFS_STACK_COL_FILE,
-                PREFS_STACK_COL_LINE,
-                PREFS_STACK_COL_NATIVE,
-                store);
-        
-        GridData gd;
-        mStackTraceTable.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
-        gd.horizontalSpan = 2;
-        
-        // now setup the sash.
-        // form layout data
-        FormData data = new FormData();
-        data.top = new FormAttachment(0, 0);
-        data.bottom = new FormAttachment(sash, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        mThreadTable.setLayoutData(data);
-
-        final FormData sashData = new FormData();
-        if (store != null && store.contains(PREFS_THREAD_SASH)) {
-            sashData.top = new FormAttachment(0, store.getInt(PREFS_THREAD_SASH));
-        } else {
-            sashData.top = new FormAttachment(50,0); // 50% across
-        }
-        sashData.left = new FormAttachment(0, 0);
-        sashData.right = new FormAttachment(100, 0);
-        sash.setLayoutData(sashData);
-
-        data = new FormData();
-        data.top = new FormAttachment(sash, 0);
-        data.bottom = new FormAttachment(100, 0);
-        data.left = new FormAttachment(0, 0);
-        data.right = new FormAttachment(100, 0);
-        mStackTraceBase.setLayoutData(data);
-
-        // allow resizes, but cap at minPanelWidth
-        sash.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                Rectangle sashRect = sash.getBounds();
-                Rectangle panelRect = mThreadBase.getClientArea();
-                int bottom = panelRect.height - sashRect.height - 100;
-                e.y = Math.max(Math.min(e.y, bottom), 100);
-                if (e.y != sashRect.y) {
-                    sashData.top = new FormAttachment(0, e.y);
-                    store.setValue(PREFS_THREAD_SASH, e.y);
-                    mThreadBase.layout();
-                }
-            }
-        });
-
-        ((StackLayout)mBase.getLayout()).topControl = mNotSelected;
-
-        return mBase;
-    }
-    
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        mThreadTable.setFocus();
-    }
-
-    /**
-     * Sent when an existing client information changed.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param client the updated client.
-     * @param changeMask the bit mask describing the changed properties. It can contain
-     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-     * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-     * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-     *
-     * @see IClientChangeListener#clientChanged(Client, int)
-     */
-    public void clientChanged(final Client client, int changeMask) {
-        if (client == getCurrentClient()) {
-            if ((changeMask & Client.CHANGE_THREAD_MODE) != 0 ||
-                    (changeMask & Client.CHANGE_THREAD_DATA) != 0) {
-                try {
-                    mThreadTable.getDisplay().asyncExec(new Runnable() {
-                        public void run() {
-                            clientSelected();
-                        }
-                    });
-                } catch (SWTException e) {
-                    // widget is disposed, we do nothing
-                }
-            } else if ((changeMask & Client.CHANGE_THREAD_STACKTRACE) != 0) {
-                try {
-                    mThreadTable.getDisplay().asyncExec(new Runnable() {
-                        public void run() {
-                            updateThreadStackCall();
-                        }
-                    });
-                } catch (SWTException e) {
-                    // widget is disposed, we do nothing
-                }
-            }
-        }
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}.
-     */
-    @Override
-    public void deviceSelected() {
-        // pass
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}.
-     */
-    @Override
-    public void clientSelected() {
-        if (mThreadTable.isDisposed()) {
-            return;
-        }
-
-        Client client = getCurrentClient();
-        
-        mStackTracePanel.setCurrentClient(client);
-
-        if (client != null) {
-            if (!client.isThreadUpdateEnabled()) {
-                ((StackLayout)mBase.getLayout()).topControl = mNotEnabled;
-                mThreadViewer.setInput(null);
-
-                // if we are currently updating the thread, stop doing it.
-                mMustStopRecurringThreadUpdate = true;
-            } else {
-                ((StackLayout)mBase.getLayout()).topControl = mThreadBase;
-                mThreadViewer.setInput(client);
-
-                synchronized (mLock) {
-                    // if we're not updating we start the process
-                    if (mRecurringThreadUpdateRunning == false) {
-                        startRecurringThreadUpdate();
-                    } else if (mMustStopRecurringThreadUpdate) {
-                        // else if there's a runnable that's still going to get called, lets
-                        // simply cancel the stop, and keep going
-                        mMustStopRecurringThreadUpdate = false;
-                    }
-                }
-            }
-        } else {
-            ((StackLayout)mBase.getLayout()).topControl = mNotSelected;
-            mThreadViewer.setInput(null);
-        }
-
-        mBase.layout();
-    }
-    
-    /**
-     * Updates the stack call of the currently selected thread.
-     * <p/>
-     * This <b>must</b> be called from the UI thread.
-     */
-    private void updateThreadStackCall() {
-        Client client = getCurrentClient();
-        if (client != null) {
-            // get the current selection in the ThreadTable
-            ThreadInfo selectedThread = getThreadSelection(null);
-            
-            if (selectedThread != null) {
-                updateThreadStackTrace(selectedThread);
-            } else {
-                updateThreadStackTrace(null);
-            }
-        }
-    }
-    
-    /**
-     * updates the stackcall of the specified thread. If <code>null</code> the UI is emptied
-     * of current data.
-     * @param thread
-     */
-    private void updateThreadStackTrace(ThreadInfo thread) {
-        mStackTracePanel.setViewerInput(thread);
-        
-        if (thread != null) {
-            mRefreshStackTraceButton.setEnabled(true);
-            long stackcallTime = thread.getStackCallTime();
-            if (stackcallTime != 0) {
-                String label = new Date(stackcallTime).toString();
-                mStackTraceTimeLabel.setText(label);
-            } else {
-                mStackTraceTimeLabel.setText(""); //$NON-NLS-1$
-            }
-        } else {
-            mRefreshStackTraceButton.setEnabled(true);
-            mStackTraceTimeLabel.setText(""); //$NON-NLS-1$
-        }
-    }
-
-    @Override
-    protected void setTableFocusListener() {
-        addTableToFocusListener(mThreadTable);
-        addTableToFocusListener(mStackTraceTable);
-    }
-
-    /**
-     * Initiate recurring events. We use a shorter "initialWait" so we do the
-     * first execution sooner. We don't do it immediately because we want to
-     * give the clients a chance to get set up.
-     */
-    private void startRecurringThreadUpdate() {
-        mRecurringThreadUpdateRunning = true;
-        int initialWait = 1000;
-
-        mDisplay.timerExec(initialWait, new Runnable() {
-            public void run() {
-                synchronized (mLock) {
-                    // lets check we still want updates.
-                    if (mMustStopRecurringThreadUpdate == false) {
-                        Client client = getCurrentClient();
-                        if (client != null) {
-                            client.requestThreadUpdate();
-
-                            mDisplay.timerExec(
-                                    DdmUiPreferences.getThreadRefreshInterval() * 1000, this);
-                        } else {
-                            // we don't have a Client, which means the runnable is not
-                            // going to be called through the timer. We reset the running flag.
-                            mRecurringThreadUpdateRunning = false;
-                        }
-                    } else {
-                        // else actually stops (don't call the timerExec) and reset the flags.
-                        mRecurringThreadUpdateRunning = false;
-                        mMustStopRecurringThreadUpdate = false;
-                    }
-                }
-            }
-        });
-    }
-    
-    /**
-     * Returns the current thread selection or <code>null</code> if none is found.
-     * If a {@link ISelection} object is specified, the first {@link ThreadInfo} from this selection
-     * is returned, otherwise, the <code>ISelection</code> returned by
-     * {@link TableViewer#getSelection()} is used.
-     * @param selection the {@link ISelection} to use, or <code>null</code>
-     */
-    private ThreadInfo getThreadSelection(ISelection selection) {
-        if (selection == null) {
-            selection = mThreadViewer.getSelection();
-        }
-        
-        if (selection instanceof IStructuredSelection) {
-            IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-            Object object = structuredSelection.getFirstElement();
-            if (object instanceof ThreadInfo) {
-                return (ThreadInfo)object;
-            }
-        }
-        
-        return null;
-    }
-
-}
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ICommonAction.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ICommonAction.java
deleted file mode 100644
index 856b874..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ICommonAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.android.ddmuilib.actions;
-
-/**
- * Common interface for basic action handling. This allows the common ui
- * components to access ToolItem or Action the same way.
- */
-public interface ICommonAction {
-    /**
-     * Sets the enabled state of this action.
-     * @param enabled <code>true</code> to enable, and
-     *   <code>false</code> to disable
-     */
-    public void setEnabled(boolean enabled);
-
-    /**
-     * Sets the checked status of this action.
-     * @param checked the new checked status
-     */
-    public void setChecked(boolean checked);
-    
-    /**
-     * Sets the {@link Runnable} that will be executed when the action is triggered.
-     */
-    public void setRunnable(Runnable runnable);
-}
-
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ToolItemAction.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ToolItemAction.java
deleted file mode 100644
index bc1598f..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ToolItemAction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.android.ddmuilib.actions;
-
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-
-/**
- * Wrapper around {@link ToolItem} to implement {@link ICommonAction}
- */
-public class ToolItemAction implements ICommonAction {
-    public ToolItem item;
-
-    public ToolItemAction(ToolBar parent, int style) {
-        item = new ToolItem(parent, style);
-    }
-
-    /**
-     * Sets the enabled state of this action.
-     * @param enabled <code>true</code> to enable, and
-     *   <code>false</code> to disable
-     * @see ICommonAction#setChecked(boolean)
-     */
-    public void setChecked(boolean checked) {
-        item.setSelection(checked);
-    }
-
-    /**
-     * Sets the enabled state of this action.
-     * @param enabled <code>true</code> to enable, and
-     *   <code>false</code> to disable
-     * @see ICommonAction#setEnabled(boolean)
-     */
-    public void setEnabled(boolean enabled) {
-        item.setEnabled(enabled);
-    }
-
-    /**
-     * Sets the {@link Runnable} that will be executed when the action is triggered (through
-     * {@link SelectionListener#widgetSelected(SelectionEvent)} on the wrapped {@link ToolItem}).
-     * @see ICommonAction#setRunnable(Runnable)
-     */
-    public void setRunnable(final Runnable runnable) {
-        item.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                runnable.run();
-            }
-        });
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/UiThread.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/UiThread.java
deleted file mode 100644
index 8e9e11b..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/UiThread.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.android.ddmuilib.annotation;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Simple utility annotation used only to mark methods that are executed on the UI thread.
- * This annotation's sole purpose is to help reading the source code. It has no additional effect.
- */
-@Target({ ElementType.METHOD })
-@Retention(RetentionPolicy.SOURCE)
-public @interface UiThread {
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/WorkerThread.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/WorkerThread.java
deleted file mode 100644
index e767eda..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/WorkerThread.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.android.ddmuilib.annotation;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Simple utility annotation used only to mark methods that are not executed on the UI thread.
- * This annotation's sole purpose is to help reading the source code. It has no additional effect.
- */
-@Target({ ElementType.METHOD })
-@Retention(RetentionPolicy.SOURCE)
-public @interface WorkerThread {
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/DdmConsole.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/DdmConsole.java
deleted file mode 100644
index 4df4376..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/DdmConsole.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.android.ddmuilib.console;
-
-
-/**
- * Static Console used to ouput messages. By default outputs the message to System.out and
- * System.err, but can receive a IDdmConsole object which will actually do something.
- */
-public class DdmConsole {
-
-    private static IDdmConsole mConsole;
-
-    /**
-     * Prints a message to the android console.
-     * @param message the message to print
-     * @param forceDisplay if true, this force the console to be displayed.
-     */
-    public static void printErrorToConsole(String message) {
-        if (mConsole != null) {
-            mConsole.printErrorToConsole(message);
-        } else {
-            System.err.println(message);
-        }
-    }
-
-    /**
-     * Prints several messages to the android console.
-     * @param messages the messages to print
-     * @param forceDisplay if true, this force the console to be displayed.
-     */
-    public static void printErrorToConsole(String[] messages) {
-        if (mConsole != null) {
-            mConsole.printErrorToConsole(messages);
-        } else {
-            for (String message : messages) {
-                System.err.println(message);
-            }
-        }
-    }
-
-    /**
-     * Prints a message to the android console.
-     * @param message the message to print
-     * @param forceDisplay if true, this force the console to be displayed.
-     */
-    public static void printToConsole(String message) {
-        if (mConsole != null) {
-            mConsole.printToConsole(message);
-        } else {
-            System.out.println(message);
-        }
-    }
-
-    /**
-     * Prints several messages to the android console.
-     * @param messages the messages to print
-     * @param forceDisplay if true, this force the console to be displayed.
-     */
-    public static void printToConsole(String[] messages) {
-        if (mConsole != null) {
-            mConsole.printToConsole(messages);
-        } else {
-            for (String message : messages) {
-                System.out.println(message);
-            }
-        }
-    }
-
-    /**
-     * Sets a IDdmConsole to override the default behavior of the console
-     * @param console The new IDdmConsole
-     * **/
-    public static void setConsole(IDdmConsole console) {
-        mConsole = console;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/IDdmConsole.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/IDdmConsole.java
deleted file mode 100644
index 3679d41..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/IDdmConsole.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.android.ddmuilib.console;
-
-
-/**
- * DDMS console interface.
- */
-public interface IDdmConsole {
-    /**
-     * Prints a message to the android console.
-     * @param message the message to print
-     */
-    public void printErrorToConsole(String message);
-
-    /**
-     * Prints several messages to the android console.
-     * @param messages the messages to print
-     */
-    public void printErrorToConsole(String[] messages);
-
-    /**
-     * Prints a message to the android console.
-     * @param message the message to print
-     */
-    public void printToConsole(String message);
-
-    /**
-     * Prints several messages to the android console.
-     * @param messages the messages to print
-     */
-    public void printToConsole(String[] messages);
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceContentProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceContentProvider.java
deleted file mode 100644
index 75c19fe..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceContentProvider.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.android.ddmuilib.explorer;
-
-import com.android.ddmlib.FileListingService;
-import com.android.ddmlib.FileListingService.FileEntry;
-import com.android.ddmlib.FileListingService.IListingReceiver;
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Tree;
-
-/**
- * Content provider class for device Explorer.
- */
-class DeviceContentProvider implements ITreeContentProvider {
-
-    private TreeViewer mViewer;
-    private FileListingService mFileListingService;
-    private FileEntry mRootEntry;
-
-    private IListingReceiver sListingReceiver = new IListingReceiver() {
-        public void setChildren(final FileEntry entry, FileEntry[] children) {
-            final Tree t = mViewer.getTree();
-            if (t != null && t.isDisposed() == false) {
-                Display display = t.getDisplay();
-                if (display.isDisposed() == false) {
-                    display.asyncExec(new Runnable() {
-                        public void run() {
-                            if (t.isDisposed() == false) {
-                                // refresh the entry.
-                                mViewer.refresh(entry);
-
-                                // force it open, since on linux and windows
-                                // when getChildren() returns null, the node is
-                                // not considered expanded.
-                                mViewer.setExpandedState(entry, true);
-                            }
-                        }
-                    });
-                }
-            }
-        }
-
-        public void refreshEntry(final FileEntry entry) {
-            final Tree t = mViewer.getTree();
-            if (t != null && t.isDisposed() == false) {
-                Display display = t.getDisplay();
-                if (display.isDisposed() == false) {
-                    display.asyncExec(new Runnable() {
-                        public void run() {
-                            if (t.isDisposed() == false) {
-                                // refresh the entry.
-                                mViewer.refresh(entry);
-                            }
-                        }
-                    });
-                }
-            }
-        }
-    };
-
-    /**
-     *
-     */
-    public DeviceContentProvider() {
-    }
-
-    public void setListingService(FileListingService fls) {
-        mFileListingService = fls;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
-     */
-    public Object[] getChildren(Object parentElement) {
-        if (parentElement instanceof FileEntry) {
-            FileEntry parentEntry = (FileEntry)parentElement;
-
-            Object[] oldEntries = parentEntry.getCachedChildren();
-            Object[] newEntries = mFileListingService.getChildren(parentEntry,
-                    true, sListingReceiver);
-
-            if (newEntries != null) {
-                return newEntries;
-            } else {
-                // if null was returned, this means the cache was not valid,
-                // and a thread was launched for ls. sListingReceiver will be
-                // notified with the new entries.
-                return oldEntries;
-            }
-        }
-        return new Object[0];
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
-     */
-    public Object getParent(Object element) {
-        if (element instanceof FileEntry) {
-            FileEntry entry = (FileEntry)element;
-
-            return entry.getParent();
-        }
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
-     */
-    public boolean hasChildren(Object element) {
-        if (element instanceof FileEntry) {
-            FileEntry entry = (FileEntry)element;
-
-            return entry.getType() == FileListingService.TYPE_DIRECTORY;
-        }
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
-     */
-    public Object[] getElements(Object inputElement) {
-        if (inputElement instanceof FileEntry) {
-            FileEntry entry = (FileEntry)inputElement;
-            if (entry.isRoot()) {
-                return getChildren(mRootEntry);
-            }
-        }
-
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IContentProvider#dispose()
-     */
-    public void dispose() {
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
-     */
-    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-        if (viewer instanceof TreeViewer) {
-            mViewer = (TreeViewer)viewer;
-        }
-        if (newInput instanceof FileEntry) {
-            mRootEntry = (FileEntry)newInput;
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
deleted file mode 100644
index 66843a4..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * 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.android.ddmuilib.explorer;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.FileListingService;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.FileListingService.FileEntry;
-import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.Panel;
-import com.android.ddmuilib.SyncProgressMonitor;
-import com.android.ddmuilib.TableHelper;
-import com.android.ddmuilib.actions.ICommonAction;
-import com.android.ddmuilib.console.DdmConsole;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.ViewerDropAdapter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.FileTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.dnd.TransferData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.DirectoryDialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeItem;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Device filesystem explorer class.
- */
-public class DeviceExplorer extends Panel {
-
-    private final static String TRACE_KEY_EXT = ".key"; // $NON-NLS-1S
-    private final static String TRACE_DATA_EXT = ".data"; // $NON-NLS-1S
-
-    private static Pattern mKeyFilePattern = Pattern.compile(
-            "(.+)\\" + TRACE_KEY_EXT); // $NON-NLS-1S
-    private static Pattern mDataFilePattern = Pattern.compile(
-            "(.+)\\" + TRACE_DATA_EXT); // $NON-NLS-1S
-
-    public static String COLUMN_NAME = "android.explorer.name"; //$NON-NLS-1S
-    public static String COLUMN_SIZE = "android.explorer.size"; //$NON-NLS-1S
-    public static String COLUMN_DATE = "android.explorer.data"; //$NON-NLS-1S
-    public static String COLUMN_TIME = "android.explorer.time"; //$NON-NLS-1S
-    public static String COLUMN_PERMISSIONS = "android.explorer.permissions"; // $NON-NLS-1S
-    public static String COLUMN_INFO = "android.explorer.info"; // $NON-NLS-1S
-
-    private Composite mParent;
-    private TreeViewer mTreeViewer;
-    private Tree mTree;
-    private DeviceContentProvider mContentProvider;
-
-    private ICommonAction mPushAction;
-    private ICommonAction mPullAction;
-    private ICommonAction mDeleteAction;
-
-    private Image mFileImage;
-    private Image mFolderImage;
-    private Image mPackageImage;
-    private Image mOtherImage;
-
-    private IDevice mCurrentDevice;
-
-    private String mDefaultSave;
-
-    public DeviceExplorer() {
-
-    }
-
-    /**
-     * Sets the images for the listview
-     * @param fileImage
-     * @param folderImage
-     * @param otherImage
-     */
-    public void setImages(Image fileImage, Image folderImage, Image packageImage,
-            Image otherImage) {
-        mFileImage = fileImage;
-        mFolderImage = folderImage;
-        mPackageImage = packageImage;
-        mOtherImage = otherImage;
-    }
-
-    /**
-     * Sets the actions so that the device explorer can enable/disable them based on the current
-     * selection
-     * @param pushAction
-     * @param pullAction
-     * @param deleteAction
-     */
-    public void setActions(ICommonAction pushAction, ICommonAction pullAction,
-            ICommonAction deleteAction) {
-        mPushAction = pushAction;
-        mPullAction = pullAction;
-        mDeleteAction = deleteAction;
-    }
-
-    /**
-     * Creates a control capable of displaying some information.  This is
-     * called once, when the application is initializing, from the UI thread.
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        mParent = parent;
-        parent.setLayout(new FillLayout());
-
-        mTree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL);
-        mTree.setHeaderVisible(true);
-
-        IPreferenceStore store = DdmUiPreferences.getStore();
-
-        // create columns
-        TableHelper.createTreeColumn(mTree, "Name", SWT.LEFT,
-                "0000drwxrwxrwx", COLUMN_NAME, store); //$NON-NLS-1$
-        TableHelper.createTreeColumn(mTree, "Size", SWT.RIGHT,
-                "000000", COLUMN_SIZE, store); //$NON-NLS-1$
-        TableHelper.createTreeColumn(mTree, "Date", SWT.LEFT,
-                "2007-08-14", COLUMN_DATE, store); //$NON-NLS-1$
-        TableHelper.createTreeColumn(mTree, "Time", SWT.LEFT,
-                "20:54", COLUMN_TIME, store); //$NON-NLS-1$
-        TableHelper.createTreeColumn(mTree, "Permissions", SWT.LEFT,
-                "drwxrwxrwx", COLUMN_PERMISSIONS, store); //$NON-NLS-1$
-        TableHelper.createTreeColumn(mTree, "Info", SWT.LEFT,
-                "drwxrwxrwx", COLUMN_INFO, store); //$NON-NLS-1$
-
-        // create the jface wrapper
-        mTreeViewer = new TreeViewer(mTree);
-
-        // setup data provider
-        mContentProvider = new DeviceContentProvider();
-        mTreeViewer.setContentProvider(mContentProvider);
-        mTreeViewer.setLabelProvider(new FileLabelProvider(mFileImage,
-                mFolderImage, mPackageImage, mOtherImage));
-
-        // setup a listener for selection
-        mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                ISelection sel = event.getSelection();
-                if (sel.isEmpty()) {
-                    mPullAction.setEnabled(false);
-                    mPushAction.setEnabled(false);
-                    mDeleteAction.setEnabled(false);
-                    return;
-                }
-                if (sel instanceof IStructuredSelection) {
-                    IStructuredSelection selection = (IStructuredSelection) sel;
-                    Object element = selection.getFirstElement();
-                    if (element == null)
-                        return;
-                    if (element instanceof FileEntry) {
-                        mPullAction.setEnabled(true);
-                        mPushAction.setEnabled(selection.size() == 1);
-                        if (selection.size() == 1) {
-                            setDeleteEnabledState((FileEntry)element);
-                        } else {
-                            mDeleteAction.setEnabled(false);
-                        }
-                    }
-                }
-            }
-        });
-
-        // add support for double click
-        mTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
-            public void doubleClick(DoubleClickEvent event) {
-                ISelection sel = event.getSelection();
-
-                if (sel instanceof IStructuredSelection) {
-                    IStructuredSelection selection = (IStructuredSelection) sel;
-
-                    if (selection.size() == 1) {
-                        FileEntry entry = (FileEntry)selection.getFirstElement();
-                        String name = entry.getName();
-
-                        FileEntry parentEntry = entry.getParent();
-
-                        // can't really do anything with no parent
-                        if (parentEntry == null) {
-                            return;
-                        }
-
-                        // check this is a file like we want.
-                        Matcher m = mKeyFilePattern.matcher(name);
-                        if (m.matches()) {
-                            // get the name w/o the extension
-                            String baseName = m.group(1);
-
-                            // add the data extension
-                            String dataName = baseName + TRACE_DATA_EXT;
-
-                            FileEntry dataEntry = parentEntry.findChild(dataName);
-
-                            handleTraceDoubleClick(baseName, entry, dataEntry);
-
-                        } else {
-                            m = mDataFilePattern.matcher(name);
-                            if (m.matches()) {
-                                // get the name w/o the extension
-                                String baseName = m.group(1);
-
-                                // add the key extension
-                                String keyName = baseName + TRACE_KEY_EXT;
-
-                                FileEntry keyEntry = parentEntry.findChild(keyName);
-
-                                handleTraceDoubleClick(baseName, keyEntry, entry);
-                            }
-                        }
-                    }
-                }
-            }
-        });
-
-        // setup drop listener
-        mTreeViewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE,
-                new Transfer[] { FileTransfer.getInstance() },
-                new ViewerDropAdapter(mTreeViewer) {
-            @Override
-            public boolean performDrop(Object data) {
-                // get the item on which we dropped the item(s)
-                FileEntry target = (FileEntry)getCurrentTarget();
-
-                // in case we drop at the same level as root
-                if (target == null) {
-                    return false;
-                }
-
-                // if the target is not a directory, we get the parent directory
-                if (target.isDirectory() == false) {
-                    target = target.getParent();
-                }
-
-                if (target == null) {
-                    return false;
-                }
-
-                // get the list of files to drop
-                String[] files = (String[])data;
-
-                // do the drop
-                pushFiles(files, target);
-
-                // we need to finish with a refresh
-                refresh(target);
-
-                return true;
-            }
-
-            @Override
-            public boolean validateDrop(Object target, int operation, TransferData transferType) {
-                if (target == null) {
-                    return false;
-                }
-
-                // convert to the real item
-                FileEntry targetEntry = (FileEntry)target;
-
-                // if the target is not a directory, we get the parent directory
-                if (targetEntry.isDirectory() == false) {
-                    target = targetEntry.getParent();
-                }
-
-                if (target == null) {
-                    return false;
-                }
-
-                return true;
-            }
-        });
-
-        // create and start the refresh thread
-        new Thread("Device Ls refresher") {
-            @Override
-            public void run() {
-                while (true) {
-                    try {
-                        sleep(FileListingService.REFRESH_RATE);
-                    } catch (InterruptedException e) {
-                        return;
-                    }
-
-                    if (mTree != null && mTree.isDisposed() == false) {
-                        Display display = mTree.getDisplay();
-                        if (display.isDisposed() == false) {
-                            display.asyncExec(new Runnable() {
-                                public void run() {
-                                    if (mTree.isDisposed() == false) {
-                                        mTreeViewer.refresh(true);
-                                    }
-                                }
-                            });
-                        } else {
-                            return;
-                        }
-                    } else {
-                        return;
-                    }
-                }
-
-            }
-        }.start();
-
-        return mTree;
-    }
-
-    @Override
-    protected void postCreation() {
-
-    }
-
-    /**
-     * Sets the focus to the proper control inside the panel.
-     */
-    @Override
-    public void setFocus() {
-        mTree.setFocus();
-    }
-
-    /**
-     * Processes a double click on a trace file
-     * @param baseName the base name of the 2 files.
-     * @param keyEntry The FileEntry for the .key file.
-     * @param dataEntry The FileEntry for the .data file.
-     */
-    private void handleTraceDoubleClick(String baseName, FileEntry keyEntry,
-            FileEntry dataEntry) {
-        // first we need to download the files.
-        File keyFile;
-        File dataFile;
-        String path;
-        try {
-            // create a temp file for keyFile
-            File f = File.createTempFile(baseName, ".trace");
-            f.delete();
-            f.mkdir();
-
-            path = f.getAbsolutePath();
-
-            keyFile = new File(path + File.separator + keyEntry.getName());
-            dataFile = new File(path + File.separator + dataEntry.getName());
-        } catch (IOException e) {
-            return;
-        }
-
-        // download the files
-        try {
-            SyncService sync = mCurrentDevice.getSyncService();
-            if (sync != null) {
-                ISyncProgressMonitor monitor = SyncService.getNullProgressMonitor();
-                SyncResult result = sync.pullFile(keyEntry, keyFile.getAbsolutePath(), monitor);
-                if (result.getCode() != SyncService.RESULT_OK) {
-                    DdmConsole.printErrorToConsole(String.format(
-                            "Failed to pull %1$s: %2$s", keyEntry.getName(), result.getMessage()));
-                    return;
-                }
-
-                result = sync.pullFile(dataEntry, dataFile.getAbsolutePath(), monitor);
-                if (result.getCode() != SyncService.RESULT_OK) {
-                    DdmConsole.printErrorToConsole(String.format(
-                            "Failed to pull %1$s: %2$s", dataEntry.getName(), result.getMessage()));
-                    return;
-                }
-
-                // now that we have the file, we need to launch traceview
-                String[] command = new String[2];
-                command[0] = DdmUiPreferences.getTraceview();
-                command[1] = path + File.separator + baseName;
-
-                try {
-                    final Process p = Runtime.getRuntime().exec(command);
-
-                    // create a thread for the output
-                    new Thread("Traceview output") {
-                        @Override
-                        public void run() {
-                            // create a buffer to read the stderr output
-                            InputStreamReader is = new InputStreamReader(p.getErrorStream());
-                            BufferedReader resultReader = new BufferedReader(is);
-
-                            // read the lines as they come. if null is returned, it's
-                            // because the process finished
-                            try {
-                                while (true) {
-                                    String line = resultReader.readLine();
-                                    if (line != null) {
-                                        DdmConsole.printErrorToConsole("Traceview: " + line);
-                                    } else {
-                                        break;
-                                    }
-                                }
-                                // get the return code from the process
-                                p.waitFor();
-                            } catch (IOException e) {
-                            } catch (InterruptedException e) {
-
-                            }
-                        }
-                    }.start();
-
-                } catch (IOException e) {
-                }
-            }
-        } catch (IOException e) {
-            DdmConsole.printErrorToConsole(String.format(
-                    "Failed to pull %1$s: %2$s", keyEntry.getName(), e.getMessage()));
-            return;
-        }
-    }
-
-    /**
-     * Pull the current selection on the local drive. This method displays
-     * a dialog box to let the user select where to store the file(s) and
-     * folder(s).
-     */
-    public void pullSelection() {
-        // get the selection
-        TreeItem[] items = mTree.getSelection();
-
-        // name of the single file pull, or null if we're pulling a directory
-        // or more than one object.
-        String filePullName = null;
-        FileEntry singleEntry = null;
-
-        // are we pulling a single file?
-        if (items.length == 1) {
-            singleEntry = (FileEntry)items[0].getData();
-            if (singleEntry.getType() == FileListingService.TYPE_FILE) {
-                filePullName = singleEntry.getName();
-            }
-        }
-
-        // where do we save by default?
-        String defaultPath = mDefaultSave;
-        if (defaultPath == null) {
-            defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
-        }
-
-        if (filePullName != null) {
-            FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.SAVE);
-
-            fileDialog.setText("Get Device File");
-            fileDialog.setFileName(filePullName);
-            fileDialog.setFilterPath(defaultPath);
-
-            String fileName = fileDialog.open();
-            if (fileName != null) {
-                mDefaultSave = fileDialog.getFilterPath();
-
-                pullFile(singleEntry, fileName);
-            }
-        } else {
-            DirectoryDialog directoryDialog = new DirectoryDialog(mParent.getShell(), SWT.SAVE);
-
-            directoryDialog.setText("Get Device Files/Folders");
-            directoryDialog.setFilterPath(defaultPath);
-
-            String directoryName = directoryDialog.open();
-            if (directoryName != null) {
-                pullSelection(items, directoryName);
-            }
-        }
-    }
-
-    /**
-     * Push new file(s) and folder(s) into the current selection. Current
-     * selection must be single item. If the current selection is not a
-     * directory, the parent directory is used.
-     * This method displays a dialog to let the user choose file to push to
-     * the device.
-     */
-    public void pushIntoSelection() {
-        // get the name of the object we're going to pull
-        TreeItem[] items = mTree.getSelection();
-
-        if (items.length == 0) {
-            return;
-        }
-
-        FileDialog dlg = new FileDialog(mParent.getShell(), SWT.OPEN);
-        String fileName;
-
-        dlg.setText("Put File on Device");
-
-        // There should be only one.
-        FileEntry entry = (FileEntry)items[0].getData();
-        dlg.setFileName(entry.getName());
-
-        String defaultPath = mDefaultSave;
-        if (defaultPath == null) {
-            defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
-        }
-        dlg.setFilterPath(defaultPath);
-
-        fileName = dlg.open();
-        if (fileName != null) {
-            mDefaultSave = dlg.getFilterPath();
-
-            // we need to figure out the remote path based on the current selection type.
-            String remotePath;
-            FileEntry toRefresh = entry;
-            if (entry.isDirectory()) {
-                remotePath = entry.getFullPath();
-            } else {
-                toRefresh = entry.getParent();
-                remotePath = toRefresh.getFullPath();
-            }
-
-            pushFile(fileName, remotePath);
-            mTreeViewer.refresh(toRefresh);
-        }
-    }
-
-    public void deleteSelection() {
-        // get the name of the object we're going to pull
-        TreeItem[] items = mTree.getSelection();
-
-        if (items.length != 1) {
-            return;
-        }
-
-        FileEntry entry = (FileEntry)items[0].getData();
-        final FileEntry parentEntry = entry.getParent();
-
-        // create the delete command
-        String command = "rm " + entry.getFullEscapedPath(); //$NON-NLS-1$
-
-        try {
-            mCurrentDevice.executeShellCommand(command, new IShellOutputReceiver() {
-                public void addOutput(byte[] data, int offset, int length) {
-                    // pass
-                    // TODO get output to display errors if any.
-                }
-
-                public void flush() {
-                    mTreeViewer.refresh(parentEntry);
-                }
-
-                public boolean isCancelled() {
-                    return false;
-                }
-            });
-        } catch (IOException e) {
-            // adb failed somehow, we do nothing. We should be displaying the error from the output
-            // of the shell command.
-        }
-
-    }
-
-    /**
-     * Force a full refresh of the explorer.
-     */
-    public void refresh() {
-        mTreeViewer.refresh(true);
-    }
-
-    /**
-     * Sets the new device to explorer
-     */
-    public void switchDevice(final IDevice device) {
-        if (device != mCurrentDevice) {
-            mCurrentDevice = device;
-            // now we change the input. but we need to do that in the
-            // ui thread.
-            if (mTree.isDisposed() == false) {
-                Display d = mTree.getDisplay();
-                d.asyncExec(new Runnable() {
-                    public void run() {
-                        if (mTree.isDisposed() == false) {
-                            // new service
-                            if (mCurrentDevice != null) {
-                                FileListingService fls = mCurrentDevice.getFileListingService();
-                                mContentProvider.setListingService(fls);
-                                mTreeViewer.setInput(fls.getRoot());
-                            }
-                        }
-                    }
-                });
-            }
-        }
-    }
-
-    /**
-     * Refresh an entry from a non ui thread.
-     * @param entry the entry to refresh.
-     */
-    private void refresh(final FileEntry entry) {
-        Display d = mTreeViewer.getTree().getDisplay();
-        d.asyncExec(new Runnable() {
-            public void run() {
-                mTreeViewer.refresh(entry);
-            }
-        });
-    }
-
-    /**
-     * Pulls the selection from a device.
-     * @param items the tree selection the remote file on the device
-     * @param localDirector the local directory in which to save the files.
-     */
-    private void pullSelection(TreeItem[] items, final String localDirectory) {
-        try {
-            final SyncService sync = mCurrentDevice.getSyncService();
-            if (sync != null) {
-                // make a list of the FileEntry.
-                ArrayList<FileEntry> entries = new ArrayList<FileEntry>();
-                for (TreeItem item : items) {
-                    Object data = item.getData();
-                    if (data instanceof FileEntry) {
-                        entries.add((FileEntry)data);
-                    }
-                }
-                final FileEntry[] entryArray = entries.toArray(
-                        new FileEntry[entries.size()]);
-
-                // get a progressdialog
-                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
-                        new IRunnableWithProgress() {
-                    public void run(IProgressMonitor monitor)
-                            throws InvocationTargetException,
-                            InterruptedException {
-                        // create a monitor wrapper around the jface monitor
-                        SyncResult result = sync.pull(entryArray, localDirectory,
-                                new SyncProgressMonitor(monitor,
-                                        "Pulling file(s) from the device"));
-
-                        if (result.getCode() != SyncService.RESULT_OK) {
-                            DdmConsole.printErrorToConsole(String.format(
-                                    "Failed to pull selection: %1$s", result.getMessage()));
-                        }
-                        sync.close();
-                    }
-                });
-            }
-        } catch (Exception e) {
-            DdmConsole.printErrorToConsole( "Failed to pull selection");
-            DdmConsole.printErrorToConsole(e.getMessage());
-        }
-    }
-
-    /**
-     * Pulls a file from a device.
-     * @param remote the remote file on the device
-     * @param local the destination filepath
-     */
-    private void pullFile(final FileEntry remote, final String local) {
-        try {
-            final SyncService sync = mCurrentDevice.getSyncService();
-            if (sync != null) {
-                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
-                        new IRunnableWithProgress() {
-                    public void run(IProgressMonitor monitor)
-                            throws InvocationTargetException,
-                            InterruptedException {
-                        SyncResult result = sync.pullFile(remote, local, new SyncProgressMonitor(
-                                monitor, String.format("Pulling %1$s from the device",
-                                        remote.getName())));
-                        if (result.getCode() != SyncService.RESULT_OK) {
-                            DdmConsole.printErrorToConsole(String.format(
-                                    "Failed to pull %1$s: %2$s", remote, result.getMessage()));
-                        }
-
-                        sync.close();
-                    }
-                });
-            }
-        } catch (Exception e) {
-            DdmConsole.printErrorToConsole( "Failed to pull selection");
-            DdmConsole.printErrorToConsole(e.getMessage());
-        }
-    }
-
-    /**
-     * Pushes several files and directory into a remote directory.
-     * @param localFiles
-     * @param remoteDirectory
-     */
-    private void pushFiles(final String[] localFiles, final FileEntry remoteDirectory) {
-        try {
-            final SyncService sync = mCurrentDevice.getSyncService();
-            if (sync != null) {
-                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
-                        new IRunnableWithProgress() {
-                    public void run(IProgressMonitor monitor)
-                            throws InvocationTargetException,
-                            InterruptedException {
-                        SyncResult result = sync.push(localFiles, remoteDirectory,
-                                    new SyncProgressMonitor(monitor,
-                                            "Pushing file(s) to the device"));
-                        if (result.getCode() != SyncService.RESULT_OK) {
-                            DdmConsole.printErrorToConsole(String.format(
-                                    "Failed to push the items: %1$s", result.getMessage()));
-                        }
-
-                        sync.close();
-                    }
-                });
-            }
-        } catch (Exception e) {
-            DdmConsole.printErrorToConsole("Failed to push the items");
-            DdmConsole.printErrorToConsole(e.getMessage());
-        }
-    }
-
-    /**
-     * Pushes a file on a device.
-     * @param local the local filepath of the file to push
-     * @param remoteDirectory the remote destination directory on the device
-     */
-    private void pushFile(final String local, final String remoteDirectory) {
-        try {
-            final SyncService sync = mCurrentDevice.getSyncService();
-            if (sync != null) {
-                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
-                        new IRunnableWithProgress() {
-                    public void run(IProgressMonitor monitor)
-                            throws InvocationTargetException,
-                            InterruptedException {
-                        // get the file name
-                        String[] segs = local.split(Pattern.quote(File.separator));
-                        String name = segs[segs.length-1];
-                        String remoteFile = remoteDirectory + FileListingService.FILE_SEPARATOR
-                                + name;
-
-                        SyncResult result = sync.pushFile(local, remoteFile,
-                                    new SyncProgressMonitor(monitor,
-                                            String.format("Pushing %1$s to the device.", name)));
-                        if (result.getCode() != SyncService.RESULT_OK) {
-                            DdmConsole.printErrorToConsole(String.format(
-                                    "Failed to push %1$s on %2$s: %3$s",
-                                    name, mCurrentDevice.getSerialNumber(), result.getMessage()));
-                        }
-
-                        sync.close();
-                    }
-                });
-            }
-        } catch (Exception e) {
-            DdmConsole.printErrorToConsole("Failed to push the item(s).");
-            DdmConsole.printErrorToConsole(e.getMessage());
-        }
-    }
-
-    /**
-     * Sets the enabled state based on a FileEntry properties
-     * @param element The selected FileEntry
-     */
-    protected void setDeleteEnabledState(FileEntry element) {
-        mDeleteAction.setEnabled(element.getType() == FileListingService.TYPE_FILE);
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/FileLabelProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/FileLabelProvider.java
deleted file mode 100644
index 1dca962..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/FileLabelProvider.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.android.ddmuilib.explorer;
-
-import com.android.ddmlib.FileListingService;
-import com.android.ddmlib.FileListingService.FileEntry;
-
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * Label provider for the FileEntry.
- */
-class FileLabelProvider implements ILabelProvider, ITableLabelProvider {
-
-    private Image mFileImage;
-    private Image mFolderImage;
-    private Image mPackageImage;
-    private Image mOtherImage;
-
-    /**
-     * Creates Label provider with custom images.
-     * @param fileImage the Image to represent a file
-     * @param folderImage the Image to represent a folder
-     * @param packageImage the Image to represent a .apk file. If null,
-     *      fileImage is used instead.
-     * @param otherImage the Image to represent all other entry type.
-     */
-    public FileLabelProvider(Image fileImage, Image folderImage,
-            Image packageImage, Image otherImage) {
-        mFileImage = fileImage;
-        mFolderImage = folderImage;
-        mOtherImage = otherImage;
-        if (packageImage != null) {
-            mPackageImage = packageImage;
-        } else {
-            mPackageImage = fileImage;
-        }
-    }
-
-    /**
-     * Creates a label provider with default images.
-     *
-     */
-    public FileLabelProvider() {
-
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
-     */
-    public Image getImage(Object element) {
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
-     */
-    public String getText(Object element) {
-        return null;
-    }
-
-    public Image getColumnImage(Object element, int columnIndex) {
-        if (columnIndex == 0) {
-            if (element instanceof FileEntry) {
-                FileEntry entry = (FileEntry)element;
-                switch (entry.getType()) {
-                    case FileListingService.TYPE_FILE:
-                    case FileListingService.TYPE_LINK:
-                        // get the name and extension
-                        if (entry.isApplicationPackage()) {
-                            return mPackageImage;
-                        }
-                        return mFileImage;
-                    case FileListingService.TYPE_DIRECTORY:
-                    case FileListingService.TYPE_DIRECTORY_LINK:
-                        return mFolderImage;
-                }
-            }
-
-            // default case return a different image.
-            return mOtherImage;
-        }
-        return null;
-    }
-
-    public String getColumnText(Object element, int columnIndex) {
-        if (element instanceof FileEntry) {
-            FileEntry entry = (FileEntry)element;
-
-            switch (columnIndex) {
-                case 0:
-                    return entry.getName();
-                case 1:
-                    return entry.getSize();
-                case 2:
-                    return entry.getDate();
-                case 3:
-                    return entry.getTime();
-                case 4:
-                    return entry.getPermissions();
-                case 5:
-                    return entry.getInfo();
-            }
-        }
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
-     */
-    public void addListener(ILabelProviderListener listener) {
-        // we don't need listeners.
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
-     */
-    public void dispose() {
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
-     */
-    public boolean isLabelProperty(Object element, String property) {
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
-     */
-    public void removeListener(ILabelProviderListener listener) {
-        // we don't need listeners
-    }
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java
deleted file mode 100644
index 3a2a2ef..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/BaseFileHandler.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmuilib.handler;
-
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.ClientData.IHprofDumpHandler;
-import com.android.ddmlib.ClientData.IMethodProfilingHandler;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmuilib.SyncProgressMonitor;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Base handler class for handler dealing with files located on a device.
- *
- * @see IHprofDumpHandler
- * @see IMethodProfilingHandler
- */
-public class BaseFileHandler {
-
-    protected final Shell mParentShell;
-
-    public BaseFileHandler(Shell parentShell) {
-        mParentShell = parentShell;
-    }
-
-    /**
-     * Prompts the user for a save location and pulls the remote files into this location.
-     * <p/>This <strong>must</strong> be called from the UI Thread.
-     * @param sync the {@link SyncService} to use to pull the file from the device
-     * @param localFileName The default local name
-     * @param remoteFilePath The name of the file to pull off of the device
-     * @param title The title of the File Save dialog.
-     * @return The result of the pull as a {@link SyncResult} object, or null if the sync
-     * didn't happen (canceled by the user).
-     * @throws InvocationTargetException
-     * @throws InterruptedException
-     */
-    protected SyncResult promptAndPull(SyncService sync,
-            String localFileName, String remoteFilePath, String title)
-            throws InvocationTargetException, InterruptedException {
-        FileDialog fileDialog = new FileDialog(mParentShell, SWT.SAVE);
-
-        fileDialog.setText(title);
-        fileDialog.setFileName(localFileName);
-
-        String localFilePath = fileDialog.open();
-        if (localFilePath != null) {
-            return pull(sync, localFilePath, remoteFilePath);
-        }
-
-        return null;
-    }
-
-    /**
-     * Pulls a file off of a device
-     * @param sync the {@link SyncService} to use to pull the file.
-     * @param localFilePath the path of the local file to create
-     * @param remoteFilePath the path of the remote file to pull
-     * @return the result of the sync as an instance of {@link SyncResult}
-     * @throws InvocationTargetException
-     * @throws InterruptedException
-     */
-    protected SyncResult pull(final SyncService sync, final String localFilePath,
-            final String remoteFilePath)
-            throws InvocationTargetException, InterruptedException {
-        final SyncResult[] res = new SyncResult[1];
-        new ProgressMonitorDialog(mParentShell).run(true, true, new IRunnableWithProgress() {
-            public void run(IProgressMonitor monitor) {
-                try {
-                    res[0] = sync.pullFile(remoteFilePath, localFilePath,
-                            new SyncProgressMonitor(monitor, String.format(
-                                    "Pulling %1$s from the device", remoteFilePath)));
-                } finally {
-                    sync.close();
-                }
-            }
-        });
-
-        return res[0];
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java
deleted file mode 100644
index f469a7d..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmuilib.handler;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.ClientData.IMethodProfilingHandler;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.console.DdmConsole;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Handler for Method tracing.
- * This will pull the trace file into a temp file and launch traceview.
- */
-public class MethodProfilingHandler extends BaseFileHandler
-        implements IMethodProfilingHandler {
-
-    public MethodProfilingHandler(Shell parentShell) {
-        super(parentShell);
-    }
-
-    public void onFailure(final Client client) {
-        mParentShell.getDisplay().asyncExec(new Runnable() {
-            public void run() {
-                displayError(
-                        "Unable to create Method Profiling file for application '%1$s'.\n" +
-                        "Check logcat for more information.",
-                        client.getClientData().getClientDescription());
-            }
-        });
-    }
-
-    public void onSuccess(final String remoteFilePath, final Client client) {
-        mParentShell.getDisplay().asyncExec(new Runnable() {
-            public void run() {
-                if (remoteFilePath == null) {
-                    displayError(
-                            "Unable to download trace file: unknown file name.\n" +
-                            "This can happen if you disconnected the device while recording the trace.");
-                    return;
-                }
-
-                final IDevice device = client.getDevice();
-                try {
-                    // get the sync service to pull the HPROF file
-                    final SyncService sync = client.getDevice().getSyncService();
-                    if (sync != null) {
-                        pullAndOpen(sync, remoteFilePath);
-                    } else {
-                        displayError("Unable to download trace file from device '%1$s'.",
-                                device.getSerialNumber());
-                    }
-                } catch (Exception e) {
-                    displayError("Unable to download trace file from device '%1$s'.",
-                            device.getSerialNumber());
-                }
-            }
-
-        });
-    }
-
-    private void pullAndOpen(SyncService sync, String remoteFilePath)
-            throws InvocationTargetException, InterruptedException, IOException {
-        // get a temp file
-        File temp = File.createTempFile("android", ".trace"); //$NON-NLS-1$ //$NON-NLS-2$
-        String tempPath = temp.getAbsolutePath();
-
-        // pull the file
-        SyncResult result = pull(sync, tempPath, remoteFilePath);
-        if (result != null) {
-            if (result.getCode() == SyncService.RESULT_OK) {
-                // open the temp file in traceview
-                openInTraceview(tempPath);
-            } else {
-                displayError("Unable to download trace file:\n\n%1$s",
-                        result.getMessage());
-            }
-        } else {
-            // this really shouldn't happen.
-            displayError("Unable to download trace file.");
-        }
-    }
-
-    private void openInTraceview(String tempPath) {
-        // now that we have the file, we need to launch traceview
-        String[] command = new String[2];
-        command[0] = DdmUiPreferences.getTraceview();
-        command[1] = tempPath;
-
-        try {
-            final Process p = Runtime.getRuntime().exec(command);
-
-            // create a thread for the output
-            new Thread("Traceview output") {
-                @Override
-                public void run() {
-                    // create a buffer to read the stderr output
-                    InputStreamReader is = new InputStreamReader(p.getErrorStream());
-                    BufferedReader resultReader = new BufferedReader(is);
-
-                    // read the lines as they come. if null is returned, it's
-                    // because the process finished
-                    try {
-                        while (true) {
-                            String line = resultReader.readLine();
-                            if (line != null) {
-                                DdmConsole.printErrorToConsole("Traceview: " + line);
-                            } else {
-                                break;
-                            }
-                        }
-                        // get the return code from the process
-                        p.waitFor();
-                    } catch (Exception e) {
-                        Log.e("traceview", e);
-                    }
-                }
-            }.start();
-        } catch (IOException e) {
-            Log.e("traceview", e);
-        }
-    }
-
-    private void displayError(String format, Object... args) {
-        MessageDialog.openError(mParentShell, "Method Profiling Error",
-                String.format(format, args));
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/CoordinateControls.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/CoordinateControls.java
deleted file mode 100644
index 578a7ac..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/CoordinateControls.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Encapsulation of controls handling a location coordinate in decimal and sexagesimal.
- * <p/>This handle the conversion between both modes automatically by using a {@link ModifyListener}
- * on all the {@link Text} widgets.
- * <p/>To get/set the coordinate, use {@link #setValue(double)} and {@link #getValue()} (preceded by
- * a call to {@link #isValueValid()})
- */
-public final class CoordinateControls {
-    private double mValue;
-    private boolean mValueValidity = false;
-    private Text mDecimalText;
-    private Text mSexagesimalDegreeText;
-    private Text mSexagesimalMinuteText;
-    private Text mSexagesimalSecondText;
-    
-    /** Internal flag to prevent {@link ModifyEvent} to be sent when {@link Text#setText(String)}
-     * is called. This is an int instead of a boolean to act as a counter. */
-    private int mManualTextChange = 0;
-    
-    /**
-     * ModifyListener for the 3 {@link Text} controls of the sexagesimal mode.
-     */
-    private ModifyListener mSexagesimalListener = new ModifyListener() {
-        public void modifyText(ModifyEvent event) {
-            if (mManualTextChange > 0) {
-                return;
-            }
-            try {
-                mValue = getValueFromSexagesimalControls();
-                setValueIntoDecimalControl(mValue);
-                mValueValidity = true;
-            } catch (NumberFormatException e) {
-                // wrong format empty the decimal controls.
-                mValueValidity = false;
-                resetDecimalControls();
-            }
-        }
-    };
-    
-    /**
-     * Creates the {@link Text} control for the decimal display of the coordinate.
-     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
-     * @param parent The {@link Composite} parent of the control.
-     */
-    public void createDecimalText(Composite parent) {
-        mDecimalText = createTextControl(parent, "-199.999999", new ModifyListener() {
-            public void modifyText(ModifyEvent event) {
-                if (mManualTextChange > 0) {
-                    return;
-                }
-                try {
-                    mValue = Double.parseDouble(mDecimalText.getText());
-                    setValueIntoSexagesimalControl(mValue);
-                    mValueValidity = true;
-                } catch (NumberFormatException e) {
-                    // wrong format empty the sexagesimal controls.
-                    mValueValidity = false;
-                    resetSexagesimalControls();
-                }
-            }
-        });
-    }
-    
-    /**
-     * Creates the {@link Text} control for the "degree" display of the coordinate in sexagesimal
-     * mode.
-     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
-     * @param parent The {@link Composite} parent of the control.
-     */
-    public void createSexagesimalDegreeText(Composite parent) {
-        mSexagesimalDegreeText = createTextControl(parent, "-199", mSexagesimalListener); //$NON-NLS-1$
-    }
-    
-    /**
-     * Creates the {@link Text} control for the "minute" display of the coordinate in sexagesimal
-     * mode.
-     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
-     * @param parent The {@link Composite} parent of the control.
-     */
-    public void createSexagesimalMinuteText(Composite parent) {
-        mSexagesimalMinuteText = createTextControl(parent, "99", mSexagesimalListener); //$NON-NLS-1$
-    }
-
-    /**
-     * Creates the {@link Text} control for the "second" display of the coordinate in sexagesimal
-     * mode.
-     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
-     * @param parent The {@link Composite} parent of the control.
-     */
-    public void createSexagesimalSecondText(Composite parent) {
-        mSexagesimalSecondText = createTextControl(parent, "99.999", mSexagesimalListener); //$NON-NLS-1$
-    }
-    
-    /**
-     * Sets the coordinate into the {@link Text} controls.
-     * @param value the coordinate value to set.
-     */
-    public void setValue(double value) {
-        mValue = value;
-        mValueValidity = true;
-        setValueIntoDecimalControl(value);
-        setValueIntoSexagesimalControl(value);
-    }
-    
-    /**
-     * Returns whether the value in the control(s) is valid.
-     */
-    public boolean isValueValid() {
-        return mValueValidity;
-    }
-
-    /**
-     * Returns the current value set in the control(s).
-     * <p/>This value can be erroneous, and a check with {@link #isValueValid()} should be performed
-     * before any call to this method.
-     */
-    public double getValue() {
-        return mValue;
-    }
-    
-    /**
-     * Enables or disables all the {@link Text} controls.
-     * @param enabled the enabled state.
-     */
-    public void setEnabled(boolean enabled) {
-        mDecimalText.setEnabled(enabled);
-        mSexagesimalDegreeText.setEnabled(enabled);
-        mSexagesimalMinuteText.setEnabled(enabled);
-        mSexagesimalSecondText.setEnabled(enabled);
-    }
-    
-    private void resetDecimalControls() {
-        mManualTextChange++;
-        mDecimalText.setText(""); //$NON-NLS-1$
-        mManualTextChange--;
-    }
-
-    private void resetSexagesimalControls() {
-        mManualTextChange++;
-        mSexagesimalDegreeText.setText(""); //$NON-NLS-1$
-        mSexagesimalMinuteText.setText(""); //$NON-NLS-1$
-        mSexagesimalSecondText.setText(""); //$NON-NLS-1$
-        mManualTextChange--;
-    }
-    
-    /**
-     * Creates a {@link Text} with a given parent, default string and a {@link ModifyListener}
-     * @param parent the parent {@link Composite}.
-     * @param defaultString the default string to be used to compute the {@link Text} control
-     * size hint.
-     * @param listener the {@link ModifyListener} to be called when the {@link Text} control is
-     * modified.
-     */
-    private Text createTextControl(Composite parent, String defaultString,
-            ModifyListener listener) {
-        // create the control
-        Text text = new Text(parent, SWT.BORDER | SWT.LEFT | SWT.SINGLE);
-        
-        // add the standard listener to it.
-        text.addModifyListener(listener);
-        
-        // compute its size/
-        mManualTextChange++;
-        text.setText(defaultString);
-        text.pack();
-        Point size = text.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-        text.setText(""); //$NON-NLS-1$
-        mManualTextChange--;
-        
-        GridData gridData = new GridData();
-        gridData.widthHint = size.x;
-        text.setLayoutData(gridData);
-        
-        return text;
-    }
-    
-    private double getValueFromSexagesimalControls() throws NumberFormatException {
-        double degrees = Double.parseDouble(mSexagesimalDegreeText.getText());
-        double minutes = Double.parseDouble(mSexagesimalMinuteText.getText());
-        double seconds = Double.parseDouble(mSexagesimalSecondText.getText());
-        
-        boolean isPositive = (degrees >= 0.);
-        degrees = Math.abs(degrees);
-
-        double value = degrees + minutes / 60. + seconds / 3600.; 
-        return isPositive ? value : - value;
-    }
-
-    private void setValueIntoDecimalControl(double value) {
-        mManualTextChange++;
-        mDecimalText.setText(String.format("%.6f", value));
-        mManualTextChange--;
-    }
-    
-    private void setValueIntoSexagesimalControl(double value) {
-        // get the sign and make the number positive no matter what.
-        boolean isPositive = (value >= 0.);
-        value = Math.abs(value);
-        
-        // get the degree
-        double degrees = Math.floor(value);
-        
-        // get the minutes
-        double minutes = Math.floor((value - degrees) * 60.);
-        
-        // get the seconds.
-        double seconds = (value - degrees) * 3600. - minutes * 60.;
-        
-        mManualTextChange++;
-        mSexagesimalDegreeText.setText(
-                Integer.toString(isPositive ? (int)degrees : (int)- degrees));
-        mSexagesimalMinuteText.setText(Integer.toString((int)minutes));
-        mSexagesimalSecondText.setText(String.format("%.3f", seconds)); //$NON-NLS-1$
-        mManualTextChange--;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/GpxParser.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/GpxParser.java
deleted file mode 100644
index a30337a..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/GpxParser.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * A very basic GPX parser to meet the need of the emulator control panel.
- * <p/>
- * It parses basic waypoint information, and tracks (merging segments).
- */
-public class GpxParser {
-    
-    private final static String NS_GPX = "http://www.topografix.com/GPX/1/1";  //$NON-NLS-1$
-        
-    private final static String NODE_WAYPOINT = "wpt"; //$NON-NLS-1$
-    private final static String NODE_TRACK = "trk"; //$NON-NLS-1$
-    private final static String NODE_TRACK_SEGMENT = "trkseg"; //$NON-NLS-1$
-    private final static String NODE_TRACK_POINT = "trkpt"; //$NON-NLS-1$
-    private final static String NODE_NAME = "name"; //$NON-NLS-1$
-    private final static String NODE_TIME = "time"; //$NON-NLS-1$
-    private final static String NODE_ELEVATION = "ele"; //$NON-NLS-1$
-    private final static String NODE_DESCRIPTION = "desc"; //$NON-NLS-1$
-    private final static String ATTR_LONGITUDE = "lon"; //$NON-NLS-1$
-    private final static String ATTR_LATITUDE = "lat"; //$NON-NLS-1$
-    
-    private static SAXParserFactory sParserFactory;
-    
-    static {
-        sParserFactory = SAXParserFactory.newInstance();
-        sParserFactory.setNamespaceAware(true);
-    }
-
-    private String mFileName;
-
-    private GpxHandler mHandler;
-    
-    /** Pattern to parse time with optional sub-second precision, and optional
-     * Z indicating the time is in UTC. */
-    private final static Pattern ISO8601_TIME =
-        Pattern.compile("(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)(?:(\\.\\d+))?(Z)?"); //$NON-NLS-1$
-    
-    /**
-     * Handler for the SAX parser.
-     */
-    private static class GpxHandler extends DefaultHandler {
-        // --------- parsed data --------- 
-        List<WayPoint> mWayPoints;
-        List<Track> mTrackList;
-        
-        // --------- state for parsing --------- 
-        Track mCurrentTrack;
-        TrackPoint mCurrentTrackPoint;
-        WayPoint mCurrentWayPoint;
-        final StringBuilder mStringAccumulator = new StringBuilder();
-        
-        boolean mSuccess = true;
-
-        @Override
-        public void startElement(String uri, String localName, String name, Attributes attributes)
-                throws SAXException {
-            // we only care about the standard GPX nodes.
-            try {
-                if (NS_GPX.equals(uri)) {
-                    if (NODE_WAYPOINT.equals(localName)) {
-                        if (mWayPoints == null) {
-                            mWayPoints = new ArrayList<WayPoint>();
-                        }
-                        
-                        mWayPoints.add(mCurrentWayPoint = new WayPoint());
-                        handleLocation(mCurrentWayPoint, attributes);
-                    } else if (NODE_TRACK.equals(localName)) {
-                        if (mTrackList == null) {
-                            mTrackList = new ArrayList<Track>();
-                        }
-                        
-                        mTrackList.add(mCurrentTrack = new Track());
-                    } else if (NODE_TRACK_SEGMENT.equals(localName)) {
-                        // for now we do nothing here. This will merge all the segments into
-                        // a single TrackPoint list in the Track.
-                    } else if (NODE_TRACK_POINT.equals(localName)) {
-                        if (mCurrentTrack != null) {
-                            mCurrentTrack.addPoint(mCurrentTrackPoint = new TrackPoint());
-                            handleLocation(mCurrentTrackPoint, attributes);
-                        }
-                    }
-                }
-            } finally {
-                // no matter the node, we empty the StringBuilder accumulator when we start
-                // a new node.
-                mStringAccumulator.setLength(0);
-            }
-        }
-
-        /**
-         * Processes new characters for the node content. The characters are simply stored,
-         * and will be processed when {@link #endElement(String, String, String)} is called.
-         */
-        @Override
-        public void characters(char[] ch, int start, int length) throws SAXException {
-            mStringAccumulator.append(ch, start, length);
-        }
-        
-        @Override
-        public void endElement(String uri, String localName, String name) throws SAXException {
-            if (NS_GPX.equals(uri)) {
-                if (NODE_WAYPOINT.equals(localName)) {
-                    mCurrentWayPoint = null;
-                } else if (NODE_TRACK.equals(localName)) {
-                    mCurrentTrack = null;
-                } else if (NODE_TRACK_POINT.equals(localName)) {
-                    mCurrentTrackPoint = null;
-                } else if (NODE_NAME.equals(localName)) {
-                    if (mCurrentTrack != null) {
-                        mCurrentTrack.setName(mStringAccumulator.toString());
-                    } else if (mCurrentWayPoint != null) {
-                        mCurrentWayPoint.setName(mStringAccumulator.toString());
-                    }
-                } else if (NODE_TIME.equals(localName)) {
-                    if (mCurrentTrackPoint != null) {
-                        mCurrentTrackPoint.setTime(computeTime(mStringAccumulator.toString()));
-                    }
-                } else if (NODE_ELEVATION.equals(localName)) {
-                    if (mCurrentTrackPoint != null) {
-                        mCurrentTrackPoint.setElevation(
-                                Double.parseDouble(mStringAccumulator.toString()));
-                    } else if (mCurrentWayPoint != null) {
-                        mCurrentWayPoint.setElevation(
-                                Double.parseDouble(mStringAccumulator.toString()));
-                    }
-                } else if (NODE_DESCRIPTION.equals(localName)) {
-                    if (mCurrentWayPoint != null) {
-                        mCurrentWayPoint.setDescription(mStringAccumulator.toString());
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void error(SAXParseException e) throws SAXException {
-            mSuccess = false;
-        }
-
-        @Override
-        public void fatalError(SAXParseException e) throws SAXException {
-            mSuccess = false;
-        }
-        
-        /**
-         * Converts the string description of the time into milliseconds since epoch.
-         * @param timeString the string data.
-         * @return date in milliseconds.
-         */
-        private long computeTime(String timeString) {
-            // Time looks like: 2008-04-05T19:24:50Z
-            Matcher m = ISO8601_TIME.matcher(timeString);
-            if (m.matches()) {
-                // get the various elements and reconstruct time as a long.
-                try {
-                    int year = Integer.parseInt(m.group(1));
-                    int month = Integer.parseInt(m.group(2));
-                    int date = Integer.parseInt(m.group(3));
-                    int hourOfDay = Integer.parseInt(m.group(4));
-                    int minute = Integer.parseInt(m.group(5));
-                    int second = Integer.parseInt(m.group(6));
-                    
-                    // handle the optional parameters.
-                    int milliseconds = 0;
-
-                    String subSecondGroup = m.group(7);
-                    if (subSecondGroup != null) {
-                        milliseconds = (int)(1000 * Double.parseDouble(subSecondGroup));
-                    }
-                    
-                    boolean utcTime = m.group(8) != null;
-
-                    // now we convert into milliseconds since epoch.
-                    Calendar c;
-                    if (utcTime) {
-                        c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
-                    } else {
-                        c = Calendar.getInstance();
-                    }
-                    
-                    c.set(year, month, date, hourOfDay, minute, second);
-                    
-                    return c.getTimeInMillis() + milliseconds;
-                } catch (NumberFormatException e) {
-                    // format is invalid, we'll return -1 below.
-                }
-                
-            }
-
-            // invalid time!
-            return -1;
-        }
-        
-        /**
-         * Handles the location attributes and store them into a {@link LocationPoint}.
-         * @param locationNode the {@link LocationPoint} to receive the location data.
-         * @param attributes the attributes from the XML node.
-         */
-        private void handleLocation(LocationPoint locationNode, Attributes attributes) {
-            try {
-                double longitude = Double.parseDouble(attributes.getValue(ATTR_LONGITUDE));
-                double latitude = Double.parseDouble(attributes.getValue(ATTR_LATITUDE));
-                
-                locationNode.setLocation(longitude, latitude);
-            } catch (NumberFormatException e) {
-                // wrong data, do nothing.
-            }
-        }
-
-        WayPoint[] getWayPoints() {
-            if (mWayPoints != null) {
-                return mWayPoints.toArray(new WayPoint[mWayPoints.size()]);
-            }
-
-            return null;
-        }
-
-        Track[] getTracks() {
-            if (mTrackList != null) {
-                return mTrackList.toArray(new Track[mTrackList.size()]);
-            }
-
-            return null;
-        }
-        
-        boolean getSuccess() {
-            return mSuccess;
-        }
-    }
-
-    /**
-     * A GPS track.
-     * <p/>A track is composed of a list of {@link TrackPoint} and optional name and comment.
-     */
-    public final static class Track {
-        private String mName;
-        private String mComment;
-        private List<TrackPoint> mPoints = new ArrayList<TrackPoint>();
-
-        void setName(String name) {
-            mName = name;
-        }
-        
-        public String getName() {
-            return mName;
-        }
-        
-        void setComment(String comment) {
-            mComment = comment;
-        }
-        
-        public String getComment() {
-            return mComment;
-        }
-        
-        void addPoint(TrackPoint trackPoint) {
-            mPoints.add(trackPoint);
-        }
-        
-        public TrackPoint[] getPoints() {
-            return mPoints.toArray(new TrackPoint[mPoints.size()]);
-        }
-        
-        public long getFirstPointTime() {
-            if (mPoints.size() > 0) {
-                return mPoints.get(0).getTime();
-            }
-            
-            return -1;
-        }
-
-        public long getLastPointTime() {
-            if (mPoints.size() > 0) {
-                return mPoints.get(mPoints.size()-1).getTime();
-            }
-            
-            return -1;
-        }
-        
-        public int getPointCount() {
-            return mPoints.size();
-        }
-    }
-    
-    /**
-     * Creates a new GPX parser for a file specified by its full path.
-     * @param fileName The full path of the GPX file to parse.
-     */
-    public GpxParser(String fileName) {
-        mFileName = fileName;
-    }
-
-    /**
-     * Parses the GPX file.
-     * @return <code>true</code> if success.
-     */
-    public boolean parse() {
-        try {
-            SAXParser parser = sParserFactory.newSAXParser();
-
-            mHandler = new GpxHandler();
-
-            parser.parse(new InputSource(new FileReader(mFileName)), mHandler);
-            
-            return mHandler.getSuccess();
-        } catch (ParserConfigurationException e) {
-        } catch (SAXException e) {
-        } catch (IOException e) {
-        } finally {
-        }
-
-        return false;
-    }
-    
-    /**
-     * Returns the parsed {@link WayPoint} objects, or <code>null</code> if none were found (or
-     * if the parsing failed.
-     */
-    public WayPoint[] getWayPoints() {
-        if (mHandler != null) {
-            return mHandler.getWayPoints();
-        }
-        
-        return null;
-    }
-    
-    /**
-     * Returns the parsed {@link Track} objects, or <code>null</code> if none were found (or
-     * if the parsing failed.
-     */
-    public Track[] getTracks() {
-        if (mHandler != null) {
-            return mHandler.getTracks();
-        }
-        
-        return null;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java
deleted file mode 100644
index af485ac..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * A very basic KML parser to meet the need of the emulator control panel.
- * <p/>
- * It parses basic Placemark information.
- */
-public class KmlParser {
-    
-    private final static String NS_KML_2 = "http://earth.google.com/kml/2.";  //$NON-NLS-1$
-        
-    private final static String NODE_PLACEMARK = "Placemark"; //$NON-NLS-1$
-    private final static String NODE_NAME = "name"; //$NON-NLS-1$
-    private final static String NODE_COORDINATES = "coordinates"; //$NON-NLS-1$
-    
-    private final static Pattern sLocationPattern = Pattern.compile("([^,]+),([^,]+)(?:,([^,]+))?");
-    
-    private static SAXParserFactory sParserFactory;
-    
-    static {
-        sParserFactory = SAXParserFactory.newInstance();
-        sParserFactory.setNamespaceAware(true);
-    }
-
-    private String mFileName;
-
-    private KmlHandler mHandler;
-    
-    /**
-     * Handler for the SAX parser.
-     */
-    private static class KmlHandler extends DefaultHandler {
-        // --------- parsed data --------- 
-        List<WayPoint> mWayPoints;
-        
-        // --------- state for parsing --------- 
-        WayPoint mCurrentWayPoint;
-        final StringBuilder mStringAccumulator = new StringBuilder();
-
-        boolean mSuccess = true;
-
-        @Override
-        public void startElement(String uri, String localName, String name, Attributes attributes)
-                throws SAXException {
-            // we only care about the standard GPX nodes.
-            try {
-                if (uri.startsWith(NS_KML_2)) {
-                    if (NODE_PLACEMARK.equals(localName)) {
-                        if (mWayPoints == null) {
-                            mWayPoints = new ArrayList<WayPoint>();
-                        }
-                        
-                        mWayPoints.add(mCurrentWayPoint = new WayPoint());
-                    }
-                }
-            } finally {
-                // no matter the node, we empty the StringBuilder accumulator when we start
-                // a new node.
-                mStringAccumulator.setLength(0);
-            }
-        }
-
-        /**
-         * Processes new characters for the node content. The characters are simply stored,
-         * and will be processed when {@link #endElement(String, String, String)} is called.
-         */
-        @Override
-        public void characters(char[] ch, int start, int length) throws SAXException {
-            mStringAccumulator.append(ch, start, length);
-        }
-        
-        @Override
-        public void endElement(String uri, String localName, String name) throws SAXException {
-            if (uri.startsWith(NS_KML_2)) {
-                if (NODE_PLACEMARK.equals(localName)) {
-                    mCurrentWayPoint = null;
-                } else if (NODE_NAME.equals(localName)) {
-                    if (mCurrentWayPoint != null) {
-                        mCurrentWayPoint.setName(mStringAccumulator.toString());
-                    }
-                } else if (NODE_COORDINATES.equals(localName)) {
-                    if (mCurrentWayPoint != null) {
-                        parseLocation(mCurrentWayPoint, mStringAccumulator.toString());
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void error(SAXParseException e) throws SAXException {
-            mSuccess = false;
-        }
-
-        @Override
-        public void fatalError(SAXParseException e) throws SAXException {
-            mSuccess = false;
-        }
-        
-        /**
-         * Parses the location string and store the information into a {@link LocationPoint}.
-         * @param locationNode the {@link LocationPoint} to receive the location data.
-         * @param location The string containing the location info.
-         */
-        private void parseLocation(LocationPoint locationNode, String location) {
-            Matcher m = sLocationPattern.matcher(location);
-            if (m.matches()) {
-                try {
-                    double longitude = Double.parseDouble(m.group(1));
-                    double latitude = Double.parseDouble(m.group(2));
-                    
-                    locationNode.setLocation(longitude, latitude);
-                    
-                    if (m.groupCount() == 3) {
-                        // looks like we have elevation data.
-                        locationNode.setElevation(Double.parseDouble(m.group(3)));
-                    }
-                } catch (NumberFormatException e) {
-                    // wrong data, do nothing.
-                }
-            }
-        }
-        
-        WayPoint[] getWayPoints() {
-            if (mWayPoints != null) {
-                return mWayPoints.toArray(new WayPoint[mWayPoints.size()]);
-            }
-
-            return null;
-        }
-
-        boolean getSuccess() {
-            return mSuccess;
-        }
-    }
-
-    /**
-     * Creates a new GPX parser for a file specified by its full path.
-     * @param fileName The full path of the GPX file to parse.
-     */
-    public KmlParser(String fileName) {
-        mFileName = fileName;
-    }
-
-    /**
-     * Parses the GPX file.
-     * @return <code>true</code> if success.
-     */
-    public boolean parse() {
-        try {
-            SAXParser parser = sParserFactory.newSAXParser();
-
-            mHandler = new KmlHandler();
-
-            parser.parse(new InputSource(new FileReader(mFileName)), mHandler);
-            
-            return mHandler.getSuccess();
-        } catch (ParserConfigurationException e) {
-        } catch (SAXException e) {
-        } catch (IOException e) {
-        } finally {
-        }
-
-        return false;
-    }
-    
-    /**
-     * Returns the parsed {@link WayPoint} objects, or <code>null</code> if none were found (or
-     * if the parsing failed.
-     */
-    public WayPoint[] getWayPoints() {
-        if (mHandler != null) {
-            return mHandler.getWayPoints();
-        }
-        
-        return null;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/LocationPoint.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/LocationPoint.java
deleted file mode 100644
index dbb8f41..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/LocationPoint.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-/**
- * Base class for Location aware points.
- */
-class LocationPoint {
-    private double mLongitude;
-    private double mLatitude;
-    private boolean mHasElevation = false;
-    private double mElevation;
-
-    final void setLocation(double longitude, double latitude) {
-        mLongitude = longitude;
-        mLatitude = latitude;
-    }
-    
-    public final double getLongitude() {
-        return mLongitude;
-    }
-    
-    public final double getLatitude() {
-        return mLatitude;
-    }
-
-    final void setElevation(double elevation) {
-        mElevation = elevation;
-        mHasElevation = true;
-    }
-    
-    public final boolean hasElevation() {
-        return mHasElevation;
-    }
-    
-    public final double getElevation() {
-        return mElevation;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackContentProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackContentProvider.java
deleted file mode 100644
index 7fb37ce..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackContentProvider.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-import com.android.ddmuilib.location.GpxParser.Track;
-
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Content provider to display {@link Track} objects in a Table.
- * <p/>The expected type for the input is {@link Track}<code>[]</code>. 
- */
-public class TrackContentProvider implements IStructuredContentProvider {
-
-    public Object[] getElements(Object inputElement) {
-        if (inputElement instanceof Track[]) {
-            return (Track[])inputElement;
-        }
-
-        return new Object[0];
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-        // pass
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackLabelProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackLabelProvider.java
deleted file mode 100644
index 81d1f7d..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackLabelProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-import com.android.ddmuilib.location.GpxParser.Track;
-
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Table;
-
-import java.util.Date;
-
-/**
- * Label Provider for {@link Table} objects displaying {@link Track} objects.
- */
-public class TrackLabelProvider implements ITableLabelProvider {
-
-    public Image getColumnImage(Object element, int columnIndex) {
-        return null;
-    }
-
-    public String getColumnText(Object element, int columnIndex) {
-        if (element instanceof Track) {
-            Track track = (Track)element;
-            switch (columnIndex) {
-                case 0:
-                    return track.getName();
-                case 1:
-                    return Integer.toString(track.getPointCount());
-                case 2:
-                    long time = track.getFirstPointTime();
-                    if (time != -1) {
-                        return new Date(time).toString();
-                    }
-                    break;
-                case 3:
-                    time = track.getLastPointTime();
-                    if (time != -1) {
-                        return new Date(time).toString();
-                    }
-                    break;
-                case 4:
-                    return track.getComment();
-            }
-        }
-
-        return null;
-    }
-
-    public void addListener(ILabelProviderListener listener) {
-        // pass
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-    public boolean isLabelProperty(Object element, String property) {
-        // pass
-        return false;
-    }
-
-    public void removeListener(ILabelProviderListener listener) {
-        // pass
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackPoint.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackPoint.java
deleted file mode 100644
index 527f4bf..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackPoint.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-
-/**
- * A Track Point.
- * <p/>A track point is a point in time and space.
- */
-public class TrackPoint extends LocationPoint {
-    private long mTime;
-
-    void setTime(long time) {
-        mTime = time;
-    }
-    
-    public long getTime() {
-        return mTime;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPoint.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPoint.java
deleted file mode 100644
index 32880bd..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPoint.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-/**
- * A GPS/KML way point.
- * <p/>A waypoint is a user specified location, with a name and an optional description.
- */
-public final class WayPoint extends LocationPoint {
-    private String mName;
-    private String mDescription;
-
-    void setName(String name) {
-        mName = name;
-    }
-    
-    public String getName() {
-        return mName;
-    }
-
-    void setDescription(String description) {
-        mDescription = description;
-    }
-
-    public String getDescription() {
-        return mDescription;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointContentProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointContentProvider.java
deleted file mode 100644
index fced777..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointContentProvider.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Content provider to display {@link WayPoint} objects in a Table.
- * <p/>The expected type for the input is {@link WayPoint}<code>[]</code>. 
- */
-public class WayPointContentProvider implements IStructuredContentProvider {
-
-    public Object[] getElements(Object inputElement) {
-        if (inputElement instanceof WayPoint[]) {
-            return (WayPoint[])inputElement;
-        }
-
-        return new Object[0];
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-        // pass
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointLabelProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointLabelProvider.java
deleted file mode 100644
index f5e6f1b..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointLabelProvider.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.android.ddmuilib.location;
-
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Table;
-
-/**
- * Label Provider for {@link Table} objects displaying {@link WayPoint} objects.
- */
-public class WayPointLabelProvider implements ITableLabelProvider {
-
-    public Image getColumnImage(Object element, int columnIndex) {
-        return null;
-    }
-
-    public String getColumnText(Object element, int columnIndex) {
-        if (element instanceof WayPoint) {
-            WayPoint wayPoint = (WayPoint)element;
-            switch (columnIndex) {
-                case 0:
-                    return wayPoint.getName();
-                case 1:
-                    return String.format("%.6f", wayPoint.getLongitude());
-                case 2:
-                    return String.format("%.6f", wayPoint.getLatitude());
-                case 3:
-                    if (wayPoint.hasElevation()) {
-                        return String.format("%.1f", wayPoint.getElevation());
-                    } else {
-                        return "-";
-                    }
-                case 4:
-                    return wayPoint.getDescription();
-            }
-        }
-
-        return null;
-    }
-
-    public void addListener(ILabelProviderListener listener) {
-        // pass
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-    public boolean isLabelProperty(Object element, String property) {
-        // pass
-        return false;
-    }
-
-    public void removeListener(ILabelProviderListener listener) {
-        // pass
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/BugReportImporter.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/BugReportImporter.java
deleted file mode 100644
index 9de1ac7..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/BugReportImporter.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-
-public class BugReportImporter {
-    
-    private final static String TAG_HEADER = "------ EVENT LOG TAGS ------";
-    private final static String LOG_HEADER = "------ EVENT LOG ------";
-    private final static String HEADER_TAG = "------";
-    
-    private String[] mTags;
-    private String[] mLog;
-    
-    public BugReportImporter(String filePath) throws FileNotFoundException {
-        BufferedReader reader = new BufferedReader(
-                new InputStreamReader(new FileInputStream(filePath)));
-
-        try {
-            String line;
-            while ((line = reader.readLine()) != null) {
-                if (TAG_HEADER.equals(line)) {
-                    readTags(reader);
-                    return;
-                }
-            }
-        } catch (IOException e) {
-        }
-    }
-    
-    public String[] getTags() {
-        return mTags;
-    }
-    
-    public String[] getLog() {
-        return mLog;
-    }
-
-    private void readTags(BufferedReader reader) throws IOException {
-        String line;
-        
-        ArrayList<String> content = new ArrayList<String>();
-        while ((line = reader.readLine()) != null) {
-            if (LOG_HEADER.equals(line)) {
-                mTags = content.toArray(new String[content.size()]);
-                readLog(reader);
-                return;
-            } else {
-                content.add(line);
-            }
-        }
-    }
-
-    private void readLog(BufferedReader reader) throws IOException {
-        String line;
-
-        ArrayList<String> content = new ArrayList<String>();
-        while ((line = reader.readLine()) != null) {
-            if (line.startsWith(HEADER_TAG) == false) {
-                content.add(line);
-            } else {
-                break;
-            }
-        }
-        
-        mLog = content.toArray(new String[content.size()]);
-    }
-    
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayFilteredLog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayFilteredLog.java
deleted file mode 100644
index 473387a..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayFilteredLog.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-
-import java.util.ArrayList;
-
-public class DisplayFilteredLog extends DisplayLog {
-
-    public DisplayFilteredLog(String name) {
-        super(name);
-    }
-
-    /**
-     * Adds event to the display.
-     */
-    @Override
-    void newEvent(EventContainer event, EventLogParser logParser) {
-        ArrayList<ValueDisplayDescriptor> valueDescriptors =
-                new ArrayList<ValueDisplayDescriptor>();
-
-        ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors =
-                new ArrayList<OccurrenceDisplayDescriptor>();
-
-        if (filterEvent(event, valueDescriptors, occurrenceDescriptors)) {
-            addToLog(event, logParser, valueDescriptors, occurrenceDescriptors);
-        }
-    }
-
-    /**
-     * Gets display type
-     *
-     * @return display type as an integer
-     */
-    @Override
-    int getDisplayType() {
-        return DISPLAY_TYPE_FILTERED_LOG;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayGraph.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayGraph.java
deleted file mode 100644
index 0cffd7e..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayGraph.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.EventValueDescription;
-import com.android.ddmlib.log.InvalidTypeException;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.jfree.chart.axis.AxisLocation;
-import org.jfree.chart.axis.NumberAxis;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
-import org.jfree.chart.renderer.xy.XYAreaRenderer;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
-import org.jfree.data.time.Millisecond;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-public class DisplayGraph extends EventDisplay {
-
-    public DisplayGraph(String name) {
-        super(name);
-    }
-
-    /**
-     * Resets the display.
-     */
-    @Override
-    void resetUI() {
-        Collection<TimeSeriesCollection> datasets = mValueTypeDataSetMap.values();
-        for (TimeSeriesCollection dataset : datasets) {
-            dataset.removeAllSeries();
-        }
-        if (mOccurrenceDataSet != null) {
-            mOccurrenceDataSet.removeAllSeries();
-        }
-        mValueDescriptorSeriesMap.clear();
-        mOcurrenceDescriptorSeriesMap.clear();
-    }
-
-    /**
-     * Creates the UI for the event display.
-     * @param parent the parent composite.
-     * @param logParser the current log parser.
-     * @return the created control (which may have children).
-     */
-    @Override
-    public Control createComposite(final Composite parent, EventLogParser logParser,
-            final ILogColumnListener listener) {
-        String title = getChartTitle(logParser);
-        return createCompositeChart(parent, logParser, title);
-    }
-
-    /**
-     * Adds event to the display.
-     */
-    @Override
-    void newEvent(EventContainer event, EventLogParser logParser) {
-        ArrayList<ValueDisplayDescriptor> valueDescriptors =
-                new ArrayList<ValueDisplayDescriptor>();
-
-        ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors =
-                new ArrayList<OccurrenceDisplayDescriptor>();
-
-        if (filterEvent(event, valueDescriptors, occurrenceDescriptors)) {
-            updateChart(event, logParser, valueDescriptors, occurrenceDescriptors);
-        }
-    }
-
-     /**
-     * Updates the chart with the {@link EventContainer} by adding the values/occurrences defined
-     * by the {@link ValueDisplayDescriptor} and {@link OccurrenceDisplayDescriptor} objects from
-     * the two lists.
-     * <p/>This method is only called when at least one of the descriptor list is non empty.
-     * @param event
-     * @param logParser
-     * @param valueDescriptors
-     * @param occurrenceDescriptors
-     */
-    private void updateChart(EventContainer event, EventLogParser logParser,
-            ArrayList<ValueDisplayDescriptor> valueDescriptors,
-            ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
-        Map<Integer, String> tagMap = logParser.getTagMap();
-
-        Millisecond millisecondTime = null;
-        long msec = -1;
-
-        // If the event container is a cpu container (tag == 2721), and there is no descriptor
-        // for the total CPU load, then we do accumulate all the values.
-        boolean accumulateValues = false;
-        double accumulatedValue = 0;
-
-        if (event.mTag == 2721) {
-            accumulateValues = true;
-            for (ValueDisplayDescriptor descriptor : valueDescriptors) {
-                accumulateValues &= (descriptor.valueIndex != 0);
-            }
-        }
-
-        for (ValueDisplayDescriptor descriptor : valueDescriptors) {
-            try {
-                // get the hashmap for this descriptor
-                HashMap<Integer, TimeSeries> map = mValueDescriptorSeriesMap.get(descriptor);
-
-                // if it's not there yet, we create it.
-                if (map == null) {
-                    map = new HashMap<Integer, TimeSeries>();
-                    mValueDescriptorSeriesMap.put(descriptor, map);
-                }
-
-                // get the TimeSeries for this pid
-                TimeSeries timeSeries = map.get(event.pid);
-
-                // if it doesn't exist yet, we create it
-                if (timeSeries == null) {
-                    // get the series name
-                    String seriesFullName = null;
-                    String seriesLabel = getSeriesLabel(event, descriptor);
-
-                    switch (mValueDescriptorCheck) {
-                        case EVENT_CHECK_SAME_TAG:
-                            seriesFullName = String.format("%1$s / %2$s", seriesLabel,
-                                    descriptor.valueName);
-                            break;
-                        case EVENT_CHECK_SAME_VALUE:
-                            seriesFullName = String.format("%1$s", seriesLabel);
-                            break;
-                        default:
-                            seriesFullName = String.format("%1$s / %2$s: %3$s", seriesLabel,
-                                    tagMap.get(descriptor.eventTag),
-                                    descriptor.valueName);
-                            break;
-                    }
-
-                    // get the data set for this ValueType
-                    TimeSeriesCollection dataset = getValueDataset(
-                            logParser.getEventInfoMap().get(event.mTag)[descriptor.valueIndex]
-                                                                        .getValueType(),
-                            accumulateValues);
-
-                    // create the series
-                    timeSeries = new TimeSeries(seriesFullName, Millisecond.class);
-                    if (mMaximumChartItemAge != -1) {
-                        timeSeries.setMaximumItemAge(mMaximumChartItemAge * 1000);
-                    }
-
-                    dataset.addSeries(timeSeries);
-
-                    // add it to the map.
-                    map.put(event.pid, timeSeries);
-                }
-
-                // update the timeSeries.
-
-                // get the value from the event
-                double value = event.getValueAsDouble(descriptor.valueIndex);
-
-                // accumulate the values if needed.
-                if (accumulateValues) {
-                    accumulatedValue += value;
-                    value = accumulatedValue;
-                }
-
-                // get the time
-                if (millisecondTime == null) {
-                    msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
-                    millisecondTime = new Millisecond(new Date(msec));
-                }
-
-                // add the value to the time series
-                timeSeries.addOrUpdate(millisecondTime, value);
-            } catch (InvalidTypeException e) {
-                // just ignore this descriptor if there's a type mismatch
-            }
-        }
-
-        for (OccurrenceDisplayDescriptor descriptor : occurrenceDescriptors) {
-            try {
-                // get the hashmap for this descriptor
-                HashMap<Integer, TimeSeries> map = mOcurrenceDescriptorSeriesMap.get(descriptor);
-
-                // if it's not there yet, we create it.
-                if (map == null) {
-                    map = new HashMap<Integer, TimeSeries>();
-                    mOcurrenceDescriptorSeriesMap.put(descriptor, map);
-                }
-
-                // get the TimeSeries for this pid
-                TimeSeries timeSeries = map.get(event.pid);
-
-                // if it doesn't exist yet, we create it.
-                if (timeSeries == null) {
-                    String seriesLabel = getSeriesLabel(event, descriptor);
-
-                    String seriesFullName = String.format("[%1$s:%2$s]",
-                            tagMap.get(descriptor.eventTag), seriesLabel);
-
-                    timeSeries = new TimeSeries(seriesFullName, Millisecond.class);
-                    if (mMaximumChartItemAge != -1) {
-                        timeSeries.setMaximumItemAge(mMaximumChartItemAge);
-                    }
-
-                    getOccurrenceDataSet().addSeries(timeSeries);
-
-                    map.put(event.pid, timeSeries);
-                }
-
-                // update the series
-
-                // get the time
-                if (millisecondTime == null) {
-                    msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
-                    millisecondTime = new Millisecond(new Date(msec));
-                }
-
-                // add the value to the time series
-                timeSeries.addOrUpdate(millisecondTime, 0); // the value is unused
-            } catch (InvalidTypeException e) {
-                // just ignore this descriptor if there's a type mismatch
-            }
-        }
-
-        // go through all the series and remove old values.
-        if (msec != -1 && mMaximumChartItemAge != -1) {
-            Collection<HashMap<Integer, TimeSeries>> pidMapValues =
-                mValueDescriptorSeriesMap.values();
-
-            for (HashMap<Integer, TimeSeries> pidMapValue : pidMapValues) {
-                Collection<TimeSeries> seriesCollection = pidMapValue.values();
-
-                for (TimeSeries timeSeries : seriesCollection) {
-                    timeSeries.removeAgedItems(msec, true);
-                }
-            }
-
-            pidMapValues = mOcurrenceDescriptorSeriesMap.values();
-            for (HashMap<Integer, TimeSeries> pidMapValue : pidMapValues) {
-                Collection<TimeSeries> seriesCollection = pidMapValue.values();
-
-                for (TimeSeries timeSeries : seriesCollection) {
-                    timeSeries.removeAgedItems(msec, true);
-                }
-            }
-        }
-    }
-
-       /**
-     * Returns a {@link TimeSeriesCollection} for a specific {@link com.android.ddmlib.log.EventValueDescription.ValueType}.
-     * If the data set is not yet created, it is first allocated and set up into the
-     * {@link org.jfree.chart.JFreeChart} object.
-     * @param type the {@link com.android.ddmlib.log.EventValueDescription.ValueType} of the data set.
-     * @param accumulateValues
-     */
-    private TimeSeriesCollection getValueDataset(EventValueDescription.ValueType type, boolean accumulateValues) {
-        TimeSeriesCollection dataset = mValueTypeDataSetMap.get(type);
-        if (dataset == null) {
-            // create the data set and store it in the map
-            dataset = new TimeSeriesCollection();
-            mValueTypeDataSetMap.put(type, dataset);
-
-            // create the renderer and configure it depending on the ValueType
-            AbstractXYItemRenderer renderer;
-            if (type == EventValueDescription.ValueType.PERCENT && accumulateValues) {
-                renderer = new XYAreaRenderer();
-            } else {
-                XYLineAndShapeRenderer r = new XYLineAndShapeRenderer();
-                r.setBaseShapesVisible(type != EventValueDescription.ValueType.PERCENT);
-
-                renderer = r;
-            }
-
-            // set both the dataset and the renderer in the plot object.
-            XYPlot xyPlot = mChart.getXYPlot();
-            xyPlot.setDataset(mDataSetCount, dataset);
-            xyPlot.setRenderer(mDataSetCount, renderer);
-
-            // put a new axis label, and configure it.
-            NumberAxis axis = new NumberAxis(type.toString());
-
-            if (type == EventValueDescription.ValueType.PERCENT) {
-                // force percent range to be (0,100) fixed.
-                axis.setAutoRange(false);
-                axis.setRange(0., 100.);
-            }
-
-            // for the index, we ignore the occurrence dataset
-            int count = mDataSetCount;
-            if (mOccurrenceDataSet != null) {
-                count--;
-            }
-
-            xyPlot.setRangeAxis(count, axis);
-            if ((count % 2) == 0) {
-                xyPlot.setRangeAxisLocation(count, AxisLocation.BOTTOM_OR_LEFT);
-            } else {
-                xyPlot.setRangeAxisLocation(count, AxisLocation.TOP_OR_RIGHT);
-            }
-
-            // now we link the dataset and the axis
-            xyPlot.mapDatasetToRangeAxis(mDataSetCount, count);
-
-            mDataSetCount++;
-        }
-
-        return dataset;
-    }
-
-    /**
-     * Return the series label for this event. This only contains the pid information.
-     * @param event the {@link EventContainer}
-     * @param descriptor the {@link OccurrenceDisplayDescriptor}
-     * @return the series label.
-     * @throws InvalidTypeException
-     */
-    private String getSeriesLabel(EventContainer event, OccurrenceDisplayDescriptor descriptor)
-            throws InvalidTypeException {
-        if (descriptor.seriesValueIndex != -1) {
-            if (descriptor.includePid == false) {
-                return event.getValueAsString(descriptor.seriesValueIndex);
-            } else {
-                return String.format("%1$s (%2$d)",
-                        event.getValueAsString(descriptor.seriesValueIndex), event.pid);
-            }
-        }
-
-        return Integer.toString(event.pid);
-    }
-
-    /**
-     * Returns the {@link TimeSeriesCollection} for the occurrence display. If the data set is not
-     * yet created, it is first allocated and set up into the {@link org.jfree.chart.JFreeChart} object.
-     */
-    private TimeSeriesCollection getOccurrenceDataSet() {
-        if (mOccurrenceDataSet == null) {
-            mOccurrenceDataSet = new TimeSeriesCollection();
-
-            XYPlot xyPlot = mChart.getXYPlot();
-            xyPlot.setDataset(mDataSetCount, mOccurrenceDataSet);
-
-            OccurrenceRenderer renderer = new OccurrenceRenderer();
-            renderer.setBaseShapesVisible(false);
-            xyPlot.setRenderer(mDataSetCount, renderer);
-
-            mDataSetCount++;
-        }
-
-        return mOccurrenceDataSet;
-    }
-
-    /**
-     * Gets display type
-     *
-     * @return display type as an integer
-     */
-    @Override
-    int getDisplayType() {
-        return DISPLAY_TYPE_GRAPH;
-    }
-
-    /**
-     * Sets the current {@link EventLogParser} object.
-     */
-    @Override
-    protected void setNewLogParser(EventLogParser logParser) {
-        if (mChart != null) {
-            mChart.setTitle(getChartTitle(logParser));
-        }
-    }
-    /**
-     * Returns a meaningful chart title based on the value of {@link #mValueDescriptorCheck}.
-     *
-     * @param logParser the logParser.
-     * @return the chart title.
-     */
-    private String getChartTitle(EventLogParser logParser) {
-        if (mValueDescriptors.size() > 0) {
-            String chartDesc = null;
-            switch (mValueDescriptorCheck) {
-                case EVENT_CHECK_SAME_TAG:
-                    if (logParser != null) {
-                        chartDesc = logParser.getTagMap().get(mValueDescriptors.get(0).eventTag);
-                    }
-                    break;
-                case EVENT_CHECK_SAME_VALUE:
-                    if (logParser != null) {
-                        chartDesc = String.format("%1$s / %2$s",
-                                logParser.getTagMap().get(mValueDescriptors.get(0).eventTag),
-                                mValueDescriptors.get(0).valueName);
-                    }
-                    break;
-            }
-
-            if (chartDesc != null) {
-                return String.format("%1$s - %2$s", mName, chartDesc);
-            }
-        }
-
-        return mName;
-    }
-}
\ No newline at end of file
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayLog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayLog.java
deleted file mode 100644
index 26296f3..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayLog.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.EventValueDescription;
-import com.android.ddmlib.log.InvalidTypeException;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.TableHelper;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.ScrollBar;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-
-public class DisplayLog extends EventDisplay {
-    public DisplayLog(String name) {
-        super(name);
-    }
-
-    private final static String PREFS_COL_DATE = "EventLogPanel.log.Col1"; //$NON-NLS-1$
-    private final static String PREFS_COL_PID = "EventLogPanel.log.Col2"; //$NON-NLS-1$
-    private final static String PREFS_COL_EVENTTAG = "EventLogPanel.log.Col3"; //$NON-NLS-1$
-    private final static String PREFS_COL_VALUENAME = "EventLogPanel.log.Col4"; //$NON-NLS-1$
-    private final static String PREFS_COL_VALUE = "EventLogPanel.log.Col5"; //$NON-NLS-1$
-    private final static String PREFS_COL_TYPE = "EventLogPanel.log.Col6"; //$NON-NLS-1$
-
-    /**
-     * Resets the display.
-     */
-    @Override
-    void resetUI() {
-        mLogTable.removeAll();
-    }
-
-    /**
-     * Adds event to the display.
-     */
-    @Override
-    void newEvent(EventContainer event, EventLogParser logParser) {
-        addToLog(event, logParser);
-    }
-
-    /**
-     * Creates the UI for the event display.
-     *
-     * @param parent    the parent composite.
-     * @param logParser the current log parser.
-     * @return the created control (which may have children).
-     */
-    @Override
-    Control createComposite(Composite parent, EventLogParser logParser, ILogColumnListener listener) {
-        return createLogUI(parent, listener);
-    }
-
-    /**
-     * Adds an {@link EventContainer} to the log.
-     *
-     * @param event     the event.
-     * @param logParser the log parser.
-     */
-    private void addToLog(EventContainer event, EventLogParser logParser) {
-        ScrollBar bar = mLogTable.getVerticalBar();
-        boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
-
-        // get the date.
-        Calendar c = Calendar.getInstance();
-        long msec = (long) event.sec * 1000L;
-        c.setTimeInMillis(msec);
-
-        // convert the time into a string
-        String date = String.format("%1$tF %1$tT", c);
-
-        String eventName = logParser.getTagMap().get(event.mTag);
-        String pidName = Integer.toString(event.pid);
-
-        // get the value description
-        EventValueDescription[] valueDescription = logParser.getEventInfoMap().get(event.mTag);
-        if (valueDescription != null) {
-            for (int i = 0; i < valueDescription.length; i++) {
-                EventValueDescription description = valueDescription[i];
-                try {
-                    String value = event.getValueAsString(i);
-
-                    logValue(date, pidName, eventName, description.getName(), value,
-                            description.getEventValueType(), description.getValueType());
-                } catch (InvalidTypeException e) {
-                    logValue(date, pidName, eventName, description.getName(), e.getMessage(),
-                            description.getEventValueType(), description.getValueType());
-                }
-            }
-
-            // scroll if needed, by showing the last item
-            if (scroll) {
-                int itemCount = mLogTable.getItemCount();
-                if (itemCount > 0) {
-                    mLogTable.showItem(mLogTable.getItem(itemCount - 1));
-                }
-            }
-        }
-    }
-
-    /**
-     * Adds an {@link EventContainer} to the log. Only add the values/occurrences defined by
-     * the list of descriptors. If an event is configured to be displayed by value and occurrence,
-     * only the values are displayed (as they mark an event occurrence anyway).
-     * <p/>This method is only called when at least one of the descriptor list is non empty.
-     *
-     * @param event
-     * @param logParser
-     * @param valueDescriptors
-     * @param occurrenceDescriptors
-     */
-    protected void addToLog(EventContainer event, EventLogParser logParser,
-            ArrayList<ValueDisplayDescriptor> valueDescriptors,
-            ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
-        ScrollBar bar = mLogTable.getVerticalBar();
-        boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
-
-        // get the date.
-        Calendar c = Calendar.getInstance();
-        long msec = (long) event.sec * 1000L;
-        c.setTimeInMillis(msec);
-
-        // convert the time into a string
-        String date = String.format("%1$tF %1$tT", c);
-
-        String eventName = logParser.getTagMap().get(event.mTag);
-        String pidName = Integer.toString(event.pid);
-
-        if (valueDescriptors.size() > 0) {
-            for (ValueDisplayDescriptor descriptor : valueDescriptors) {
-                logDescriptor(event, descriptor, date, pidName, eventName, logParser);
-            }
-        } else {
-            // we display the event. Since the StringBuilder contains the header (date, event name,
-            // pid) at this point, there isn't anything else to display.
-        }
-
-        // scroll if needed, by showing the last item
-        if (scroll) {
-            int itemCount = mLogTable.getItemCount();
-            if (itemCount > 0) {
-                mLogTable.showItem(mLogTable.getItem(itemCount - 1));
-            }
-        }
-    }
-
-
-    /**
-     * Logs a value in the ui.
-     *
-     * @param date
-     * @param pid
-     * @param event
-     * @param valueName
-     * @param value
-     * @param eventValueType
-     * @param valueType
-     */
-    private void logValue(String date, String pid, String event, String valueName,
-            String value, EventContainer.EventValueType eventValueType, EventValueDescription.ValueType valueType) {
-
-        TableItem item = new TableItem(mLogTable, SWT.NONE);
-        item.setText(0, date);
-        item.setText(1, pid);
-        item.setText(2, event);
-        item.setText(3, valueName);
-        item.setText(4, value);
-
-        String type;
-        if (valueType != EventValueDescription.ValueType.NOT_APPLICABLE) {
-            type = String.format("%1$s, %2$s", eventValueType.toString(), valueType.toString());
-        } else {
-            type = eventValueType.toString();
-        }
-
-        item.setText(5, type);
-    }
-
-    /**
-     * Logs a value from an {@link EventContainer} as defined by the {@link ValueDisplayDescriptor}.
-     *
-     * @param event      the EventContainer
-     * @param descriptor the ValueDisplayDescriptor defining which value to display.
-     * @param date       the date of the event in a string.
-     * @param pidName
-     * @param eventName
-     * @param logParser
-     */
-    private void logDescriptor(EventContainer event, ValueDisplayDescriptor descriptor,
-            String date, String pidName, String eventName, EventLogParser logParser) {
-
-        String value;
-        try {
-            value = event.getValueAsString(descriptor.valueIndex);
-        } catch (InvalidTypeException e) {
-            value = e.getMessage();
-        }
-
-        EventValueDescription[] values = logParser.getEventInfoMap().get(event.mTag);
-
-        EventValueDescription valueDescription = values[descriptor.valueIndex];
-
-        logValue(date, pidName, eventName, descriptor.valueName, value,
-                valueDescription.getEventValueType(), valueDescription.getValueType());
-    }
-
-    /**
-     * Creates the UI for a log display.
-     *
-     * @param parent   the parent {@link Composite}
-     * @param listener the {@link ILogColumnListener} to notify on column resize events.
-     * @return the top Composite of the UI.
-     */
-    private Control createLogUI(Composite parent, final ILogColumnListener listener) {
-        Composite mainComp = new Composite(parent, SWT.NONE);
-        GridLayout gl;
-        mainComp.setLayout(gl = new GridLayout(1, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        mainComp.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                mLogTable = null;
-            }
-        });
-
-        Label l = new Label(mainComp, SWT.CENTER);
-        l.setText(mName);
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mLogTable = new Table(mainComp, SWT.MULTI | SWT.FULL_SELECTION | SWT.V_SCROLL |
-                SWT.BORDER);
-        mLogTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        IPreferenceStore store = DdmUiPreferences.getStore();
-
-        TableColumn col = TableHelper.createTableColumn(
-                mLogTable, "Time",
-                SWT.LEFT, "0000-00-00 00:00:00", PREFS_COL_DATE, store); //$NON-NLS-1$
-        col.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Object source = e.getSource();
-                if (source instanceof TableColumn) {
-                    listener.columnResized(0, (TableColumn) source);
-                }
-            }
-        });
-
-        col = TableHelper.createTableColumn(
-                mLogTable, "pid",
-                SWT.LEFT, "0000", PREFS_COL_PID, store); //$NON-NLS-1$
-        col.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Object source = e.getSource();
-                if (source instanceof TableColumn) {
-                    listener.columnResized(1, (TableColumn) source);
-                }
-            }
-        });
-
-        col = TableHelper.createTableColumn(
-                mLogTable, "Event",
-                SWT.LEFT, "abcdejghijklmno", PREFS_COL_EVENTTAG, store); //$NON-NLS-1$
-        col.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Object source = e.getSource();
-                if (source instanceof TableColumn) {
-                    listener.columnResized(2, (TableColumn) source);
-                }
-            }
-        });
-
-        col = TableHelper.createTableColumn(
-                mLogTable, "Name",
-                SWT.LEFT, "Process Name", PREFS_COL_VALUENAME, store); //$NON-NLS-1$
-        col.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Object source = e.getSource();
-                if (source instanceof TableColumn) {
-                    listener.columnResized(3, (TableColumn) source);
-                }
-            }
-        });
-
-        col = TableHelper.createTableColumn(
-                mLogTable, "Value",
-                SWT.LEFT, "0000000", PREFS_COL_VALUE, store); //$NON-NLS-1$
-        col.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Object source = e.getSource();
-                if (source instanceof TableColumn) {
-                    listener.columnResized(4, (TableColumn) source);
-                }
-            }
-        });
-
-        col = TableHelper.createTableColumn(
-                mLogTable, "Type",
-                SWT.LEFT, "long, seconds", PREFS_COL_TYPE, store); //$NON-NLS-1$
-        col.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Object source = e.getSource();
-                if (source instanceof TableColumn) {
-                    listener.columnResized(5, (TableColumn) source);
-                }
-            }
-        });
-
-        mLogTable.setHeaderVisible(true);
-        mLogTable.setLinesVisible(true);
-
-        return mainComp;
-    }
-
-    /**
-     * Resizes the <code>index</code>-th column of the log {@link Table} (if applicable).
-     * <p/>
-     * This does nothing if the <code>Table</code> object is <code>null</code> (because the display
-     * type does not use a column) or if the <code>index</code>-th column is in fact the originating
-     * column passed as argument.
-     *
-     * @param index        the index of the column to resize
-     * @param sourceColumn the original column that was resize, and on which we need to sync the
-     *                     index-th column width.
-     */
-    @Override
-    void resizeColumn(int index, TableColumn sourceColumn) {
-        if (mLogTable != null) {
-            TableColumn col = mLogTable.getColumn(index);
-            if (col != sourceColumn) {
-                col.setWidth(sourceColumn.getWidth());
-            }
-        }
-    }
-
-    /**
-     * Gets display type
-     *
-     * @return display type as an integer
-     */
-    @Override
-    int getDisplayType() {
-        return DISPLAY_TYPE_LOG_ALL;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySync.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySync.java
deleted file mode 100644
index 1c006bc..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySync.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.InvalidTypeException;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.jfree.chart.labels.CustomXYToolTipGenerator;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYBarRenderer;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
-import org.jfree.data.time.FixedMillisecond;
-import org.jfree.data.time.SimpleTimePeriod;
-import org.jfree.data.time.TimePeriodValues;
-import org.jfree.data.time.TimePeriodValuesCollection;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-import org.jfree.util.ShapeUtilities;
-
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-import java.util.regex.Pattern;
-
-public class DisplaySync extends SyncCommon {
-
-    // Information to graph for each authority
-    private TimePeriodValues mDatasetsSync[];
-    private List<String> mTooltipsSync[];
-    private CustomXYToolTipGenerator mTooltipGenerators[];
-    private TimeSeries mDatasetsSyncTickle[];
-
-    // Dataset of error events to graph
-    private TimeSeries mDatasetError;
-
-    public DisplaySync(String name) {
-        super(name);
-    }
-
-    /**
-     * Creates the UI for the event display.
-     * @param parent the parent composite.
-     * @param logParser the current log parser.
-     * @return the created control (which may have children).
-     */
-    @Override
-    public Control createComposite(final Composite parent, EventLogParser logParser,
-            final ILogColumnListener listener) {
-        Control composite = createCompositeChart(parent, logParser, "Sync Status");
-        resetUI();
-        return composite;
-    }
-
-    /**
-     * Resets the display.
-     */
-    @Override
-    void resetUI() {
-        super.resetUI();
-        XYPlot xyPlot = mChart.getXYPlot();
-
-        XYBarRenderer br = new XYBarRenderer();
-        mDatasetsSync = new TimePeriodValues[NUM_AUTHS];
-        mTooltipsSync = new List[NUM_AUTHS];
-        mTooltipGenerators = new CustomXYToolTipGenerator[NUM_AUTHS];
-
-        TimePeriodValuesCollection tpvc = new TimePeriodValuesCollection();
-        xyPlot.setDataset(tpvc);
-        xyPlot.setRenderer(0, br);
-
-        XYLineAndShapeRenderer ls = new XYLineAndShapeRenderer();
-        ls.setBaseLinesVisible(false);
-        mDatasetsSyncTickle = new TimeSeries[NUM_AUTHS];
-        TimeSeriesCollection tsc = new TimeSeriesCollection();
-        xyPlot.setDataset(1, tsc);
-        xyPlot.setRenderer(1, ls);
-
-        mDatasetError = new TimeSeries("Errors", FixedMillisecond.class);
-        xyPlot.setDataset(2, new TimeSeriesCollection(mDatasetError));
-        XYLineAndShapeRenderer errls = new XYLineAndShapeRenderer();
-        errls.setBaseLinesVisible(false);
-        errls.setSeriesPaint(0, Color.RED);
-        xyPlot.setRenderer(2, errls);
-
-        for (int i = 0; i < NUM_AUTHS; i++) {
-            br.setSeriesPaint(i, AUTH_COLORS[i]);
-            ls.setSeriesPaint(i, AUTH_COLORS[i]);
-            mDatasetsSync[i] = new TimePeriodValues(AUTH_NAMES[i]);
-            tpvc.addSeries(mDatasetsSync[i]);
-            mTooltipsSync[i] = new ArrayList<String>();
-            mTooltipGenerators[i] = new CustomXYToolTipGenerator();
-            br.setSeriesToolTipGenerator(i, mTooltipGenerators[i]);
-            mTooltipGenerators[i].addToolTipSeries(mTooltipsSync[i]);
-
-            mDatasetsSyncTickle[i] = new TimeSeries(AUTH_NAMES[i] + " tickle",
-                    FixedMillisecond.class);
-            tsc.addSeries(mDatasetsSyncTickle[i]);
-            ls.setSeriesShape(i, ShapeUtilities.createUpTriangle(2.5f));
-        }
-    }
-
-    /**
-     * Updates the display with a new event.
-     *
-     * @param event     The event
-     * @param logParser The parser providing the event.
-     */
-    @Override
-    void newEvent(EventContainer event, EventLogParser logParser) {
-        super.newEvent(event, logParser); // Handle sync operation
-        try {
-            if (event.mTag == EVENT_TICKLE) {
-                int auth = getAuth(event.getValueAsString(0));
-                if (auth >= 0) {
-                    long msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
-                    mDatasetsSyncTickle[auth].addOrUpdate(new FixedMillisecond(msec), -1);
-                }
-            }
-        } catch (InvalidTypeException e) {
-        }
-    }
-
-    /**
-     * Generate the height for an event.
-     * Height is somewhat arbitrarily the count of "things" that happened
-     * during the sync.
-     * When network traffic measurements are available, code should be modified
-     * to use that instead.
-     * @param details The details string associated with the event
-     * @return The height in arbirary units (0-100)
-     */
-    private int getHeightFromDetails(String details) {
-        if (details == null) {
-            return 1; // Arbitrary
-        }
-        int total = 0;
-        String parts[] = details.split("[a-zA-Z]");
-        for (String part : parts) {
-            if ("".equals(part)) continue;
-            total += Integer.parseInt(part);
-        }
-        if (total == 0) {
-            total = 1;
-        }
-        return total;
-    }
-
-    /**
-     * Generates the tooltips text for an event.
-     * This method decodes the cryptic details string.
-     * @param auth The authority associated with the event
-     * @param details The details string
-     * @param eventSource server, poll, etc.
-     * @return The text to display in the tooltips
-     */
-    private String getTextFromDetails(int auth, String details, int eventSource) {
-
-        StringBuffer sb = new StringBuffer();
-        sb.append(AUTH_NAMES[auth]).append(": \n");
-
-        Scanner scanner = new Scanner(details);
-        Pattern charPat = Pattern.compile("[a-zA-Z]");
-        Pattern numPat = Pattern.compile("[0-9]+");
-        while (scanner.hasNext()) {
-            String key = scanner.findInLine(charPat);
-            int val = Integer.parseInt(scanner.findInLine(numPat));
-            if (auth == GMAIL && "M".equals(key)) {
-                sb.append("messages from server: ").append(val).append("\n");
-            } else if (auth == GMAIL && "L".equals(key)) {
-                sb.append("labels from server: ").append(val).append("\n");
-            } else if (auth == GMAIL && "C".equals(key)) {
-                sb.append("check conversation requests from server: ").append(val).append("\n");
-            } else if (auth == GMAIL && "A".equals(key)) {
-                sb.append("attachments from server: ").append(val).append("\n");
-            } else if (auth == GMAIL && "U".equals(key)) {
-                sb.append("op updates from server: ").append(val).append("\n");
-            } else if (auth == GMAIL && "u".equals(key)) {
-                sb.append("op updates to server: ").append(val).append("\n");
-            } else if (auth == GMAIL && "S".equals(key)) {
-                sb.append("send/receive cycles: ").append(val).append("\n");
-            } else if ("Q".equals(key)) {
-                sb.append("queries to server: ").append(val).append("\n");
-            } else if ("E".equals(key)) {
-                sb.append("entries from server: ").append(val).append("\n");
-            } else if ("u".equals(key)) {
-                sb.append("updates from client: ").append(val).append("\n");
-            } else if ("i".equals(key)) {
-                sb.append("inserts from client: ").append(val).append("\n");
-            } else if ("d".equals(key)) {
-                sb.append("deletes from client: ").append(val).append("\n");
-            } else if ("f".equals(key)) {
-                sb.append("full sync requested\n");
-            } else if ("r".equals(key)) {
-                sb.append("partial sync unavailable\n");
-            } else if ("X".equals(key)) {
-                sb.append("hard error\n");
-            } else if ("e".equals(key)) {
-                sb.append("number of parse exceptions: ").append(val).append("\n");
-            } else if ("c".equals(key)) {
-                sb.append("number of conflicts: ").append(val).append("\n");
-            } else if ("a".equals(key)) {
-                sb.append("number of auth exceptions: ").append(val).append("\n");
-            } else if ("D".equals(key)) {
-                sb.append("too many deletions\n");
-            } else if ("R".equals(key)) {
-                sb.append("too many retries: ").append(val).append("\n");
-            } else if ("b".equals(key)) {
-                sb.append("database error\n");
-            } else if ("x".equals(key)) {
-                sb.append("soft error\n");
-            } else if ("l".equals(key)) {
-                sb.append("sync already in progress\n");
-            } else if ("I".equals(key)) {
-                sb.append("io exception\n");
-            } else if (auth == CONTACTS && "g".equals(key)) {
-                sb.append("aggregation query: ").append(val).append("\n");
-            } else if (auth == CONTACTS && "G".equals(key)) {
-                sb.append("aggregation merge: ").append(val).append("\n");
-            } else if (auth == CONTACTS && "n".equals(key)) {
-                sb.append("num entries: ").append(val).append("\n");
-            } else if (auth == CONTACTS && "p".equals(key)) {
-                sb.append("photos uploaded from server: ").append(val).append("\n");
-            } else if (auth == CONTACTS && "P".equals(key)) {
-                sb.append("photos downloaded from server: ").append(val).append("\n");
-            } else if (auth == CALENDAR && "F".equals(key)) {
-                sb.append("server refresh\n");
-            } else if (auth == CALENDAR && "s".equals(key)) {
-                sb.append("server diffs fetched\n");
-            } else {
-                sb.append(key).append("=").append(val);
-            }
-        }
-        if (eventSource == 0) {
-            sb.append("(server)");
-        } else if (eventSource == 1) {
-            sb.append("(local)");
-        } else if (eventSource == 2) {
-            sb.append("(poll)");
-        } else if (eventSource == 3) {
-            sb.append("(user)");
-        }
-        return sb.toString();
-    }
-
-
-    /**
-     * Callback to process a sync event.
-     */
-    @Override
-    void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
-            String details, boolean newEvent, int syncSource) {
-        if (!newEvent) {
-            // Details arrived for a previous sync event
-            // Remove event before reinserting.
-            int lastItem = mDatasetsSync[auth].getItemCount();
-            mDatasetsSync[auth].delete(lastItem-1, lastItem-1);
-            mTooltipsSync[auth].remove(lastItem-1);
-        }
-        double height = getHeightFromDetails(details);
-        height = height / (stopTime - startTime + 1) * 10000;
-        if (height > 30) {
-            height = 30;
-        }
-        mDatasetsSync[auth].add(new SimpleTimePeriod(startTime, stopTime), height);
-        mTooltipsSync[auth].add(getTextFromDetails(auth, details, syncSource));
-        mTooltipGenerators[auth].addToolTipSeries(mTooltipsSync[auth]);
-        if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
-            long msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
-            mDatasetError.addOrUpdate(new FixedMillisecond(msec), -1);
-        }
-    }
-
-    /**
-     * Gets display type
-     *
-     * @return display type as an integer
-     */
-    @Override
-    int getDisplayType() {
-        return DISPLAY_TYPE_SYNC;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncHistogram.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncHistogram.java
deleted file mode 100644
index 36d90ce..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncHistogram.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
-import org.jfree.chart.renderer.xy.XYBarRenderer;
-import org.jfree.data.time.RegularTimePeriod;
-import org.jfree.data.time.SimpleTimePeriod;
-import org.jfree.data.time.TimePeriodValues;
-import org.jfree.data.time.TimePeriodValuesCollection;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TimeZone;
-
-public class DisplaySyncHistogram extends SyncCommon {
-
-    Map<SimpleTimePeriod, Integer> mTimePeriodMap[];
-
-    // Information to graph for each authority
-    private TimePeriodValues mDatasetsSyncHist[];
-
-    public DisplaySyncHistogram(String name) {
-        super(name);
-    }
-
-    /**
-     * Creates the UI for the event display.
-     * @param parent the parent composite.
-     * @param logParser the current log parser.
-     * @return the created control (which may have children).
-     */
-    @Override
-    public Control createComposite(final Composite parent, EventLogParser logParser,
-            final ILogColumnListener listener) {
-        Control composite = createCompositeChart(parent, logParser, "Sync Histogram");
-        resetUI();
-        return composite;
-    }
-
-    /**
-     * Resets the display.
-     */
-    @Override
-    void resetUI() {
-        super.resetUI();
-        XYPlot xyPlot = mChart.getXYPlot();
-
-        AbstractXYItemRenderer br = new XYBarRenderer();
-        mDatasetsSyncHist = new TimePeriodValues[NUM_AUTHS+1];
-        mTimePeriodMap = new HashMap[NUM_AUTHS + 1];
-
-        TimePeriodValuesCollection tpvc = new TimePeriodValuesCollection();
-        xyPlot.setDataset(tpvc);
-        xyPlot.setRenderer(br);
-
-        for (int i = 0; i < NUM_AUTHS + 1; i++) {
-            br.setSeriesPaint(i, AUTH_COLORS[i]);
-            mDatasetsSyncHist[i] = new TimePeriodValues(AUTH_NAMES[i]);
-            tpvc.addSeries(mDatasetsSyncHist[i]);
-            mTimePeriodMap[i] = new HashMap<SimpleTimePeriod, Integer>();
-
-        }
-    }
-
-    /**
-     * Callback to process a sync event.
-     *
-     * @param event      The sync event
-     * @param startTime Start time (ms) of events
-     * @param stopTime Stop time (ms) of events
-     * @param details Details associated with the event.
-     * @param newEvent True if this event is a new sync event.  False if this event
-     * @param syncSource
-     */
-    @Override
-    void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
-            String details, boolean newEvent, int syncSource) {
-        if (newEvent) {
-            if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
-                auth = ERRORS;
-            }
-            double delta = (stopTime - startTime) * 100. / 1000 / 3600; // Percent of hour
-            addHistEvent(0, auth, delta);
-        } else {
-            // sync_details arrived for an event that has already been graphed.
-            if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
-                // Item turns out to be in error, so transfer time from old auth to error.
-                double delta = (stopTime - startTime) * 100. / 1000 / 3600; // Percent of hour
-                addHistEvent(0, auth, -delta);
-                addHistEvent(0, ERRORS, delta);
-            }
-        }
-    }
-
-    /**
-     * Helper to add an event to the data series.
-     * Also updates error series if appropriate (x or X in details).
-     * @param stopTime Time event ends
-     * @param auth Sync authority
-     * @param value Value to graph for event
-     */
-    private void addHistEvent(long stopTime, int auth, double value) {
-        SimpleTimePeriod hour = getTimePeriod(stopTime, mHistWidth);
-
-        // Loop over all datasets to do the stacking.
-        for (int i = auth; i <= ERRORS; i++) {
-            addToPeriod(mDatasetsSyncHist, i, hour, value);
-        }
-    }
-
-    private void addToPeriod(TimePeriodValues tpv[], int auth, SimpleTimePeriod period,
-            double value) {
-        int index;
-        if (mTimePeriodMap[auth].containsKey(period)) {
-            index = mTimePeriodMap[auth].get(period);
-            double oldValue = tpv[auth].getValue(index).doubleValue();
-            tpv[auth].update(index, oldValue + value);
-        } else {
-            index = tpv[auth].getItemCount();
-            mTimePeriodMap[auth].put(period, index);
-            tpv[auth].add(period, value);
-        }
-    }
-
-    /**
-     * Creates a multiple-hour time period for the histogram.
-     * @param time Time in milliseconds.
-     * @param numHoursWide: should divide into a day.
-     * @return SimpleTimePeriod covering the number of hours and containing time.
-     */
-    private SimpleTimePeriod getTimePeriod(long time, long numHoursWide) {
-        Date date = new Date(time);
-        TimeZone zone = RegularTimePeriod.DEFAULT_TIME_ZONE;
-        Calendar calendar = Calendar.getInstance(zone);
-        calendar.setTime(date);
-        long hoursOfYear = calendar.get(Calendar.HOUR_OF_DAY) +
-                calendar.get(Calendar.DAY_OF_YEAR) * 24;
-        int year = calendar.get(Calendar.YEAR);
-        hoursOfYear = (hoursOfYear / numHoursWide) * numHoursWide;
-        calendar.clear();
-        calendar.set(year, 0, 1, 0, 0); // Jan 1
-        long start = calendar.getTimeInMillis() + hoursOfYear * 3600 * 1000;
-        return new SimpleTimePeriod(start, start + numHoursWide * 3600 * 1000);
-    }
-
-    /**
-     * Gets display type
-     *
-     * @return display type as an integer
-     */
-    @Override
-    int getDisplayType() {
-        return DISPLAY_TYPE_SYNC_HIST;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncPerf.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncPerf.java
deleted file mode 100644
index 9ce7045..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncPerf.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.InvalidTypeException;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.jfree.chart.labels.CustomXYToolTipGenerator;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYBarRenderer;
-import org.jfree.data.time.SimpleTimePeriod;
-import org.jfree.data.time.TimePeriodValues;
-import org.jfree.data.time.TimePeriodValuesCollection;
-
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.List;
-
-public class DisplaySyncPerf extends SyncCommon {
-
-    CustomXYToolTipGenerator mTooltipGenerator;
-    List mTooltips[];
-
-    // The series number for each graphed item.
-    // sync authorities are 0-3
-    private static final int DB_QUERY = 4;
-    private static final int DB_WRITE = 5;
-    private static final int HTTP_NETWORK = 6;
-    private static final int HTTP_PROCESSING = 7;
-    private static final int NUM_SERIES = (HTTP_PROCESSING + 1);
-    private static final String SERIES_NAMES[] = {"Calendar", "Gmail", "Feeds", "Contacts",
-            "DB Query", "DB Write", "HTTP Response", "HTTP Processing",};
-    private static final Color SERIES_COLORS[] = {Color.MAGENTA, Color.GREEN, Color.BLUE,
-            Color.ORANGE, Color.RED, Color.CYAN, Color.PINK, Color.DARK_GRAY};
-    private static final double SERIES_YCOORD[] = {0, 0, 0, 0, 1, 1, 2, 2};
-
-    // Values from data/etc/event-log-tags
-    private static final int EVENT_DB_OPERATION = 52000;
-    private static final int EVENT_HTTP_STATS = 52001;
-    // op types for EVENT_DB_OPERATION
-    final int EVENT_DB_QUERY = 0;
-    final int EVENT_DB_WRITE = 1;
-
-    // Information to graph for each authority
-    private TimePeriodValues mDatasets[];
-
-    /**
-     * TimePeriodValuesCollection that supports Y intervals.  This allows the
-     * creation of "floating" bars, rather than bars rooted to the axis.
-     */
-    class YIntervalTimePeriodValuesCollection extends TimePeriodValuesCollection {
-        /** default serial UID */
-        private static final long serialVersionUID = 1L;
-
-        private double yheight;
-
-        /**
-         * Constructs a collection of bars with a fixed Y height.
-         *
-         * @param yheight The height of the bars.
-         */
-        YIntervalTimePeriodValuesCollection(double yheight) {
-            this.yheight = yheight;
-        }
-
-        /**
-         * Returns ending Y value that is a fixed amount greater than the starting value.
-         *
-         * @param series the series (zero-based index).
-         * @param item   the item (zero-based index).
-         * @return The ending Y value for the specified series and item.
-         */
-        @Override
-        public Number getEndY(int series, int item) {
-            return getY(series, item).doubleValue() + yheight;
-        }
-    }
-
-    /**
-     * Constructs a graph of network and database stats.
-     *
-     * @param name The name of this graph in the graph list.
-     */
-    public DisplaySyncPerf(String name) {
-        super(name);
-    }
-
-    /**
-     * Creates the UI for the event display.
-     *
-     * @param parent    the parent composite.
-     * @param logParser the current log parser.
-     * @return the created control (which may have children).
-     */
-    @Override
-    public Control createComposite(final Composite parent, EventLogParser logParser,
-            final ILogColumnListener listener) {
-        Control composite = createCompositeChart(parent, logParser, "Sync Performance");
-        resetUI();
-        return composite;
-    }
-
-    /**
-     * Resets the display.
-     */
-    @Override
-    void resetUI() {
-        super.resetUI();
-        XYPlot xyPlot = mChart.getXYPlot();
-        xyPlot.getRangeAxis().setVisible(false);
-        mTooltipGenerator = new CustomXYToolTipGenerator();
-        mTooltips = new List[NUM_SERIES];
-
-        XYBarRenderer br = new XYBarRenderer();
-        br.setUseYInterval(true);
-        mDatasets = new TimePeriodValues[NUM_SERIES];
-
-        TimePeriodValuesCollection tpvc = new YIntervalTimePeriodValuesCollection(1);
-        xyPlot.setDataset(tpvc);
-        xyPlot.setRenderer(br);
-
-        for (int i = 0; i < NUM_SERIES; i++) {
-            br.setSeriesPaint(i, SERIES_COLORS[i]);
-            mDatasets[i] = new TimePeriodValues(SERIES_NAMES[i]);
-            tpvc.addSeries(mDatasets[i]);
-            mTooltips[i] = new ArrayList<String>();
-            mTooltipGenerator.addToolTipSeries(mTooltips[i]);
-            br.setSeriesToolTipGenerator(i, mTooltipGenerator);
-        }
-    }
-
-    /**
-     * Updates the display with a new event.
-     *
-     * @param event     The event
-     * @param logParser The parser providing the event.
-     */
-    @Override
-    void newEvent(EventContainer event, EventLogParser logParser) {
-        super.newEvent(event, logParser); // Handle sync operation
-        try {
-            if (event.mTag == EVENT_DB_OPERATION) {
-                // 52000 db_operation (name|3),(op_type|1|5),(time|2|3)
-                String tip = event.getValueAsString(0);
-                long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
-                int opType = Integer.parseInt(event.getValueAsString(1));
-                long duration = Long.parseLong(event.getValueAsString(2));
-
-                if (opType == EVENT_DB_QUERY) {
-                    mDatasets[DB_QUERY].add(new SimpleTimePeriod(endTime - duration, endTime),
-                            SERIES_YCOORD[DB_QUERY]);
-                    mTooltips[DB_QUERY].add(tip);
-                } else if (opType == EVENT_DB_WRITE) {
-                    mDatasets[DB_WRITE].add(new SimpleTimePeriod(endTime - duration, endTime),
-                            SERIES_YCOORD[DB_WRITE]);
-                    mTooltips[DB_WRITE].add(tip);
-                }
-            } else if (event.mTag == EVENT_HTTP_STATS) {
-                // 52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2)
-                String tip = event.getValueAsString(0) + ", tx:" + event.getValueAsString(3) +
-                        ", rx: " + event.getValueAsString(4);
-                long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
-                long netEndTime = endTime - Long.parseLong(event.getValueAsString(2));
-                long netStartTime = netEndTime - Long.parseLong(event.getValueAsString(1));
-                mDatasets[HTTP_NETWORK].add(new SimpleTimePeriod(netStartTime, netEndTime),
-                        SERIES_YCOORD[HTTP_NETWORK]);
-                mDatasets[HTTP_PROCESSING].add(new SimpleTimePeriod(netEndTime, endTime),
-                        SERIES_YCOORD[HTTP_PROCESSING]);
-                mTooltips[HTTP_NETWORK].add(tip);
-                mTooltips[HTTP_PROCESSING].add(tip);
-            }
-        } catch (InvalidTypeException e) {
-        }
-    }
-
-    /**
-     * Callback from super.newEvent to process a sync event.
-     *
-     * @param event      The sync event
-     * @param startTime  Start time (ms) of events
-     * @param stopTime   Stop time (ms) of events
-     * @param details    Details associated with the event.
-     * @param newEvent   True if this event is a new sync event.  False if this event
-     * @param syncSource
-     */
-    @Override
-    void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
-            String details, boolean newEvent, int syncSource) {
-        if (newEvent) {
-            mDatasets[auth].add(new SimpleTimePeriod(startTime, stopTime), SERIES_YCOORD[auth]);
-        }
-    }
-
-    /**
-     * Gets display type
-     *
-     * @return display type as an integer
-     */
-    @Override
-    int getDisplayType() {
-        return DISPLAY_TYPE_SYNC_PERF;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplay.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplay.java
deleted file mode 100644
index 2223a4d..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplay.java
+++ /dev/null
@@ -1,971 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.Log;
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventContainer.CompareMethod;
-import com.android.ddmlib.log.EventContainer.EventValueType;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.EventValueDescription.ValueType;
-import com.android.ddmlib.log.InvalidTypeException;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.event.ChartChangeEvent;
-import org.jfree.chart.event.ChartChangeEventType;
-import org.jfree.chart.event.ChartChangeListener;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.title.TextTitle;
-import org.jfree.data.time.Millisecond;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-import org.jfree.experimental.chart.swt.ChartComposite;
-import org.jfree.experimental.swt.SWTUtils;
-
-import java.security.InvalidParameterException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-/**
- * Represents a custom display of one or more events.
- */
-abstract class EventDisplay {
-
-    private final static String DISPLAY_DATA_STORAGE_SEPARATOR = ":"; //$NON-NLS-1$
-    private final static String PID_STORAGE_SEPARATOR = ","; //$NON-NLS-1$
-    private final static String DESCRIPTOR_STORAGE_SEPARATOR = "$"; //$NON-NLS-1$
-    private final static String DESCRIPTOR_DATA_STORAGE_SEPARATOR = "!"; //$NON-NLS-1$
-
-    private final static String FILTER_VALUE_NULL = "<null>"; //$NON-NLS-1$
-
-    public final static int DISPLAY_TYPE_LOG_ALL = 0;
-    public final static int DISPLAY_TYPE_FILTERED_LOG = 1;
-    public final static int DISPLAY_TYPE_GRAPH = 2;
-    public final static int DISPLAY_TYPE_SYNC = 3;
-    public final static int DISPLAY_TYPE_SYNC_HIST = 4;
-    public final static int DISPLAY_TYPE_SYNC_PERF = 5;
-
-    private final static int EVENT_CHECK_FAILED = 0;
-    protected final static int EVENT_CHECK_SAME_TAG = 1;
-    protected final static int EVENT_CHECK_SAME_VALUE = 2;
-
-    /**
-     * Creates the appropriate EventDisplay subclass.
-     *
-     * @param type the type of display (DISPLAY_TYPE_LOG_ALL, etc)
-     * @param name the name of the display
-     * @return the created object
-     */
-    public static EventDisplay eventDisplayFactory(int type, String name) {
-        switch (type) {
-            case DISPLAY_TYPE_LOG_ALL:
-                return new DisplayLog(name);
-            case DISPLAY_TYPE_FILTERED_LOG:
-                return new DisplayFilteredLog(name);
-            case DISPLAY_TYPE_SYNC:
-                return new DisplaySync(name);
-            case DISPLAY_TYPE_SYNC_HIST:
-                return new DisplaySyncHistogram(name);
-            case DISPLAY_TYPE_GRAPH:
-                return new DisplayGraph(name);
-            case DISPLAY_TYPE_SYNC_PERF:
-                return new DisplaySyncPerf(name);
-            default:
-                throw new InvalidParameterException("Unknown Display Type " + type); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Adds event to the display.
-     * @param event The event
-     * @param logParser The log parser.
-     */
-    abstract void newEvent(EventContainer event, EventLogParser logParser);
-
-    /**
-     * Resets the display.
-     */
-    abstract void resetUI();
-
-    /**
-     * Gets display type
-     *
-     * @return display type as an integer
-     */
-    abstract int getDisplayType();
-
-    /**
-     * Creates the UI for the event display.
-     *
-     * @param parent    the parent composite.
-     * @param logParser the current log parser.
-     * @return the created control (which may have children).
-     */
-    abstract Control createComposite(final Composite parent, EventLogParser logParser,
-            final ILogColumnListener listener);
-
-    interface ILogColumnListener {
-        void columnResized(int index, TableColumn sourceColumn);
-    }
-
-    /**
-     * Describes an event to be displayed.
-     */
-    static class OccurrenceDisplayDescriptor {
-
-        int eventTag = -1;
-        int seriesValueIndex = -1;
-        boolean includePid = false;
-        int filterValueIndex = -1;
-        CompareMethod filterCompareMethod = CompareMethod.EQUAL_TO;
-        Object filterValue = null;
-
-        OccurrenceDisplayDescriptor() {
-        }
-
-        OccurrenceDisplayDescriptor(OccurrenceDisplayDescriptor descriptor) {
-            replaceWith(descriptor);
-        }
-
-        OccurrenceDisplayDescriptor(int eventTag) {
-            this.eventTag = eventTag;
-        }
-
-        OccurrenceDisplayDescriptor(int eventTag, int seriesValueIndex) {
-            this.eventTag = eventTag;
-            this.seriesValueIndex = seriesValueIndex;
-        }
-
-        void replaceWith(OccurrenceDisplayDescriptor descriptor) {
-            eventTag = descriptor.eventTag;
-            seriesValueIndex = descriptor.seriesValueIndex;
-            includePid = descriptor.includePid;
-            filterValueIndex = descriptor.filterValueIndex;
-            filterCompareMethod = descriptor.filterCompareMethod;
-            filterValue = descriptor.filterValue;
-        }
-
-        /**
-         * Loads the descriptor parameter from a storage string. The storage string must have
-         * been generated with {@link #getStorageString()}.
-         *
-         * @param storageString the storage string
-         */
-        final void loadFrom(String storageString) {
-            String[] values = storageString.split(Pattern.quote(DESCRIPTOR_DATA_STORAGE_SEPARATOR));
-            loadFrom(values, 0);
-        }
-
-        /**
-         * Loads the parameters from an array of strings.
-         *
-         * @param storageStrings the strings representing each parameter.
-         * @param index          the starting index in the array of strings.
-         * @return the new index in the array.
-         */
-        protected int loadFrom(String[] storageStrings, int index) {
-            eventTag = Integer.parseInt(storageStrings[index++]);
-            seriesValueIndex = Integer.parseInt(storageStrings[index++]);
-            includePid = Boolean.parseBoolean(storageStrings[index++]);
-            filterValueIndex = Integer.parseInt(storageStrings[index++]);
-            try {
-                filterCompareMethod = CompareMethod.valueOf(storageStrings[index++]);
-            } catch (IllegalArgumentException e) {
-                // if the name does not match any known CompareMethod, we init it to the default one
-                filterCompareMethod = CompareMethod.EQUAL_TO;
-            }
-            String value = storageStrings[index++];
-            if (filterValueIndex != -1 && FILTER_VALUE_NULL.equals(value) == false) {
-                filterValue = EventValueType.getObjectFromStorageString(value);
-            }
-
-            return index;
-        }
-
-        /**
-         * Returns the storage string for the receiver.
-         */
-        String getStorageString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(eventTag);
-            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
-            sb.append(seriesValueIndex);
-            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
-            sb.append(Boolean.toString(includePid));
-            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
-            sb.append(filterValueIndex);
-            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
-            sb.append(filterCompareMethod.name());
-            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
-            if (filterValue != null) {
-                String value = EventValueType.getStorageString(filterValue);
-                if (value != null) {
-                    sb.append(value);
-                } else {
-                    sb.append(FILTER_VALUE_NULL);
-                }
-            } else {
-                sb.append(FILTER_VALUE_NULL);
-            }
-
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Describes an event value to be displayed.
-     */
-    static final class ValueDisplayDescriptor extends OccurrenceDisplayDescriptor {
-        String valueName;
-        int valueIndex = -1;
-
-        ValueDisplayDescriptor() {
-            super();
-        }
-
-        ValueDisplayDescriptor(ValueDisplayDescriptor descriptor) {
-            super();
-            replaceWith(descriptor);
-        }
-
-        ValueDisplayDescriptor(int eventTag, String valueName, int valueIndex) {
-            super(eventTag);
-            this.valueName = valueName;
-            this.valueIndex = valueIndex;
-        }
-
-        ValueDisplayDescriptor(int eventTag, String valueName, int valueIndex,
-                int seriesValueIndex) {
-            super(eventTag, seriesValueIndex);
-            this.valueName = valueName;
-            this.valueIndex = valueIndex;
-        }
-
-        @Override
-        void replaceWith(OccurrenceDisplayDescriptor descriptor) {
-            super.replaceWith(descriptor);
-            if (descriptor instanceof ValueDisplayDescriptor) {
-                ValueDisplayDescriptor valueDescriptor = (ValueDisplayDescriptor) descriptor;
-                valueName = valueDescriptor.valueName;
-                valueIndex = valueDescriptor.valueIndex;
-            }
-        }
-
-        /**
-         * Loads the parameters from an array of strings.
-         *
-         * @param storageStrings the strings representing each parameter.
-         * @param index          the starting index in the array of strings.
-         * @return the new index in the array.
-         */
-        @Override
-        protected int loadFrom(String[] storageStrings, int index) {
-            index = super.loadFrom(storageStrings, index);
-            valueName = storageStrings[index++];
-            valueIndex = Integer.parseInt(storageStrings[index++]);
-            return index;
-        }
-
-        /**
-         * Returns the storage string for the receiver.
-         */
-        @Override
-        String getStorageString() {
-            String superStorage = super.getStorageString();
-
-            StringBuilder sb = new StringBuilder();
-            sb.append(superStorage);
-            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
-            sb.append(valueName);
-            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
-            sb.append(valueIndex);
-
-            return sb.toString();
-        }
-    }
-
-    /* ==================
-     * Event Display parameters.
-     * ================== */
-    protected String mName;
-
-    private boolean mPidFiltering = false;
-
-    private ArrayList<Integer> mPidFilterList = null;
-
-    protected final ArrayList<ValueDisplayDescriptor> mValueDescriptors =
-            new ArrayList<ValueDisplayDescriptor>();
-    private final ArrayList<OccurrenceDisplayDescriptor> mOccurrenceDescriptors =
-            new ArrayList<OccurrenceDisplayDescriptor>();
-
-    /* ==================
-     * Event Display members for display purpose.
-     * ================== */
-    // chart objects
-    /**
-     * This is a map of (descriptor, map2) where map2 is a map of (pid, chart-series)
-     */
-    protected final HashMap<ValueDisplayDescriptor, HashMap<Integer, TimeSeries>> mValueDescriptorSeriesMap =
-            new HashMap<ValueDisplayDescriptor, HashMap<Integer, TimeSeries>>();
-    /**
-     * This is a map of (descriptor, map2) where map2 is a map of (pid, chart-series)
-     */
-    protected final HashMap<OccurrenceDisplayDescriptor, HashMap<Integer, TimeSeries>> mOcurrenceDescriptorSeriesMap =
-            new HashMap<OccurrenceDisplayDescriptor, HashMap<Integer, TimeSeries>>();
-
-    /**
-     * This is a map of (ValueType, dataset)
-     */
-    protected final HashMap<ValueType, TimeSeriesCollection> mValueTypeDataSetMap =
-            new HashMap<ValueType, TimeSeriesCollection>();
-
-    protected JFreeChart mChart;
-    protected TimeSeriesCollection mOccurrenceDataSet;
-    protected int mDataSetCount;
-    private ChartComposite mChartComposite;
-    protected long mMaximumChartItemAge = -1;
-    protected long mHistWidth = 1;
-
-    // log objects.
-    protected Table mLogTable;
-
-    /* ==================
-     * Misc data.
-     * ================== */
-    protected int mValueDescriptorCheck = EVENT_CHECK_FAILED;
-
-    EventDisplay(String name) {
-        mName = name;
-    }
-
-    static EventDisplay clone(EventDisplay from) {
-        EventDisplay ed = eventDisplayFactory(from.getDisplayType(), from.getName());
-        ed.mName = from.mName;
-        ed.mPidFiltering = from.mPidFiltering;
-        ed.mMaximumChartItemAge = from.mMaximumChartItemAge;
-        ed.mHistWidth = from.mHistWidth;
-
-        if (from.mPidFilterList != null) {
-            ed.mPidFilterList = new ArrayList<Integer>();
-            ed.mPidFilterList.addAll(from.mPidFilterList);
-        }
-
-        for (ValueDisplayDescriptor desc : from.mValueDescriptors) {
-            ed.mValueDescriptors.add(new ValueDisplayDescriptor(desc));
-        }
-        ed.mValueDescriptorCheck = from.mValueDescriptorCheck;
-
-        for (OccurrenceDisplayDescriptor desc : from.mOccurrenceDescriptors) {
-            ed.mOccurrenceDescriptors.add(new OccurrenceDisplayDescriptor(desc));
-        }
-        return ed;
-    }
-
-    /**
-     * Returns the parameters of the receiver as a single String for storage.
-     */
-    String getStorageString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(mName);
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-        sb.append(getDisplayType());
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-        sb.append(Boolean.toString(mPidFiltering));
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-        sb.append(getPidStorageString());
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-        sb.append(getDescriptorStorageString(mValueDescriptors));
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-        sb.append(getDescriptorStorageString(mOccurrenceDescriptors));
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-        sb.append(mMaximumChartItemAge);
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-        sb.append(mHistWidth);
-        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
-
-        return sb.toString();
-    }
-
-    void setName(String name) {
-        mName = name;
-    }
-
-    String getName() {
-        return mName;
-    }
-
-    void setPidFiltering(boolean filterByPid) {
-        mPidFiltering = filterByPid;
-    }
-
-    boolean getPidFiltering() {
-        return mPidFiltering;
-    }
-
-    void setPidFilterList(ArrayList<Integer> pids) {
-        if (mPidFiltering == false) {
-            new InvalidParameterException();
-        }
-
-        mPidFilterList = pids;
-    }
-
-    ArrayList<Integer> getPidFilterList() {
-        return mPidFilterList;
-    }
-
-    void addPidFiler(int pid) {
-        if (mPidFiltering == false) {
-            new InvalidParameterException();
-        }
-
-        if (mPidFilterList == null) {
-            mPidFilterList = new ArrayList<Integer>();
-        }
-
-        mPidFilterList.add(pid);
-    }
-
-    /**
-     * Returns an iterator to the list of {@link ValueDisplayDescriptor}.
-     */
-    Iterator<ValueDisplayDescriptor> getValueDescriptors() {
-        return mValueDescriptors.iterator();
-    }
-
-    /**
-     * Update checks on the descriptors. Must be called whenever a descriptor is modified outside
-     * of this class.
-     */
-    void updateValueDescriptorCheck() {
-        mValueDescriptorCheck = checkDescriptors();
-    }
-
-    /**
-     * Returns an iterator to the list of {@link OccurrenceDisplayDescriptor}.
-     */
-    Iterator<OccurrenceDisplayDescriptor> getOccurrenceDescriptors() {
-        return mOccurrenceDescriptors.iterator();
-    }
-
-    /**
-     * Adds a descriptor. This can be a {@link OccurrenceDisplayDescriptor} or a
-     * {@link ValueDisplayDescriptor}.
-     *
-     * @param descriptor the descriptor to be added.
-     */
-    void addDescriptor(OccurrenceDisplayDescriptor descriptor) {
-        if (descriptor instanceof ValueDisplayDescriptor) {
-            mValueDescriptors.add((ValueDisplayDescriptor) descriptor);
-            mValueDescriptorCheck = checkDescriptors();
-        } else {
-            mOccurrenceDescriptors.add(descriptor);
-        }
-    }
-
-    /**
-     * Returns a descriptor by index and class (extending {@link OccurrenceDisplayDescriptor}).
-     *
-     * @param descriptorClass the class of the descriptor to return.
-     * @param index           the index of the descriptor to return.
-     * @return either a {@link OccurrenceDisplayDescriptor} or a {@link ValueDisplayDescriptor}
-     *         or <code>null</code> if <code>descriptorClass</code> is another class.
-     */
-    OccurrenceDisplayDescriptor getDescriptor(
-            Class<? extends OccurrenceDisplayDescriptor> descriptorClass, int index) {
-
-        if (descriptorClass == OccurrenceDisplayDescriptor.class) {
-            return mOccurrenceDescriptors.get(index);
-        } else if (descriptorClass == ValueDisplayDescriptor.class) {
-            return mValueDescriptors.get(index);
-        }
-
-        return null;
-    }
-
-    /**
-     * Removes a descriptor based on its class and index.
-     *
-     * @param descriptorClass the class of the descriptor.
-     * @param index           the index of the descriptor to be removed.
-     */
-    void removeDescriptor(Class<? extends OccurrenceDisplayDescriptor> descriptorClass, int index) {
-        if (descriptorClass == OccurrenceDisplayDescriptor.class) {
-            mOccurrenceDescriptors.remove(index);
-        } else if (descriptorClass == ValueDisplayDescriptor.class) {
-            mValueDescriptors.remove(index);
-            mValueDescriptorCheck = checkDescriptors();
-        }
-    }
-
-    Control createCompositeChart(final Composite parent, EventLogParser logParser,
-            String title) {
-        mChart = ChartFactory.createTimeSeriesChart(
-                null,
-                null /* timeAxisLabel */,
-                null /* valueAxisLabel */,
-                null, /* dataset. set below */
-                true /* legend */,
-                false /* tooltips */,
-                false /* urls */);
-
-        // get the font to make a proper title. We need to convert the swt font,
-        // into an awt font.
-        Font f = parent.getFont();
-        FontData[] fData = f.getFontData();
-
-        // event though on Mac OS there could be more than one fontData, we'll only use
-        // the first one.
-        FontData firstFontData = fData[0];
-
-        java.awt.Font awtFont = SWTUtils.toAwtFont(parent.getDisplay(),
-                firstFontData, true /* ensureSameSize */);
-
-
-        mChart.setTitle(new TextTitle(title, awtFont));
-
-        final XYPlot xyPlot = mChart.getXYPlot();
-        xyPlot.setRangeCrosshairVisible(true);
-        xyPlot.setRangeCrosshairLockedOnData(true);
-        xyPlot.setDomainCrosshairVisible(true);
-        xyPlot.setDomainCrosshairLockedOnData(true);
-
-        mChart.addChangeListener(new ChartChangeListener() {
-            public void chartChanged(ChartChangeEvent event) {
-                ChartChangeEventType type = event.getType();
-                if (type == ChartChangeEventType.GENERAL) {
-                    // because the value we need (rangeCrosshair and domainCrosshair) are
-                    // updated on the draw, but the notification happens before the draw,
-                    // we process the click in a future runnable!
-                    parent.getDisplay().asyncExec(new Runnable() {
-                        public void run() {
-                            processClick(xyPlot);
-                        }
-                    });
-                }
-            }
-        });
-
-        mChartComposite = new ChartComposite(parent, SWT.BORDER, mChart,
-                ChartComposite.DEFAULT_WIDTH,
-                ChartComposite.DEFAULT_HEIGHT,
-                ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
-                ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
-                3000, // max draw width. We don't want it to zoom, so we put a big number
-                3000, // max draw height. We don't want it to zoom, so we put a big number
-                true,  // off-screen buffer
-                true,  // properties
-                true,  // save
-                true,  // print
-                true,  // zoom
-                true);   // tooltips
-
-        mChartComposite.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                mValueTypeDataSetMap.clear();
-                mDataSetCount = 0;
-                mOccurrenceDataSet = null;
-                mChart = null;
-                mChartComposite = null;
-                mValueDescriptorSeriesMap.clear();
-                mOcurrenceDescriptorSeriesMap.clear();
-            }
-        });
-
-        return mChartComposite;
-
-    }
-
-    private void processClick(XYPlot xyPlot) {
-        double rangeValue = xyPlot.getRangeCrosshairValue();
-        if (rangeValue != 0) {
-            double domainValue = xyPlot.getDomainCrosshairValue();
-
-            Millisecond msec = new Millisecond(new Date((long) domainValue));
-
-            // look for values in the dataset that contains data at this TimePeriod
-            Set<ValueDisplayDescriptor> descKeys = mValueDescriptorSeriesMap.keySet();
-
-            for (ValueDisplayDescriptor descKey : descKeys) {
-                HashMap<Integer, TimeSeries> map = mValueDescriptorSeriesMap.get(descKey);
-
-                Set<Integer> pidKeys = map.keySet();
-
-                for (Integer pidKey : pidKeys) {
-                    TimeSeries series = map.get(pidKey);
-
-                    Number value = series.getValue(msec);
-                    if (value != null) {
-                        // found a match. lets check against the actual value.
-                        if (value.doubleValue() == rangeValue) {
-
-                            return;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Resizes the <code>index</code>-th column of the log {@link Table} (if applicable).
-     * Subclasses can override if necessary.
-     * <p/>
-     * This does nothing if the <code>Table</code> object is <code>null</code> (because the display
-     * type does not use a column) or if the <code>index</code>-th column is in fact the originating
-     * column passed as argument.
-     *
-     * @param index        the index of the column to resize
-     * @param sourceColumn the original column that was resize, and on which we need to sync the
-     *                     index-th column width.
-     */
-    void resizeColumn(int index, TableColumn sourceColumn) {
-    }
-
-    /**
-     * Sets the current {@link EventLogParser} object.
-     * Subclasses can override if necessary.
-     */
-    protected void setNewLogParser(EventLogParser logParser) {
-    }
-
-    /**
-     * Prepares the {@link EventDisplay} for a multi event display.
-     */
-    void startMultiEventDisplay() {
-        if (mLogTable != null) {
-            mLogTable.setRedraw(false);
-        }
-    }
-
-    /**
-     * Finalizes the {@link EventDisplay} after a multi event display.
-     */
-    void endMultiEventDisplay() {
-        if (mLogTable != null) {
-            mLogTable.setRedraw(true);
-        }
-    }
-
-    /**
-     * Returns the {@link Table} object used to display events, if any.
-     *
-     * @return a Table object or <code>null</code>.
-     */
-    Table getTable() {
-        return mLogTable;
-    }
-
-    /**
-     * Loads a new {@link EventDisplay} from a storage string. The string must have been created
-     * with {@link #getStorageString()}.
-     *
-     * @param storageString the storage string
-     * @return a new {@link EventDisplay} or null if the load failed.
-     */
-    static EventDisplay load(String storageString) {
-        if (storageString.length() > 0) {
-            // the storage string is separated by ':'
-            String[] values = storageString.split(Pattern.quote(DISPLAY_DATA_STORAGE_SEPARATOR));
-
-            try {
-                int index = 0;
-
-                String name = values[index++];
-                int displayType = Integer.parseInt(values[index++]);
-                boolean pidFiltering = Boolean.parseBoolean(values[index++]);
-
-                EventDisplay ed = eventDisplayFactory(displayType, name);
-                ed.setPidFiltering(pidFiltering);
-
-                // because empty sections are removed by String.split(), we have to check
-                // the index for those.
-                if (index < values.length) {
-                    ed.loadPidFilters(values[index++]);
-                }
-
-                if (index < values.length) {
-                    ed.loadValueDescriptors(values[index++]);
-                }
-
-                if (index < values.length) {
-                    ed.loadOccurrenceDescriptors(values[index++]);
-                }
-
-                ed.updateValueDescriptorCheck();
-
-                if (index < values.length) {
-                    ed.mMaximumChartItemAge = Long.parseLong(values[index++]);
-                }
-
-                if (index < values.length) {
-                    ed.mHistWidth = Long.parseLong(values[index++]);
-                }
-
-                return ed;
-            } catch (RuntimeException re) {
-                // we'll return null below.
-                Log.e("ddms", re);
-            }
-        }
-
-        return null;
-    }
-
-    private String getPidStorageString() {
-        if (mPidFilterList != null) {
-            StringBuilder sb = new StringBuilder();
-            boolean first = true;
-            for (Integer i : mPidFilterList) {
-                if (first == false) {
-                    sb.append(PID_STORAGE_SEPARATOR);
-                } else {
-                    first = false;
-                }
-                sb.append(i);
-            }
-
-            return sb.toString();
-        }
-        return ""; //$NON-NLS-1$
-    }
-
-
-    private void loadPidFilters(String storageString) {
-        if (storageString.length() > 0) {
-            String[] values = storageString.split(Pattern.quote(PID_STORAGE_SEPARATOR));
-
-            for (String value : values) {
-                if (mPidFilterList == null) {
-                    mPidFilterList = new ArrayList<Integer>();
-                }
-                mPidFilterList.add(Integer.parseInt(value));
-            }
-        }
-    }
-
-    private String getDescriptorStorageString(
-            ArrayList<? extends OccurrenceDisplayDescriptor> descriptorList) {
-        StringBuilder sb = new StringBuilder();
-        boolean first = true;
-
-        for (OccurrenceDisplayDescriptor descriptor : descriptorList) {
-            if (first == false) {
-                sb.append(DESCRIPTOR_STORAGE_SEPARATOR);
-            } else {
-                first = false;
-            }
-            sb.append(descriptor.getStorageString());
-        }
-
-        return sb.toString();
-    }
-
-    private void loadOccurrenceDescriptors(String storageString) {
-        if (storageString.length() == 0) {
-            return;
-        }
-
-        String[] values = storageString.split(Pattern.quote(DESCRIPTOR_STORAGE_SEPARATOR));
-
-        for (String value : values) {
-            OccurrenceDisplayDescriptor desc = new OccurrenceDisplayDescriptor();
-            desc.loadFrom(value);
-            mOccurrenceDescriptors.add(desc);
-        }
-    }
-
-    private void loadValueDescriptors(String storageString) {
-        if (storageString.length() == 0) {
-            return;
-        }
-
-        String[] values = storageString.split(Pattern.quote(DESCRIPTOR_STORAGE_SEPARATOR));
-
-        for (String value : values) {
-            ValueDisplayDescriptor desc = new ValueDisplayDescriptor();
-            desc.loadFrom(value);
-            mValueDescriptors.add(desc);
-        }
-    }
-
-    /**
-     * Fills a list with {@link OccurrenceDisplayDescriptor} (or a subclass of it) from another
-     * list if they are configured to display the {@link EventContainer}
-     *
-     * @param event    the event container
-     * @param fullList the list with all the descriptors.
-     * @param outList  the list to fill.
-     */
-    @SuppressWarnings("unchecked")
-    private void getDescriptors(EventContainer event,
-            ArrayList<? extends OccurrenceDisplayDescriptor> fullList,
-            ArrayList outList) {
-        for (OccurrenceDisplayDescriptor descriptor : fullList) {
-            try {
-                // first check the event tag.
-                if (descriptor.eventTag == event.mTag) {
-                    // now check if we have a filter on a value
-                    if (descriptor.filterValueIndex == -1 ||
-                            event.testValue(descriptor.filterValueIndex, descriptor.filterValue,
-                                    descriptor.filterCompareMethod)) {
-                        outList.add(descriptor);
-                    }
-                }
-            } catch (InvalidTypeException ite) {
-                // if the filter for the descriptor was incorrect, we ignore the descriptor.
-            } catch (ArrayIndexOutOfBoundsException aioobe) {
-                // if the index was wrong (the event content may have changed since we setup the
-                // display), we do nothing but log the error
-                Log.e("Event Log", String.format(
-                        "ArrayIndexOutOfBoundsException occured when checking %1$d-th value of event %2$d", //$NON-NLS-1$
-                        descriptor.filterValueIndex, descriptor.eventTag));
-            }
-        }
-    }
-
-    /**
-     * Filters the {@link com.android.ddmlib.log.EventContainer}, and fills two list of {@link com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor}
-     * and {@link com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor} configured to display the event.
-     *
-     * @param event
-     * @param valueDescriptors
-     * @param occurrenceDescriptors
-     * @return true if the event should be displayed.
-     */
-
-    protected boolean filterEvent(EventContainer event,
-            ArrayList<ValueDisplayDescriptor> valueDescriptors,
-            ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
-
-        // test the pid first (if needed)
-        if (mPidFiltering && mPidFilterList != null) {
-            boolean found = false;
-            for (int pid : mPidFilterList) {
-                if (pid == event.pid) {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (found == false) {
-                return false;
-            }
-        }
-
-        // now get the list of matching descriptors
-        getDescriptors(event, mValueDescriptors, valueDescriptors);
-        getDescriptors(event, mOccurrenceDescriptors, occurrenceDescriptors);
-
-        // and return whether there is at least one match in either list.
-        return (valueDescriptors.size() > 0 || occurrenceDescriptors.size() > 0);
-    }
-
-    /**
-     * Checks all the {@link ValueDisplayDescriptor} for similarity.
-     * If all the event values are from the same tag, the method will return EVENT_CHECK_SAME_TAG.
-     * If all the event/value are the same, the method will return EVENT_CHECK_SAME_VALUE
-     *
-     * @return flag as described above
-     */
-    private int checkDescriptors() {
-        if (mValueDescriptors.size() < 2) {
-            return EVENT_CHECK_SAME_VALUE;
-        }
-
-        int tag = -1;
-        int index = -1;
-        for (ValueDisplayDescriptor display : mValueDescriptors) {
-            if (tag == -1) {
-                tag = display.eventTag;
-                index = display.valueIndex;
-            } else {
-                if (tag != display.eventTag) {
-                    return EVENT_CHECK_FAILED;
-                } else {
-                    if (index != -1) {
-                        if (index != display.valueIndex) {
-                            index = -1;
-                        }
-                    }
-                }
-            }
-        }
-
-        if (index == -1) {
-            return EVENT_CHECK_SAME_TAG;
-        }
-
-        return EVENT_CHECK_SAME_VALUE;
-    }
-
-    /**
-     * Resets the time limit on the chart to be infinite.
-     */
-    void resetChartTimeLimit() {
-        mMaximumChartItemAge = -1;
-    }
-
-    /**
-     * Sets the time limit on the charts.
-     *
-     * @param timeLimit the time limit in seconds.
-     */
-    void setChartTimeLimit(long timeLimit) {
-        mMaximumChartItemAge = timeLimit;
-    }
-
-    long getChartTimeLimit() {
-        return mMaximumChartItemAge;
-    }
-
-    /**
-     * m
-     * Resets the histogram width
-     */
-    void resetHistWidth() {
-        mHistWidth = 1;
-    }
-
-    /**
-     * Sets the histogram width
-     *
-     * @param histWidth the width in hours
-     */
-    void setHistWidth(long histWidth) {
-        mHistWidth = histWidth;
-    }
-
-    long getHistWidth() {
-        return mHistWidth;
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplayOptions.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplayOptions.java
deleted file mode 100644
index 88c3cb2..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplayOptions.java
+++ /dev/null
@@ -1,955 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.EventValueDescription;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.IImageLoader;
-import com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor;
-import com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.List;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-
-class EventDisplayOptions  extends Dialog {
-    private static final int DLG_WIDTH = 700;
-    private static final int DLG_HEIGHT = 700;
-    
-    private IImageLoader mImageLoader;
-
-    private Shell mParent;
-    private Shell mShell;
-    
-    private boolean mEditStatus = false;
-    private final ArrayList<EventDisplay> mDisplayList = new ArrayList<EventDisplay>();
-
-    /* LEFT LIST */
-    private List mEventDisplayList;
-    private Button mEventDisplayNewButton;
-    private Button mEventDisplayDeleteButton;
-    private Button mEventDisplayUpButton;
-    private Button mEventDisplayDownButton;
-    private Text mDisplayWidthText;
-    private Text mDisplayHeightText;
-
-    /* WIDGETS ON THE RIGHT */
-    private Text mDisplayNameText;
-    private Combo mDisplayTypeCombo;
-    private Group mChartOptions;
-    private Group mHistOptions;
-    private Button mPidFilterCheckBox;
-    private Text mPidText;
-
-    /** Map with (event-tag, event name) */
-    private Map<Integer, String> mEventTagMap;
-
-    /** Map with (event-tag, array of value info for the event) */
-    private Map<Integer, EventValueDescription[]> mEventDescriptionMap;
-
-    /** list of current pids */
-    private ArrayList<Integer> mPidList;
-
-    private EventLogParser mLogParser;
-
-    private Group mInfoGroup;
-
-    private static class SelectionWidgets {
-        private List mList;
-        private Button mNewButton;
-        private Button mEditButton;
-        private Button mDeleteButton;
-        
-        private void setEnabled(boolean enable) {
-            mList.setEnabled(enable);
-            mNewButton.setEnabled(enable);
-            mEditButton.setEnabled(enable);
-            mDeleteButton.setEnabled(enable);
-        }
-    }
-    
-    private SelectionWidgets mValueSelection;
-    private SelectionWidgets mOccurrenceSelection;
-    
-    /** flag to temporarly disable processing of {@link Text} changes, so that 
-     * {@link Text#setText(String)} can be called safely. */
-    private boolean mProcessTextChanges = true;
-    private Text mTimeLimitText;
-    private Text mHistWidthText;
-
-    EventDisplayOptions(IImageLoader imageLoader, Shell parent) {
-        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-        mImageLoader = imageLoader;
-    }
-
-    /**
-     * Opens the display option dialog, to edit the {@link EventDisplay} objects provided in the
-     * list.
-     * @param logParser
-     * @param displayList
-     * @param eventList
-     * @return true if the list of {@link EventDisplay} objects was updated.
-     */
-    boolean open(EventLogParser logParser, ArrayList<EventDisplay> displayList,
-            ArrayList<EventContainer> eventList) {
-        mLogParser = logParser;
-
-        if (logParser != null) {
-            // we need 2 things from the parser.
-            // the event tag / event name map
-            mEventTagMap = logParser.getTagMap();
-            
-            // the event info map
-            mEventDescriptionMap = logParser.getEventInfoMap();
-        }
-
-        // make a copy of the EventDisplay list since we'll use working copies.
-        duplicateEventDisplay(displayList);
-        
-        // build a list of pid from the list of events.
-        buildPidList(eventList);
-
-        createUI();
-
-        if (mParent == null || mShell == null) {
-            return false;
-        }
-
-        // Set the dialog size.
-        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
-        Rectangle r = mParent.getBounds();
-        // get the center new top left.
-        int cx = r.x + r.width/2;
-        int x = cx - DLG_WIDTH / 2;
-        int cy = r.y + r.height/2;
-        int y = cy - DLG_HEIGHT / 2;
-        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
-
-        mShell.layout();
-
-        // actually open the dialog
-        mShell.open();
-
-        // event loop until the dialog is closed.
-        Display display = mParent.getDisplay();
-        while (!mShell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-        
-        return mEditStatus;
-    }
-    
-    ArrayList<EventDisplay> getEventDisplays() {
-        return mDisplayList;
-    }
-    
-    private void createUI() {
-        mParent = getParent();
-        mShell = new Shell(mParent, getStyle());
-        mShell.setText("Event Display Configuration");
-
-        mShell.setLayout(new GridLayout(1, true));
-
-        final Composite topPanel = new Composite(mShell, SWT.NONE);
-        topPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
-        topPanel.setLayout(new GridLayout(2, false));
-        
-        // create the tree on the left and the controls on the right.
-        Composite leftPanel = new Composite(topPanel, SWT.NONE);
-        Composite rightPanel = new Composite(topPanel, SWT.NONE);
-
-        createLeftPanel(leftPanel);
-        createRightPanel(rightPanel);
-
-        mShell.addListener(SWT.Close, new Listener() {
-            public void handleEvent(Event event) {
-                event.doit = true;
-            }
-        });
-        
-        Label separator = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
-        separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        
-        Composite bottomButtons = new Composite(mShell, SWT.NONE);
-        bottomButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        GridLayout gl;
-        bottomButtons.setLayout(gl = new GridLayout(2, true));
-        gl.marginHeight = gl.marginWidth = 0;
-        
-        Button okButton = new Button(bottomButtons, SWT.PUSH);
-        okButton.setText("OK");
-        okButton.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mShell.close();
-            }
-        });
-
-        Button cancelButton = new Button(bottomButtons, SWT.PUSH);
-        cancelButton.setText("Cancel");
-        cancelButton.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // cancel the modification flag.
-                mEditStatus = false;
-                
-                // and close
-                mShell.close();
-            }
-        });
-
-        enable(false);
-        
-        // fill the list with the current display
-        fillEventDisplayList();
-    }
-
-    private void createLeftPanel(Composite leftPanel) {
-        final IPreferenceStore store = DdmUiPreferences.getStore();
-
-        GridLayout gl;
-
-        leftPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-        leftPanel.setLayout(gl = new GridLayout(1, false));
-        gl.verticalSpacing = 1;
-
-        mEventDisplayList = new List(leftPanel,
-                SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL | SWT.FULL_SELECTION);
-        mEventDisplayList.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mEventDisplayList.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                handleEventDisplaySelection();
-            }
-        });
-
-        Composite bottomControls = new Composite(leftPanel, SWT.NONE);
-        bottomControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        bottomControls.setLayout(gl = new GridLayout(5, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        gl.verticalSpacing = 0;
-        gl.horizontalSpacing = 0;
-
-        mEventDisplayNewButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
-        mEventDisplayNewButton.setImage(mImageLoader.loadImage("add.png", // $NON-NLS-1$
-                leftPanel.getDisplay()));
-        mEventDisplayNewButton.setToolTipText("Adds a new event display");
-        mEventDisplayNewButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
-        mEventDisplayNewButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                createNewEventDisplay();
-            }
-        });
-        
-        mEventDisplayDeleteButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
-        mEventDisplayDeleteButton.setImage(mImageLoader.loadImage("delete.png", // $NON-NLS-1$
-                leftPanel.getDisplay()));
-        mEventDisplayDeleteButton.setToolTipText("Deletes the selected event display");
-        mEventDisplayDeleteButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
-        mEventDisplayDeleteButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                deleteEventDisplay();
-            }
-        });
-
-        mEventDisplayUpButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
-        mEventDisplayUpButton.setImage(mImageLoader.loadImage("up.png", // $NON-NLS-1$
-                leftPanel.getDisplay()));
-        mEventDisplayUpButton.setToolTipText("Moves the selected event display up");
-        mEventDisplayUpButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // get current selection.
-                int selection = mEventDisplayList.getSelectionIndex();
-                if (selection > 0) {
-                    // update the list of EventDisplay.
-                    EventDisplay display = mDisplayList.remove(selection);
-                    mDisplayList.add(selection - 1, display);
-                    
-                    // update the list widget
-                    mEventDisplayList.remove(selection);
-                    mEventDisplayList.add(display.getName(), selection - 1);
-                    
-                    // update the selection and reset the ui.
-                    mEventDisplayList.select(selection - 1);
-                    handleEventDisplaySelection();
-                    mEventDisplayList.showSelection();
-
-                    setModified();
-                }
-            }
-        });
-
-        mEventDisplayDownButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
-        mEventDisplayDownButton.setImage(mImageLoader.loadImage("down.png", // $NON-NLS-1$
-                leftPanel.getDisplay()));
-        mEventDisplayDownButton.setToolTipText("Moves the selected event display down");
-        mEventDisplayDownButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // get current selection.
-                int selection = mEventDisplayList.getSelectionIndex();
-                if (selection != -1 && selection < mEventDisplayList.getItemCount() - 1) {
-                    // update the list of EventDisplay.
-                    EventDisplay display = mDisplayList.remove(selection);
-                    mDisplayList.add(selection + 1, display);
-                    
-                    // update the list widget
-                    mEventDisplayList.remove(selection);
-                    mEventDisplayList.add(display.getName(), selection + 1);
-                    
-                    // update the selection and reset the ui.
-                    mEventDisplayList.select(selection + 1);
-                    handleEventDisplaySelection();
-                    mEventDisplayList.showSelection();
-
-                    setModified();
-                }
-            }
-        });
-        
-        Group sizeGroup = new Group(leftPanel, SWT.NONE);
-        sizeGroup.setText("Display Size:");
-        sizeGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        sizeGroup.setLayout(new GridLayout(2, false));
-
-        Label l = new Label(sizeGroup, SWT.NONE);
-        l.setText("Width:");
-        
-        mDisplayWidthText = new Text(sizeGroup, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
-        mDisplayWidthText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mDisplayWidthText.setText(Integer.toString(
-                store.getInt(EventLogPanel.PREFS_DISPLAY_WIDTH)));
-        mDisplayWidthText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                String text = mDisplayWidthText.getText().trim();
-                try {
-                    store.setValue(EventLogPanel.PREFS_DISPLAY_WIDTH, Integer.parseInt(text));
-                    setModified();
-                } catch (NumberFormatException nfe) {
-                    // do something?
-                }
-            }
-        });
-
-        l = new Label(sizeGroup, SWT.NONE);
-        l.setText("Height:");
-
-        mDisplayHeightText = new Text(sizeGroup, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
-        mDisplayHeightText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mDisplayHeightText.setText(Integer.toString(
-                store.getInt(EventLogPanel.PREFS_DISPLAY_HEIGHT)));
-        mDisplayHeightText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                String text = mDisplayHeightText.getText().trim();
-                try {
-                    store.setValue(EventLogPanel.PREFS_DISPLAY_HEIGHT, Integer.parseInt(text));
-                    setModified();
-                } catch (NumberFormatException nfe) {
-                    // do something?
-                }
-            }
-        });
-    }
-
-    private void createRightPanel(Composite rightPanel) {
-        rightPanel.setLayout(new GridLayout(1, true));
-        rightPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        mInfoGroup = new Group(rightPanel, SWT.NONE);
-        mInfoGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mInfoGroup.setLayout(new GridLayout(2, false));
-        
-        Label nameLabel = new Label(mInfoGroup, SWT.LEFT);
-        nameLabel.setText("Name:");
-
-        mDisplayNameText = new Text(mInfoGroup, SWT.BORDER | SWT.LEFT | SWT.SINGLE);
-        mDisplayNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mDisplayNameText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                if (mProcessTextChanges) {
-                    EventDisplay eventDisplay = getCurrentEventDisplay();
-                    if (eventDisplay != null) {
-                        eventDisplay.setName(mDisplayNameText.getText());
-                        int index = mEventDisplayList.getSelectionIndex();
-                        mEventDisplayList.remove(index);
-                        mEventDisplayList.add(eventDisplay.getName(), index);
-                        mEventDisplayList.select(index);
-                        handleEventDisplaySelection();
-                        setModified();
-                    }
-                }
-            }
-        });
-
-        Label displayLabel = new Label(mInfoGroup, SWT.LEFT);
-        displayLabel.setText("Type:");
-        
-        mDisplayTypeCombo = new Combo(mInfoGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
-        mDisplayTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        // add the combo values. This must match the values EventDisplay.DISPLAY_TYPE_*
-        mDisplayTypeCombo.add("Log All");
-        mDisplayTypeCombo.add("Filtered Log");
-        mDisplayTypeCombo.add("Graph");
-        mDisplayTypeCombo.add("Sync");
-        mDisplayTypeCombo.add("Sync Histogram");
-        mDisplayTypeCombo.add("Sync Performance");
-        mDisplayTypeCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                EventDisplay eventDisplay = getCurrentEventDisplay();
-                if (eventDisplay != null && eventDisplay.getDisplayType() != mDisplayTypeCombo.getSelectionIndex()) {
-                    /* Replace the EventDisplay object with a different subclass */
-                    setModified();
-                    String name = eventDisplay.getName();
-                    EventDisplay newEventDisplay = EventDisplay.eventDisplayFactory(mDisplayTypeCombo.getSelectionIndex(), name);
-                    setCurrentEventDisplay(newEventDisplay);
-                    fillUiWith(newEventDisplay);
-                }
-            }
-        });
-        
-        mChartOptions = new Group(mInfoGroup, SWT.NONE);
-        mChartOptions.setText("Chart Options");
-        GridData gd;
-        mChartOptions.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-        mChartOptions.setLayout(new GridLayout(2, false));
-        
-        Label l = new Label(mChartOptions, SWT.NONE);
-        l.setText("Time Limit (seconds):");
-        
-        mTimeLimitText = new Text(mChartOptions, SWT.BORDER);
-        mTimeLimitText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mTimeLimitText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent arg0) {
-                String text = mTimeLimitText.getText().trim();
-                EventDisplay eventDisplay = getCurrentEventDisplay();
-                if (eventDisplay != null) {
-                    try {
-                        if (text.length() == 0) {
-                            eventDisplay.resetChartTimeLimit();
-                        } else {
-                            eventDisplay.setChartTimeLimit(Long.parseLong(text));
-                        }
-                    } catch (NumberFormatException nfe) {
-                        eventDisplay.resetChartTimeLimit();
-                    } finally {
-                        setModified();
-                    }
-                }
-            }
-        });
-
-        mHistOptions = new Group(mInfoGroup, SWT.NONE);
-        mHistOptions.setText("Histogram Options");
-        GridData gdh;
-        mHistOptions.setLayoutData(gdh = new GridData(GridData.FILL_HORIZONTAL));
-        gdh.horizontalSpan = 2;
-        mHistOptions.setLayout(new GridLayout(2, false));
-        
-        Label lh = new Label(mHistOptions, SWT.NONE);
-        lh.setText("Histogram width (hours):");
-        
-        mHistWidthText = new Text(mHistOptions, SWT.BORDER);
-        mHistWidthText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mHistWidthText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent arg0) {
-                String text = mHistWidthText.getText().trim();
-                EventDisplay eventDisplay = getCurrentEventDisplay();
-                if (eventDisplay != null) {
-                    try {
-                        if (text.length() == 0) {
-                            eventDisplay.resetHistWidth();
-                        } else {
-                            eventDisplay.setHistWidth(Long.parseLong(text));
-                        }
-                    } catch (NumberFormatException nfe) {
-                        eventDisplay.resetHistWidth();
-                    } finally {
-                        setModified();
-                    }
-                }
-            }
-        });
-
-        mPidFilterCheckBox = new Button(mInfoGroup, SWT.CHECK);
-        mPidFilterCheckBox.setText("Enable filtering by pid");
-        mPidFilterCheckBox.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-        mPidFilterCheckBox.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                EventDisplay eventDisplay = getCurrentEventDisplay();
-                if (eventDisplay != null) {
-                    eventDisplay.setPidFiltering(mPidFilterCheckBox.getSelection());
-                    mPidText.setEnabled(mPidFilterCheckBox.getSelection());
-                    setModified();
-                }
-            }
-        });
-
-        Label pidLabel = new Label(mInfoGroup, SWT.NONE);
-        pidLabel.setText("Pid Filter:");
-        pidLabel.setToolTipText("Enter all pids, separated by commas");
-        
-        mPidText = new Text(mInfoGroup, SWT.BORDER);
-        mPidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mPidText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                if (mProcessTextChanges) {
-                    EventDisplay eventDisplay = getCurrentEventDisplay();
-                    if (eventDisplay != null && eventDisplay.getPidFiltering()) {
-                        String pidText = mPidText.getText().trim();
-                        String[] pids = pidText.split("\\s*,\\s*"); //$NON-NLS-1$
-    
-                        ArrayList<Integer> list = new ArrayList<Integer>();
-                        for (String pid : pids) {
-                            try {
-                                list.add(Integer.valueOf(pid));
-                            } catch (NumberFormatException nfe) {
-                                // just ignore non valid pid
-                            }
-                        }
-                        
-                        eventDisplay.setPidFilterList(list);
-                        setModified();
-                    }
-                }
-            }
-        });
-        
-        /* ------------------
-         * EVENT VALUE/OCCURRENCE SELECTION
-         * ------------------ */
-        mValueSelection = createEventSelection(rightPanel, ValueDisplayDescriptor.class,
-                "Event Value Display");
-        mOccurrenceSelection = createEventSelection(rightPanel, OccurrenceDisplayDescriptor.class,
-                "Event Occurrence Display");
-    }
-
-    private SelectionWidgets createEventSelection(Composite rightPanel,
-            final Class<? extends OccurrenceDisplayDescriptor> descriptorClass,
-            String groupMessage) {
-
-        Group eventSelectionPanel = new Group(rightPanel, SWT.NONE);
-        eventSelectionPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
-        GridLayout gl;
-        eventSelectionPanel.setLayout(gl = new GridLayout(2, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        eventSelectionPanel.setText(groupMessage);
-        
-        final SelectionWidgets widgets = new SelectionWidgets();
-        
-        widgets.mList = new List(eventSelectionPanel, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL);
-        widgets.mList.setLayoutData(new GridData(GridData.FILL_BOTH));
-        widgets.mList.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                int index = widgets.mList.getSelectionIndex();
-                if (index != -1) {
-                    widgets.mDeleteButton.setEnabled(true);
-                    widgets.mEditButton.setEnabled(true);
-                } else {
-                    widgets.mDeleteButton.setEnabled(false);
-                    widgets.mEditButton.setEnabled(false);
-                }
-            }
-        });
-
-        Composite rightControls = new Composite(eventSelectionPanel, SWT.NONE);
-        rightControls.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-        rightControls.setLayout(gl = new GridLayout(1, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        gl.verticalSpacing = 0;
-        gl.horizontalSpacing = 0;
-
-        widgets.mNewButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
-        widgets.mNewButton.setText("New...");
-        widgets.mNewButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        widgets.mNewButton.setEnabled(false);
-        widgets.mNewButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // current event
-                try {
-                    EventDisplay eventDisplay = getCurrentEventDisplay();
-                    if (eventDisplay != null) {
-                        EventValueSelector dialog = new EventValueSelector(mShell);
-                        if (dialog.open(descriptorClass, mLogParser)) {
-                            eventDisplay.addDescriptor(dialog.getDescriptor());
-                            fillUiWith(eventDisplay);
-                            setModified();
-                        }
-                    }
-                } catch (Exception e1) {
-                    e1.printStackTrace();
-                }
-            }
-        });
-
-        widgets.mEditButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
-        widgets.mEditButton.setText("Edit...");
-        widgets.mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        widgets.mEditButton.setEnabled(false);
-        widgets.mEditButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // current event
-                EventDisplay eventDisplay = getCurrentEventDisplay();
-                if (eventDisplay != null) {
-                    // get the current descriptor index
-                    int index = widgets.mList.getSelectionIndex();
-                    if (index != -1) {
-                        // get the descriptor itself
-                        OccurrenceDisplayDescriptor descriptor = eventDisplay.getDescriptor(
-                                descriptorClass, index);
-    
-                        // open the edit dialog.
-                        EventValueSelector dialog = new EventValueSelector(mShell);
-                        if (dialog.open(descriptor, mLogParser)) {
-                            descriptor.replaceWith(dialog.getDescriptor());
-                            eventDisplay.updateValueDescriptorCheck();
-                            fillUiWith(eventDisplay);
-
-                            // reselect the item since fillUiWith remove the selection.
-                            widgets.mList.select(index);
-                            widgets.mList.notifyListeners(SWT.Selection, null);
-                            
-                            setModified();
-                        }
-                    }
-                }
-            }
-        });
-
-        widgets.mDeleteButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
-        widgets.mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        widgets.mDeleteButton.setText("Delete");
-        widgets.mDeleteButton.setEnabled(false);
-        widgets.mDeleteButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // current event
-                EventDisplay eventDisplay = getCurrentEventDisplay();
-                if (eventDisplay != null) {
-                    // get the current descriptor index
-                    int index = widgets.mList.getSelectionIndex();
-                    if (index != -1) {
-                        eventDisplay.removeDescriptor(descriptorClass, index);
-                        fillUiWith(eventDisplay);
-                        setModified();
-                    }
-                }
-            }
-        });
-
-        return widgets;
-    }
-   
-    
-    private void duplicateEventDisplay(ArrayList<EventDisplay> displayList) {
-        for (EventDisplay eventDisplay : displayList) {
-            mDisplayList.add(EventDisplay.clone(eventDisplay));
-        }
-    }
-    
-    private void buildPidList(ArrayList<EventContainer> eventList) {
-        mPidList = new ArrayList<Integer>();
-        for (EventContainer event : eventList) {
-            if (mPidList.indexOf(event.pid) == -1) {
-                mPidList.add(event.pid);
-            }
-        }
-    }
-
-    private void setModified() {
-        mEditStatus = true;
-    }
-
-    
-    private void enable(boolean status) {
-        mEventDisplayDeleteButton.setEnabled(status);
-
-        // enable up/down
-        int selection = mEventDisplayList.getSelectionIndex();
-        int count = mEventDisplayList.getItemCount();
-        mEventDisplayUpButton.setEnabled(status && selection > 0);
-        mEventDisplayDownButton.setEnabled(status && selection != -1 && selection < count - 1);
-
-        mDisplayNameText.setEnabled(status);
-        mDisplayTypeCombo.setEnabled(status);
-        mPidFilterCheckBox.setEnabled(status);
-
-        mValueSelection.setEnabled(status);
-        mOccurrenceSelection.setEnabled(status);
-        mValueSelection.mNewButton.setEnabled(status);
-        mOccurrenceSelection.mNewButton.setEnabled(status);
-        if (status == false) {
-            mPidText.setEnabled(false);
-        }
-    }
-    
-    private void fillEventDisplayList() {
-        for (EventDisplay eventDisplay : mDisplayList) {
-            mEventDisplayList.add(eventDisplay.getName());
-        }
-    }
-    
-    private void createNewEventDisplay() {
-        int count = mDisplayList.size();
-        
-        String name = String.format("display %1$d", count + 1);
-        
-        EventDisplay eventDisplay = EventDisplay.eventDisplayFactory(0 /* type*/, name);
-        
-        mDisplayList.add(eventDisplay);
-        mEventDisplayList.add(name);
-        
-        mEventDisplayList.select(count);
-        handleEventDisplaySelection();
-        mEventDisplayList.showSelection();
-        
-        setModified();
-    }
-    
-    private void deleteEventDisplay() {
-        int selection = mEventDisplayList.getSelectionIndex();
-        if (selection != -1) {
-            mDisplayList.remove(selection);
-            mEventDisplayList.remove(selection);
-            if (mDisplayList.size() < selection) {
-                selection--;
-            }
-            mEventDisplayList.select(selection);
-            handleEventDisplaySelection();
-
-            setModified();
-        }
-    }
-
-    private EventDisplay getCurrentEventDisplay() {
-        int selection = mEventDisplayList.getSelectionIndex();
-        if (selection != -1) {
-            return mDisplayList.get(selection);
-        }
-        
-        return null;
-    }
-
-    private void setCurrentEventDisplay(EventDisplay eventDisplay) {
-        int selection = mEventDisplayList.getSelectionIndex();
-        if (selection != -1) {
-            mDisplayList.set(selection, eventDisplay);
-        }
-    }
-    
-    private void handleEventDisplaySelection() {
-        EventDisplay eventDisplay = getCurrentEventDisplay();
-        if (eventDisplay != null) {
-            // enable the UI
-            enable(true);
-
-            // and fill it
-            fillUiWith(eventDisplay);
-        } else {
-            // disable the UI
-            enable(false);
-
-            // and empty it.
-            emptyUi();
-        }
-    }
-
-    private void emptyUi() {
-        mDisplayNameText.setText("");
-        mDisplayTypeCombo.clearSelection();
-        mValueSelection.mList.removeAll();
-        mOccurrenceSelection.mList.removeAll();
-    }
-
-    private void fillUiWith(EventDisplay eventDisplay) {
-        mProcessTextChanges = false;
-
-        mDisplayNameText.setText(eventDisplay.getName());
-        int displayMode = eventDisplay.getDisplayType();
-        mDisplayTypeCombo.select(displayMode);
-        if (displayMode == EventDisplay.DISPLAY_TYPE_GRAPH) {
-            GridData gd = (GridData) mChartOptions.getLayoutData();
-            gd.exclude = false;
-            mChartOptions.setVisible(!gd.exclude);
-            long limit = eventDisplay.getChartTimeLimit();
-            if (limit != -1) {
-                mTimeLimitText.setText(Long.toString(limit));
-            } else {
-                mTimeLimitText.setText(""); //$NON-NLS-1$
-            }
-        } else {
-            GridData gd = (GridData) mChartOptions.getLayoutData();
-            gd.exclude = true;
-            mChartOptions.setVisible(!gd.exclude);
-            mTimeLimitText.setText(""); //$NON-NLS-1$
-        }
-
-        if (displayMode == EventDisplay.DISPLAY_TYPE_SYNC_HIST) {
-            GridData gd = (GridData) mHistOptions.getLayoutData();
-            gd.exclude = false;
-            mHistOptions.setVisible(!gd.exclude);
-            long limit = eventDisplay.getHistWidth();
-            if (limit != -1) {
-                mHistWidthText.setText(Long.toString(limit));
-            } else {
-                mHistWidthText.setText(""); //$NON-NLS-1$
-            }
-        } else {
-            GridData gd = (GridData) mHistOptions.getLayoutData();
-            gd.exclude = true;
-            mHistOptions.setVisible(!gd.exclude);
-            mHistWidthText.setText(""); //$NON-NLS-1$
-        }
-        mInfoGroup.layout(true);
-        mShell.layout(true);
-        mShell.pack();
-        
-        if (eventDisplay.getPidFiltering()) {
-            mPidFilterCheckBox.setSelection(true);
-            mPidText.setEnabled(true);
-
-            // build the pid list.
-            ArrayList<Integer> list = eventDisplay.getPidFilterList();
-            if (list != null) {
-                StringBuilder sb = new StringBuilder();
-                int count = list.size();
-                for (int i = 0 ; i < count ; i++) {
-                    sb.append(list.get(i));
-                    if (i < count - 1) {
-                        sb.append(", ");//$NON-NLS-1$
-                    }
-                }
-                mPidText.setText(sb.toString());
-            } else {
-                mPidText.setText(""); //$NON-NLS-1$
-            }
-        } else {
-            mPidFilterCheckBox.setSelection(false);
-            mPidText.setEnabled(false);
-            mPidText.setText(""); //$NON-NLS-1$
-        }
-
-        mProcessTextChanges = true;
-
-        mValueSelection.mList.removeAll();
-        mOccurrenceSelection.mList.removeAll();
-        
-        if (eventDisplay.getDisplayType() == EventDisplay.DISPLAY_TYPE_FILTERED_LOG ||
-                eventDisplay.getDisplayType() == EventDisplay.DISPLAY_TYPE_GRAPH) {
-            mOccurrenceSelection.setEnabled(true);
-            mValueSelection.setEnabled(true);
-
-            Iterator<ValueDisplayDescriptor> valueIterator = eventDisplay.getValueDescriptors();
-    
-            while (valueIterator.hasNext()) {
-                ValueDisplayDescriptor descriptor = valueIterator.next();
-                mValueSelection.mList.add(String.format("%1$s: %2$s [%3$s]%4$s",
-                        mEventTagMap.get(descriptor.eventTag), descriptor.valueName,
-                        getSeriesLabelDescription(descriptor), getFilterDescription(descriptor)));
-            }
-
-            Iterator<OccurrenceDisplayDescriptor> occurrenceIterator =
-                eventDisplay.getOccurrenceDescriptors();
-    
-            while (occurrenceIterator.hasNext()) {
-                OccurrenceDisplayDescriptor descriptor = occurrenceIterator.next();
-    
-                mOccurrenceSelection.mList.add(String.format("%1$s [%2$s]%3$s",
-                        mEventTagMap.get(descriptor.eventTag),
-                        getSeriesLabelDescription(descriptor),
-                        getFilterDescription(descriptor)));
-            }
-
-            mValueSelection.mList.notifyListeners(SWT.Selection, null);
-            mOccurrenceSelection.mList.notifyListeners(SWT.Selection, null);
-        } else {
-            mOccurrenceSelection.setEnabled(false);
-            mValueSelection.setEnabled(false);
-        }
-        
-    }
-    
-    /**
-     * Returns a String describing what is used as the series label
-     * @param descriptor the descriptor of the display.
-     */
-    private String getSeriesLabelDescription(OccurrenceDisplayDescriptor descriptor) {
-        if (descriptor.seriesValueIndex != -1) {
-            if (descriptor.includePid) {
-                return String.format("%1$s + pid",
-                        mEventDescriptionMap.get(
-                                descriptor.eventTag)[descriptor.seriesValueIndex].getName());
-            } else {
-                return mEventDescriptionMap.get(descriptor.eventTag)[descriptor.seriesValueIndex]
-                                                                     .getName();
-            }
-        }
-        return "pid";
-    }
-    
-    private String getFilterDescription(OccurrenceDisplayDescriptor descriptor) {
-        if (descriptor.filterValueIndex != -1) {
-            return String.format(" [%1$s %2$s %3$s]",
-                    mEventDescriptionMap.get(
-                            descriptor.eventTag)[descriptor.filterValueIndex].getName(),
-                            descriptor.filterCompareMethod.testString(),
-                            descriptor.filterValue != null ?
-                                    descriptor.filterValue.toString() : "?"); //$NON-NLS-1$
-        }
-        return ""; //$NON-NLS-1$
-    }
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogImporter.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogImporter.java
deleted file mode 100644
index a1303f6..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogImporter.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.Log;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-
-/**
- * Imports a textual event log.  Gets tags from build path.
- */
-public class EventLogImporter {
-
-    private String[] mTags;
-    private String[] mLog;
-
-    public EventLogImporter(String filePath) throws FileNotFoundException {
-        String top = System.getenv("ANDROID_BUILD_TOP");
-        if (top == null) {
-            throw new FileNotFoundException();
-        }
-        final String tagFile = top + "/system/core/logcat/event-log-tags";
-        BufferedReader tagReader = new BufferedReader(
-                new InputStreamReader(new FileInputStream(tagFile)));
-        BufferedReader eventReader = new BufferedReader(
-                new InputStreamReader(new FileInputStream(filePath)));
-        try {
-            readTags(tagReader);
-            readLog(eventReader);
-        } catch (IOException e) {
-        }
-    }
-
-    public String[] getTags() {
-        return mTags;
-    }
-
-    public String[] getLog() {
-        return mLog;
-    }
-
-    private void readTags(BufferedReader reader) throws IOException {
-        String line;
-
-        ArrayList<String> content = new ArrayList<String>();
-        while ((line = reader.readLine()) != null) {
-            content.add(line);
-        }
-        mTags = content.toArray(new String[content.size()]);
-    }
-
-    private void readLog(BufferedReader reader) throws IOException {
-        String line;
-
-        ArrayList<String> content = new ArrayList<String>();
-        while ((line = reader.readLine()) != null) {
-            content.add(line);
-        }
-
-        mLog = content.toArray(new String[content.size()]);
-    }
-
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogPanel.java
deleted file mode 100644
index 11138d1..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogPanel.java
+++ /dev/null
@@ -1,926 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.LogReceiver;
-import com.android.ddmlib.log.LogReceiver.ILogListener;
-import com.android.ddmlib.log.LogReceiver.LogEntry;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.IImageLoader;
-import com.android.ddmuilib.TablePanel;
-import com.android.ddmuilib.actions.ICommonAction;
-import com.android.ddmuilib.annotation.UiThread;
-import com.android.ddmuilib.annotation.WorkerThread;
-import com.android.ddmuilib.log.event.EventDisplay.ILogColumnListener;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.RowData;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.regex.Pattern;
-
-/**
- * Event log viewer
- */
-public class EventLogPanel extends TablePanel implements ILogListener,
-        ILogColumnListener {
-
-    private final static String TAG_FILE_EXT = ".tag"; //$NON-NLS-1$
-
-    private final static String PREFS_EVENT_DISPLAY = "EventLogPanel.eventDisplay"; //$NON-NLS-1$
-    private final static String EVENT_DISPLAY_STORAGE_SEPARATOR = "|"; //$NON-NLS-1$
-
-    static final String PREFS_DISPLAY_WIDTH = "EventLogPanel.width"; //$NON-NLS-1$
-    static final String PREFS_DISPLAY_HEIGHT = "EventLogPanel.height"; //$NON-NLS-1$
-
-    private final static int DEFAULT_DISPLAY_WIDTH = 500;
-    private final static int DEFAULT_DISPLAY_HEIGHT = 400;
-
-    private IImageLoader mImageLoader;
-
-    private IDevice mCurrentLoggedDevice;
-    private String mCurrentLogFile;
-    private LogReceiver mCurrentLogReceiver;
-    private EventLogParser mCurrentEventLogParser;
-
-    private Object mLock = new Object();
-
-    /** list of all the events. */
-    private final ArrayList<EventContainer> mEvents = new ArrayList<EventContainer>();
-
-    /** list of all the new events, that have yet to be displayed by the ui */
-    private final ArrayList<EventContainer> mNewEvents = new ArrayList<EventContainer>();
-    /** indicates a pending ui thread display */
-    private boolean mPendingDisplay = false;
-
-    /** list of all the custom event displays */
-    private final ArrayList<EventDisplay> mEventDisplays = new ArrayList<EventDisplay>();
-
-    private final NumberFormat mFormatter = NumberFormat.getInstance();
-    private Composite mParent;
-    private ScrolledComposite mBottomParentPanel;
-    private Composite mBottomPanel;
-    private ICommonAction mOptionsAction;
-    private ICommonAction mClearAction;
-    private ICommonAction mSaveAction;
-    private ICommonAction mLoadAction;
-    private ICommonAction mImportAction;
-
-    /** file containing the current log raw data. */
-    private File mTempFile = null;
-
-    public EventLogPanel(IImageLoader imageLoader) {
-        super();
-        mImageLoader = imageLoader;
-        mFormatter.setGroupingUsed(true);
-    }
-
-    /**
-     * Sets the external actions.
-     * <p/>This method sets up the {@link ICommonAction} objects to execute the proper code
-     * when triggered by using {@link ICommonAction#setRunnable(Runnable)}.
-     * <p/>It will also make sure they are enabled only when possible.
-     * @param optionsAction
-     * @param clearAction
-     * @param saveAction
-     * @param loadAction
-     * @param importAction
-     */
-    public void setActions(ICommonAction optionsAction, ICommonAction clearAction,
-            ICommonAction saveAction, ICommonAction loadAction, ICommonAction importAction) {
-        mOptionsAction = optionsAction;
-        mOptionsAction.setRunnable(new Runnable() {
-            public void run() {
-                openOptionPanel();
-            }
-        });
-
-        mClearAction = clearAction;
-        mClearAction.setRunnable(new Runnable() {
-            public void run() {
-                clearLog();
-            }
-        });
-
-        mSaveAction = saveAction;
-        mSaveAction.setRunnable(new Runnable() {
-            public void run() {
-                try {
-                    FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.SAVE);
-
-                    fileDialog.setText("Save Event Log");
-                    fileDialog.setFileName("event.log");
-
-                    String fileName = fileDialog.open();
-                    if (fileName != null) {
-                        saveLog(fileName);
-                    }
-                } catch (IOException e1) {
-                }
-            }
-        });
-
-        mLoadAction = loadAction;
-        mLoadAction.setRunnable(new Runnable() {
-            public void run() {
-                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
-
-                fileDialog.setText("Load Event Log");
-
-                String fileName = fileDialog.open();
-                if (fileName != null) {
-                    loadLog(fileName);
-                }
-            }
-        });
-
-        mImportAction = importAction;
-        mImportAction.setRunnable(new Runnable() {
-            public void run() {
-                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
-
-                fileDialog.setText("Import Bug Report");
-
-                String fileName = fileDialog.open();
-                if (fileName != null) {
-                    importBugReport(fileName);
-                }
-            }
-        });
-
-        mOptionsAction.setEnabled(false);
-        mClearAction.setEnabled(false);
-        mSaveAction.setEnabled(false);
-    }
-
-    /**
-     * Opens the option panel.
-     * </p>
-     * <b>This must be called from the UI thread</b>
-     */
-    @UiThread
-    public void openOptionPanel() {
-        try {
-            EventDisplayOptions dialog = new EventDisplayOptions(mImageLoader, mParent.getShell());
-            if (dialog.open(mCurrentEventLogParser, mEventDisplays, mEvents)) {
-                synchronized (mLock) {
-                    // get the new EventDisplay list
-                    mEventDisplays.clear();
-                    mEventDisplays.addAll(dialog.getEventDisplays());
-
-                    // since the list of EventDisplay changed, we store it.
-                    saveEventDisplays();
-
-                    rebuildUi();
-                }
-            }
-        } catch (SWTException e) {
-            Log.e("EventLog", e); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Clears the log.
-     * <p/>
-     * <b>This must be called from the UI thread</b>
-     */
-    public void clearLog() {
-        try {
-            synchronized (mLock) {
-                mEvents.clear();
-                mNewEvents.clear();
-                mPendingDisplay = false;
-                for (EventDisplay eventDisplay : mEventDisplays) {
-                    eventDisplay.resetUI();
-                }
-            }
-        } catch (SWTException e) {
-            Log.e("EventLog", e); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Saves the content of the event log into a file. The log is saved in the same
-     * binary format than on the device.
-     * @param filePath
-     * @throws IOException
-     */
-    public void saveLog(String filePath) throws IOException {
-        if (mCurrentLoggedDevice != null && mCurrentEventLogParser != null) {
-            File destFile = new File(filePath);
-            destFile.createNewFile();
-            FileInputStream fis = new FileInputStream(mTempFile);
-            FileOutputStream fos = new FileOutputStream(destFile);
-            byte[] buffer = new byte[1024];
-
-            int count;
-
-            while ((count = fis.read(buffer)) != -1) {
-                fos.write(buffer, 0, count);
-            }
-
-            fos.close();
-            fis.close();
-
-            // now we save the tag file
-            filePath = filePath + TAG_FILE_EXT;
-            mCurrentEventLogParser.saveTags(filePath);
-        }
-    }
-
-    /**
-     * Loads a binary event log (if has associated .tag file) or
-     * otherwise loads a textual event log.
-     * @param filePath Event log path (and base of potential tag file)
-     */
-    public void loadLog(String filePath) {
-        if ((new File(filePath + TAG_FILE_EXT)).exists()) {
-            startEventLogFromFiles(filePath);
-        } else {
-            try {
-                EventLogImporter importer = new EventLogImporter(filePath);
-                String[] tags = importer.getTags();
-                String[] log = importer.getLog();
-                startEventLogFromContent(tags, log);
-            } catch (FileNotFoundException e) {
-                // If this fails, display the error message from startEventLogFromFiles,
-                // and pretend we never tried EventLogImporter
-                Log.logAndDisplay(Log.LogLevel.ERROR, "EventLog",
-                        String.format("Failure to read %1$s", filePath + TAG_FILE_EXT));
-            }
-
-        }
-    }
-
-    public void importBugReport(String filePath) {
-        try {
-            BugReportImporter importer = new BugReportImporter(filePath);
-
-            String[] tags = importer.getTags();
-            String[] log = importer.getLog();
-
-            startEventLogFromContent(tags, log);
-
-        } catch (FileNotFoundException e) {
-            Log.logAndDisplay(LogLevel.ERROR, "Import",
-                    "Unable to import bug report: " + e.getMessage());
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmuilib.SelectionDependentPanel#clientSelected()
-     */
-    @Override
-    public void clientSelected() {
-        // pass
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmuilib.SelectionDependentPanel#deviceSelected()
-     */
-    @Override
-    public void deviceSelected() {
-        startEventLog(getCurrentDevice());
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.AndroidDebugBridge.IClientChangeListener#clientChanged(com.android.ddmlib.Client, int)
-     */
-    public void clientChanged(Client client, int changeMask) {
-        // pass
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmuilib.Panel#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        mParent = parent;
-        mParent.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                synchronized (mLock) {
-                    if (mCurrentLogReceiver != null) {
-                        mCurrentLogReceiver.cancel();
-                        mCurrentLogReceiver = null;
-                        mCurrentEventLogParser = null;
-                        mCurrentLoggedDevice = null;
-                        mEventDisplays.clear();
-                        mEvents.clear();
-                    }
-                }
-            }
-        });
-
-        final IPreferenceStore store = DdmUiPreferences.getStore();
-
-        // init some store stuff
-        store.setDefault(PREFS_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH);
-        store.setDefault(PREFS_DISPLAY_HEIGHT, DEFAULT_DISPLAY_HEIGHT);
-
-        mBottomParentPanel = new ScrolledComposite(parent, SWT.V_SCROLL);
-        mBottomParentPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mBottomParentPanel.setExpandHorizontal(true);
-        mBottomParentPanel.setExpandVertical(true);
-
-        mBottomParentPanel.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                if (mBottomPanel != null) {
-                    Rectangle r = mBottomParentPanel.getClientArea();
-                    mBottomParentPanel.setMinSize(mBottomPanel.computeSize(r.width,
-                        SWT.DEFAULT));
-                }
-            }
-        });
-
-        prepareDisplayUi();
-
-        // load the EventDisplay from storage.
-        loadEventDisplays();
-
-        // create the ui
-        createDisplayUi();
-
-        return mBottomParentPanel;
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmuilib.Panel#postCreation()
-     */
-    @Override
-    protected void postCreation() {
-        // pass
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmuilib.Panel#setFocus()
-     */
-    @Override
-    public void setFocus() {
-        mBottomParentPanel.setFocus();
-    }
-
-    /**
-     * Starts a new logcat and set mCurrentLogCat as the current receiver.
-     * @param device the device to connect logcat to.
-     */
-    private void startEventLog(final IDevice device) {
-        if (device == mCurrentLoggedDevice) {
-            return;
-        }
-
-        // if we have a logcat already running
-        if (mCurrentLogReceiver != null) {
-            stopEventLog(false);
-        }
-        mCurrentLoggedDevice = null;
-        mCurrentLogFile = null;
-
-        if (device != null) {
-            // create a new output receiver
-            mCurrentLogReceiver = new LogReceiver(this);
-
-            // start the logcat in a different thread
-            new Thread("EventLog")  { //$NON-NLS-1$
-                @Override
-                public void run() {
-                    while (device.isOnline() == false &&
-                            mCurrentLogReceiver != null &&
-                            mCurrentLogReceiver.isCancelled() == false) {
-                        try {
-                            sleep(2000);
-                        } catch (InterruptedException e) {
-                            return;
-                        }
-                    }
-
-                    if (mCurrentLogReceiver == null || mCurrentLogReceiver.isCancelled()) {
-                        // logcat was stopped/cancelled before the device became ready.
-                        return;
-                    }
-
-                    try {
-                        mCurrentLoggedDevice = device;
-                        synchronized (mLock) {
-                            mCurrentEventLogParser = new EventLogParser();
-                            mCurrentEventLogParser.init(device);
-                        }
-
-                        // update the event display with the new parser.
-                        updateEventDisplays();
-
-                        // prepare the temp file that will contain the raw data
-                        mTempFile = File.createTempFile("android-event-", ".log");
-
-                        device.runEventLogService(mCurrentLogReceiver);
-                    } catch (Exception e) {
-                        Log.e("EventLog", e);
-                    } finally {
-                    }
-                }
-            }.start();
-        }
-    }
-
-    private void startEventLogFromFiles(final String fileName) {
-        // if we have a logcat already running
-        if (mCurrentLogReceiver != null) {
-            stopEventLog(false);
-        }
-        mCurrentLoggedDevice = null;
-        mCurrentLogFile = null;
-
-        // create a new output receiver
-        mCurrentLogReceiver = new LogReceiver(this);
-
-        mSaveAction.setEnabled(false);
-
-        // start the logcat in a different thread
-        new Thread("EventLog")  { //$NON-NLS-1$
-            @Override
-            public void run() {
-                try {
-                    mCurrentLogFile = fileName;
-                    synchronized (mLock) {
-                        mCurrentEventLogParser = new EventLogParser();
-                        if (mCurrentEventLogParser.init(fileName + TAG_FILE_EXT) == false) {
-                            mCurrentEventLogParser = null;
-                            Log.logAndDisplay(LogLevel.ERROR, "EventLog",
-                                    String.format("Failure to read %1$s", fileName + TAG_FILE_EXT));
-                            return;
-                        }
-                    }
-
-                    // update the event display with the new parser.
-                    updateEventDisplays();
-
-                    runLocalEventLogService(fileName, mCurrentLogReceiver);
-                } catch (Exception e) {
-                    Log.e("EventLog", e);
-                } finally {
-                }
-            }
-        }.start();
-    }
-
-    private void startEventLogFromContent(final String[] tags, final String[] log) {
-        // if we have a logcat already running
-        if (mCurrentLogReceiver != null) {
-            stopEventLog(false);
-        }
-        mCurrentLoggedDevice = null;
-        mCurrentLogFile = null;
-
-        // create a new output receiver
-        mCurrentLogReceiver = new LogReceiver(this);
-
-        mSaveAction.setEnabled(false);
-
-        // start the logcat in a different thread
-        new Thread("EventLog")  { //$NON-NLS-1$
-            @Override
-            public void run() {
-                try {
-                    synchronized (mLock) {
-                        mCurrentEventLogParser = new EventLogParser();
-                        if (mCurrentEventLogParser.init(tags) == false) {
-                            mCurrentEventLogParser = null;
-                            return;
-                        }
-                    }
-
-                    // update the event display with the new parser.
-                    updateEventDisplays();
-
-                    runLocalEventLogService(log, mCurrentLogReceiver);
-                } catch (Exception e) {
-                    Log.e("EventLog", e);
-                } finally {
-                }
-            }
-        }.start();
-    }
-
-
-    public void stopEventLog(boolean inUiThread) {
-        if (mCurrentLogReceiver != null) {
-            mCurrentLogReceiver.cancel();
-
-            // when the thread finishes, no one will reference that object
-            // and it'll be destroyed
-            synchronized (mLock) {
-                mCurrentLogReceiver = null;
-                mCurrentEventLogParser = null;
-
-                mCurrentLoggedDevice = null;
-                mEvents.clear();
-                mNewEvents.clear();
-                mPendingDisplay = false;
-            }
-
-            resetUI(inUiThread);
-        }
-
-        if (mTempFile != null) {
-            mTempFile.delete();
-            mTempFile = null;
-        }
-    }
-
-    private void resetUI(boolean inUiThread) {
-        mEvents.clear();
-
-        // the ui is static we just empty it.
-        if (inUiThread) {
-            resetUiFromUiThread();
-        } else {
-            try {
-                Display d = mBottomParentPanel.getDisplay();
-
-                // run sync as we need to update right now.
-                d.syncExec(new Runnable() {
-                    public void run() {
-                        if (mBottomParentPanel.isDisposed() == false) {
-                            resetUiFromUiThread();
-                        }
-                    }
-                });
-            } catch (SWTException e) {
-                // display is disposed, we're quitting. Do nothing.
-            }
-        }
-    }
-
-    private void resetUiFromUiThread() {
-        synchronized(mLock) {
-            for (EventDisplay eventDisplay : mEventDisplays) {
-                eventDisplay.resetUI();
-            }
-        }
-        mOptionsAction.setEnabled(false);
-        mClearAction.setEnabled(false);
-        mSaveAction.setEnabled(false);
-    }
-
-    private void prepareDisplayUi() {
-        mBottomPanel = new Composite(mBottomParentPanel, SWT.NONE);
-        mBottomParentPanel.setContent(mBottomPanel);
-    }
-
-    private void createDisplayUi() {
-        RowLayout rowLayout = new RowLayout();
-        rowLayout.wrap = true;
-        rowLayout.pack = false;
-        rowLayout.justify = true;
-        rowLayout.fill = true;
-        rowLayout.type = SWT.HORIZONTAL;
-        mBottomPanel.setLayout(rowLayout);
-
-        IPreferenceStore store = DdmUiPreferences.getStore();
-        int displayWidth = store.getInt(PREFS_DISPLAY_WIDTH);
-        int displayHeight = store.getInt(PREFS_DISPLAY_HEIGHT);
-
-        for (EventDisplay eventDisplay : mEventDisplays) {
-            Control c = eventDisplay.createComposite(mBottomPanel, mCurrentEventLogParser, this);
-            if (c != null) {
-                RowData rd = new RowData();
-                rd.height = displayHeight;
-                rd.width = displayWidth;
-                c.setLayoutData(rd);
-            }
-
-            Table table = eventDisplay.getTable();
-            if (table != null) {
-                addTableToFocusListener(table);
-            }
-        }
-
-        mBottomPanel.layout();
-        mBottomParentPanel.setMinSize(mBottomPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-        mBottomParentPanel.layout();
-    }
-
-    /**
-     * Rebuild the display ui.
-     */
-    @UiThread
-    private void rebuildUi() {
-        synchronized (mLock) {
-            // we need to rebuild the ui. First we get rid of it.
-            mBottomPanel.dispose();
-            mBottomPanel = null;
-
-            prepareDisplayUi();
-            createDisplayUi();
-
-            // and fill it
-
-            boolean start_event = false;
-            synchronized (mNewEvents) {
-                mNewEvents.addAll(0, mEvents);
-
-                if (mPendingDisplay == false) {
-                    mPendingDisplay = true;
-                    start_event = true;
-                }
-            }
-
-            if (start_event) {
-                scheduleUIEventHandler();
-            }
-
-            Rectangle r = mBottomParentPanel.getClientArea();
-            mBottomParentPanel.setMinSize(mBottomPanel.computeSize(r.width,
-                SWT.DEFAULT));
-        }
-    }
-
-
-    /**
-     * Processes a new {@link LogEntry} by parsing it with {@link EventLogParser} and displaying it.
-     * @param entry The new log entry
-     * @see LogReceiver.ILogListener#newEntry(LogEntry)
-     */
-    @WorkerThread
-    public void newEntry(LogEntry entry) {
-        synchronized (mLock) {
-            if (mCurrentEventLogParser != null) {
-                EventContainer event = mCurrentEventLogParser.parse(entry);
-                if (event != null) {
-                    handleNewEvent(event);
-                }
-            }
-        }
-    }
-
-    @WorkerThread
-    private void handleNewEvent(EventContainer event) {
-        // add the event to the generic list
-        mEvents.add(event);
-
-        // add to the list of events that needs to be displayed, and trigger a
-        // new display if needed.
-        boolean start_event = false;
-        synchronized (mNewEvents) {
-            mNewEvents.add(event);
-
-            if (mPendingDisplay == false) {
-                mPendingDisplay = true;
-                start_event = true;
-            }
-        }
-
-        if (start_event == false) {
-            // we're done
-            return;
-        }
-
-        scheduleUIEventHandler();
-    }
-
-    /**
-     * Schedules the UI thread to execute a {@link Runnable} calling {@link #displayNewEvents()}.
-     */
-    private void scheduleUIEventHandler() {
-        try  {
-            Display d = mBottomParentPanel.getDisplay();
-            d.asyncExec(new Runnable() {
-                public void run() {
-                    if (mBottomParentPanel.isDisposed() == false) {
-                        if (mCurrentEventLogParser != null) {
-                            displayNewEvents();
-                        }
-                    }
-                }
-            });
-        } catch (SWTException e) {
-            // if the ui is disposed, do nothing
-        }
-    }
-
-    /**
-     * Processes raw data coming from the log service.
-     * @see LogReceiver.ILogListener#newData(byte[], int, int)
-     */
-    public void newData(byte[] data, int offset, int length) {
-        if (mTempFile != null) {
-            try {
-                FileOutputStream fos = new FileOutputStream(mTempFile, true /* append */);
-                fos.write(data, offset, length);
-                fos.close();
-            } catch (FileNotFoundException e) {
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    @UiThread
-    private void displayNewEvents() {
-        // never display more than 1,000 events in this loop. We can't do too much in the UI thread.
-        int count = 0;
-
-        // prepare the displays
-        for (EventDisplay eventDisplay : mEventDisplays) {
-            eventDisplay.startMultiEventDisplay();
-        }
-
-        // display the new events
-        EventContainer event = null;
-        boolean need_to_reloop = false;
-        do {
-            // get the next event to display.
-            synchronized (mNewEvents) {
-                if (mNewEvents.size() > 0) {
-                    if (count > 200) {
-                        // there are still events to be displayed, but we don't want to hog the
-                        // UI thread for too long, so we stop this runnable, but launch a new
-                        // one to keep going.
-                        need_to_reloop = true;
-                        event = null;
-                    } else {
-                        event = mNewEvents.remove(0);
-                        count++;
-                    }
-                } else {
-                    // we're done.
-                    event = null;
-                    mPendingDisplay = false;
-                }
-            }
-
-            if (event != null) {
-                // notify the event display
-                for (EventDisplay eventDisplay : mEventDisplays) {
-                    eventDisplay.newEvent(event, mCurrentEventLogParser);
-                }
-            }
-        } while (event != null);
-
-        // we're done displaying events.
-        for (EventDisplay eventDisplay : mEventDisplays) {
-            eventDisplay.endMultiEventDisplay();
-        }
-
-        // if needed, ask the UI thread to re-run this method.
-        if (need_to_reloop) {
-            scheduleUIEventHandler();
-        }
-    }
-
-    /**
-     * Loads the {@link EventDisplay}s from the preference store.
-     */
-    private void loadEventDisplays() {
-        IPreferenceStore store = DdmUiPreferences.getStore();
-        String storage = store.getString(PREFS_EVENT_DISPLAY);
-
-        if (storage.length() > 0) {
-            String[] values = storage.split(Pattern.quote(EVENT_DISPLAY_STORAGE_SEPARATOR));
-
-            for (String value : values) {
-                EventDisplay eventDisplay = EventDisplay.load(value);
-                if (eventDisplay != null) {
-                    mEventDisplays.add(eventDisplay);
-                }
-            }
-        }
-    }
-
-    /**
-     * Saves the {@link EventDisplay}s into the {@link DdmUiPreferences} store.
-     */
-    private void saveEventDisplays() {
-        IPreferenceStore store = DdmUiPreferences.getStore();
-
-        boolean first = true;
-        StringBuilder sb = new StringBuilder();
-
-        for (EventDisplay eventDisplay : mEventDisplays) {
-            String storage = eventDisplay.getStorageString();
-            if (storage != null) {
-                if (first == false) {
-                    sb.append(EVENT_DISPLAY_STORAGE_SEPARATOR);
-                } else {
-                    first = false;
-                }
-
-                sb.append(storage);
-            }
-        }
-
-        store.setValue(PREFS_EVENT_DISPLAY, sb.toString());
-    }
-
-    /**
-     * Updates the {@link EventDisplay} with the new {@link EventLogParser}.
-     * <p/>
-     * This will run asynchronously in the UI thread.
-     */
-    @WorkerThread
-    private void updateEventDisplays() {
-        try {
-            Display d = mBottomParentPanel.getDisplay();
-
-            d.asyncExec(new Runnable() {
-                public void run() {
-                    if (mBottomParentPanel.isDisposed() == false) {
-                        for (EventDisplay eventDisplay : mEventDisplays) {
-                            eventDisplay.setNewLogParser(mCurrentEventLogParser);
-                        }
-
-                        mOptionsAction.setEnabled(true);
-                        mClearAction.setEnabled(true);
-                        if (mCurrentLogFile == null) {
-                            mSaveAction.setEnabled(true);
-                        } else {
-                            mSaveAction.setEnabled(false);
-                        }
-                    }
-                }
-            });
-        } catch (SWTException e) {
-            // display is disposed: do nothing.
-        }
-    }
-
-    @UiThread
-    public void columnResized(int index, TableColumn sourceColumn) {
-        for (EventDisplay eventDisplay : mEventDisplays) {
-            eventDisplay.resizeColumn(index, sourceColumn);
-        }
-    }
-
-    /**
-     * Runs an event log service out of a local file.
-     * @param fileName the full file name of the local file containing the event log.
-     * @param logReceiver the receiver that will handle the log
-     * @throws IOException
-     */
-    @WorkerThread
-    private void runLocalEventLogService(String fileName, LogReceiver logReceiver)
-            throws IOException {
-        byte[] buffer = new byte[256];
-
-        FileInputStream fis = new FileInputStream(fileName);
-
-        int count;
-        while ((count = fis.read(buffer)) != -1) {
-            logReceiver.parseNewData(buffer, 0, count);
-        }
-    }
-
-    @WorkerThread
-    private void runLocalEventLogService(String[] log, LogReceiver currentLogReceiver) {
-        synchronized (mLock) {
-            for (String line : log) {
-                EventContainer event = mCurrentEventLogParser.parse(line);
-                if (event != null) {
-                    handleNewEvent(event);
-                }
-            }
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventValueSelector.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventValueSelector.java
deleted file mode 100644
index dd32e2c..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventValueSelector.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.EventValueDescription;
-import com.android.ddmlib.log.EventContainer.CompareMethod;
-import com.android.ddmlib.log.EventContainer.EventValueType;
-import com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor;
-import com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Set;
-
-final class EventValueSelector extends Dialog {
-    private static final int DLG_WIDTH = 400;
-    private static final int DLG_HEIGHT = 300;
-
-    private Shell mParent;
-    private Shell mShell;
-    private boolean mEditStatus;
-    private Combo mEventCombo;
-    private Combo mValueCombo;
-    private Combo mSeriesCombo;
-    private Button mDisplayPidCheckBox;
-    private Combo mFilterCombo;
-    private Combo mFilterMethodCombo;
-    private Text mFilterValue;
-    private Button mOkButton;
-
-    private EventLogParser mLogParser;
-    private OccurrenceDisplayDescriptor mDescriptor;
-    
-    /** list of event integer in the order of the combo. */
-    private Integer[] mEventTags;
-    
-    /** list of indices in the {@link EventValueDescription} array of the current event
-     * that are of type string. This lets us get back the {@link EventValueDescription} from the
-     * index in the Series {@link Combo}.
-     */
-    private final ArrayList<Integer> mSeriesIndices = new ArrayList<Integer>();
-    
-    public EventValueSelector(Shell parent) {
-        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-    }
-
-    /**
-     * Opens the display option dialog to edit a new descriptor.
-     * @param decriptorClass the class of the object to instantiate. Must extend
-     * {@link OccurrenceDisplayDescriptor}
-     * @param logParser
-     * @return true if the object is to be created, false if the creation was canceled.
-     */
-    boolean open(Class<? extends OccurrenceDisplayDescriptor> descriptorClass,
-            EventLogParser logParser) {
-        try {
-            OccurrenceDisplayDescriptor descriptor = descriptorClass.newInstance();
-            setModified();
-            return open(descriptor, logParser);
-        } catch (InstantiationException e) {
-            return false;
-        } catch (IllegalAccessException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Opens the display option dialog, to edit a {@link OccurrenceDisplayDescriptor} object or
-     * a {@link ValueDisplayDescriptor} object.
-     * @param descriptor The descriptor to edit.
-     * @return true if the object was modified.
-     */
-    boolean open(OccurrenceDisplayDescriptor descriptor, EventLogParser logParser) {
-        // make a copy of the descriptor as we'll use a working copy.
-        if (descriptor instanceof ValueDisplayDescriptor) {
-            mDescriptor = new ValueDisplayDescriptor((ValueDisplayDescriptor)descriptor);
-        } else if (descriptor instanceof OccurrenceDisplayDescriptor) {
-            mDescriptor = new OccurrenceDisplayDescriptor(descriptor);
-        } else {
-            return false;
-        }
-
-        mLogParser = logParser;
-
-        createUI();
-
-        if (mParent == null || mShell == null) {
-            return false;
-        }
-
-        loadValueDescriptor();
-        
-        checkValidity();
-
-        // Set the dialog size.
-        try { 
-            mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
-            Rectangle r = mParent.getBounds();
-            // get the center new top left.
-            int cx = r.x + r.width/2;
-            int x = cx - DLG_WIDTH / 2;
-            int cy = r.y + r.height/2;
-            int y = cy - DLG_HEIGHT / 2;
-            mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        mShell.layout();
-
-        // actually open the dialog
-        mShell.open();
-
-        // event loop until the dialog is closed.
-        Display display = mParent.getDisplay();
-        while (!mShell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-        
-        return mEditStatus;
-    }
-    
-    OccurrenceDisplayDescriptor getDescriptor() {
-        return mDescriptor;
-    }
-    
-    private void createUI() {
-        GridData gd;
-
-        mParent = getParent();
-        mShell = new Shell(mParent, getStyle());
-        mShell.setText("Event Display Configuration");
-
-        mShell.setLayout(new GridLayout(2, false));
-        
-        Label l = new Label(mShell, SWT.NONE);
-        l.setText("Event:");
-        
-        mEventCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mEventCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        // the event tag / event name map
-        Map<Integer, String> eventTagMap = mLogParser.getTagMap();
-        Map<Integer, EventValueDescription[]> eventInfoMap = mLogParser.getEventInfoMap();
-        Set<Integer> keys = eventTagMap.keySet();
-        ArrayList<Integer> list = new ArrayList<Integer>();
-        for (Integer i : keys) {
-            if (eventInfoMap.get(i) != null) {
-                String eventName = eventTagMap.get(i);
-                mEventCombo.add(eventName);
-                
-                list.add(i);
-            }
-        }
-        mEventTags = list.toArray(new Integer[list.size()]);
-        
-        mEventCombo.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                handleEventComboSelection();
-                setModified();
-            }
-        });
-
-        l = new Label(mShell, SWT.NONE);
-        l.setText("Value:");
-        
-        mValueCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mValueCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mValueCombo.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                handleValueComboSelection();
-                setModified();
-            }
-        });
-
-        l = new Label(mShell, SWT.NONE);
-        l.setText("Series Name:");
-
-        mSeriesCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mSeriesCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mSeriesCombo.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                handleSeriesComboSelection();
-                setModified();
-            }
-        });
-
-        // empty comp
-        new Composite(mShell, SWT.NONE).setLayoutData(gd = new GridData());
-        gd.heightHint = gd.widthHint = 0;
-
-        mDisplayPidCheckBox = new Button(mShell, SWT.CHECK);
-        mDisplayPidCheckBox.setText("Also Show pid");
-        mDisplayPidCheckBox.setEnabled(false);
-        mDisplayPidCheckBox.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mDescriptor.includePid = mDisplayPidCheckBox.getSelection();
-                setModified();
-            }
-        });
-
-        l = new Label(mShell, SWT.NONE);
-        l.setText("Filter By:");
-
-        mFilterCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mFilterCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mFilterCombo.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                handleFilterComboSelection();
-                setModified();
-            }
-        });
-
-        l = new Label(mShell, SWT.NONE);
-        l.setText("Filter Method:");
-
-        mFilterMethodCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mFilterMethodCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        for (CompareMethod method : CompareMethod.values()) {
-            mFilterMethodCombo.add(method.toString());
-        }
-        mFilterMethodCombo.select(0);
-        mFilterMethodCombo.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                handleFilterMethodComboSelection();
-                setModified();
-            }
-        });
-
-        l = new Label(mShell, SWT.NONE);
-        l.setText("Filter Value:");
-        
-        mFilterValue = new Text(mShell, SWT.BORDER | SWT.SINGLE);
-        mFilterValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mFilterValue.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                if (mDescriptor.filterValueIndex != -1) {
-                    // get the current selection in the event combo
-                    int index = mEventCombo.getSelectionIndex();
-    
-                    if (index != -1) {
-                        // match it to an event
-                        int eventTag = mEventTags[index];
-                        mDescriptor.eventTag = eventTag;
-                        
-                        // get the EventValueDescription for this tag
-                        EventValueDescription valueDesc = mLogParser.getEventInfoMap()
-                            .get(eventTag)[mDescriptor.filterValueIndex];
-                        
-                        // let the EventValueDescription convert the String value into an object
-                        // of the proper type.
-                        mDescriptor.filterValue = valueDesc.getObjectFromString(
-                                mFilterValue.getText().trim());
-                        setModified();
-                    }
-                }
-            }
-        });
-        
-        // add a separator spanning the 2 columns
-        
-        l = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        l.setLayoutData(gd);
-        
-        // add a composite to hold the ok/cancel button, no matter what the columns size are.
-        Composite buttonComp = new Composite(mShell, SWT.NONE);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        buttonComp.setLayoutData(gd);
-        GridLayout gl;
-        buttonComp.setLayout(gl = new GridLayout(6, true));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        Composite padding = new Composite(mShell, SWT.NONE);
-        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mOkButton = new Button(buttonComp, SWT.PUSH);
-        mOkButton.setText("OK");
-        mOkButton.setLayoutData(new GridData(GridData.CENTER));
-        mOkButton.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mShell.close();
-            }
-        });
-
-        padding = new Composite(mShell, SWT.NONE);
-        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        padding = new Composite(mShell, SWT.NONE);
-        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        
-        Button cancelButton = new Button(buttonComp, SWT.PUSH);
-        cancelButton.setText("Cancel");
-        cancelButton.setLayoutData(new GridData(GridData.CENTER));
-        cancelButton.addSelectionListener(new SelectionAdapter() {
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // cancel the edit
-                mEditStatus = false;
-                mShell.close();
-            }
-        });
-
-        padding = new Composite(mShell, SWT.NONE);
-        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        
-        mShell.addListener(SWT.Close, new Listener() {
-            public void handleEvent(Event event) {
-                event.doit = true;
-            }
-        });
-    }
-
-    private void setModified() {
-        mEditStatus = true;
-    }
-
-    private void handleEventComboSelection() {
-        // get the current selection in the event combo
-        int index = mEventCombo.getSelectionIndex();
-
-        if (index != -1) {
-            // match it to an event
-            int eventTag = mEventTags[index];
-            mDescriptor.eventTag = eventTag;
-            
-            // get the EventValueDescription for this tag
-            EventValueDescription[] values = mLogParser.getEventInfoMap().get(eventTag);
-            
-            // fill the combo for the values
-            mValueCombo.removeAll();
-            if (values != null) {
-                if (mDescriptor instanceof ValueDisplayDescriptor) {
-                    ValueDisplayDescriptor valueDescriptor = (ValueDisplayDescriptor)mDescriptor;
-    
-                    mValueCombo.setEnabled(true);
-                    for (EventValueDescription value : values) {
-                        mValueCombo.add(value.toString());
-                    }
-                    
-                    if (valueDescriptor.valueIndex != -1) {
-                        mValueCombo.select(valueDescriptor.valueIndex);
-                    } else {
-                        mValueCombo.clearSelection();
-                    }
-                } else {
-                    mValueCombo.setEnabled(false);
-                }
-
-                // fill the axis combo
-                mSeriesCombo.removeAll();
-                mSeriesCombo.setEnabled(false);
-                mSeriesIndices.clear();
-                int axisIndex = 0;
-                int selectionIndex = -1;
-                for (EventValueDescription value : values) {
-                    if (value.getEventValueType() == EventValueType.STRING) {
-                        mSeriesCombo.add(value.getName());
-                        mSeriesCombo.setEnabled(true);
-                        mSeriesIndices.add(axisIndex);
-                        
-                        if (mDescriptor.seriesValueIndex != -1 &&
-                                mDescriptor.seriesValueIndex == axisIndex) {
-                            selectionIndex = axisIndex;
-                        }
-                    }
-                    axisIndex++;
-                }
-
-                if (mSeriesCombo.isEnabled()) {
-                    mSeriesCombo.add("default (pid)", 0 /* index */);
-                    mSeriesIndices.add(0 /* index */, -1 /* value */);
-
-                    // +1 because we added another item at index 0
-                    mSeriesCombo.select(selectionIndex + 1);
-                    
-                    if (selectionIndex >= 0) {
-                        mDisplayPidCheckBox.setSelection(mDescriptor.includePid);
-                        mDisplayPidCheckBox.setEnabled(true);
-                    } else {
-                        mDisplayPidCheckBox.setEnabled(false);
-                        mDisplayPidCheckBox.setSelection(false);
-                    }
-                } else {
-                    mDisplayPidCheckBox.setSelection(false);
-                    mDisplayPidCheckBox.setEnabled(false);
-                }
-                
-                // fill the filter combo
-                mFilterCombo.setEnabled(true);
-                mFilterCombo.removeAll();
-                mFilterCombo.add("(no filter)");
-                for (EventValueDescription value : values) {
-                    mFilterCombo.add(value.toString());
-                }
-                
-                // select the current filter
-                mFilterCombo.select(mDescriptor.filterValueIndex + 1);
-                mFilterMethodCombo.select(getFilterMethodIndex(mDescriptor.filterCompareMethod));
-
-                // fill the current filter value
-                if (mDescriptor.filterValueIndex != -1) {
-                    EventValueDescription valueInfo = values[mDescriptor.filterValueIndex];
-                    if (valueInfo.checkForType(mDescriptor.filterValue)) {
-                        mFilterValue.setText(mDescriptor.filterValue.toString());
-                    } else {
-                        mFilterValue.setText("");
-                    }
-                } else {
-                    mFilterValue.setText("");
-                }
-            } else {
-                disableSubCombos();
-            }
-        } else {
-            disableSubCombos();
-        }
-        
-        checkValidity();
-    }
-
-    /**
-     * 
-     */
-    private void disableSubCombos() {
-        mValueCombo.removeAll();
-        mValueCombo.clearSelection();
-        mValueCombo.setEnabled(false);
-
-        mSeriesCombo.removeAll();
-        mSeriesCombo.clearSelection();
-        mSeriesCombo.setEnabled(false);
-        
-        mDisplayPidCheckBox.setEnabled(false);
-        mDisplayPidCheckBox.setSelection(false);
-        
-        mFilterCombo.removeAll();
-        mFilterCombo.clearSelection();
-        mFilterCombo.setEnabled(false);
-        
-        mFilterValue.setEnabled(false);
-        mFilterValue.setText("");
-        mFilterMethodCombo.setEnabled(false);
-    }
-
-    private void handleValueComboSelection() {
-        ValueDisplayDescriptor valueDescriptor = (ValueDisplayDescriptor)mDescriptor;
-
-        // get the current selection in the value combo
-        int index = mValueCombo.getSelectionIndex();
-        valueDescriptor.valueIndex = index;
-        
-        // for now set the built-in name
-
-        // get the current selection in the event combo
-        int eventIndex = mEventCombo.getSelectionIndex();
-        
-        // match it to an event
-        int eventTag = mEventTags[eventIndex];
-        
-        // get the EventValueDescription for this tag
-        EventValueDescription[] values = mLogParser.getEventInfoMap().get(eventTag);
-
-        valueDescriptor.valueName = values[index].getName();
-        
-        checkValidity();
-    }
-
-    private void handleSeriesComboSelection() {
-        // get the current selection in the axis combo
-        int index = mSeriesCombo.getSelectionIndex();
-        
-        // get the actual value index from the list.
-        int valueIndex = mSeriesIndices.get(index);
-        
-        mDescriptor.seriesValueIndex = valueIndex;
-        
-        if (index > 0) {
-            mDisplayPidCheckBox.setEnabled(true);
-            mDisplayPidCheckBox.setSelection(mDescriptor.includePid);
-        } else {
-            mDisplayPidCheckBox.setSelection(false);
-            mDisplayPidCheckBox.setEnabled(false);
-        }
-    }
-
-    private void handleFilterComboSelection() {
-        // get the current selection in the axis combo
-        int index = mFilterCombo.getSelectionIndex();
-        
-        // decrement index by 1 since the item 0 means
-        // no filter (index = -1), and the rest is offset by 1
-        index--;
-
-        mDescriptor.filterValueIndex = index;
-        
-        if (index != -1) {
-            mFilterValue.setEnabled(true);
-            mFilterMethodCombo.setEnabled(true);
-            if (mDescriptor.filterValue instanceof String) {
-                mFilterValue.setText((String)mDescriptor.filterValue);
-            }
-        } else {
-            mFilterValue.setText("");
-            mFilterValue.setEnabled(false);
-            mFilterMethodCombo.setEnabled(false);
-        }
-    }
-    
-    private void handleFilterMethodComboSelection() {
-        // get the current selection in the axis combo
-        int index = mFilterMethodCombo.getSelectionIndex();
-        CompareMethod method = CompareMethod.values()[index];
-        
-        mDescriptor.filterCompareMethod = method;
-    }
-
-    /**
-     * Returns the index of the filter method
-     * @param filterCompareMethod the {@link CompareMethod} enum.
-     */
-    private int getFilterMethodIndex(CompareMethod filterCompareMethod) {
-        CompareMethod[] values = CompareMethod.values();
-        for (int i = 0 ; i < values.length ; i++) {
-            if (values[i] == filterCompareMethod) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    private void loadValueDescriptor() {
-        // get the index from the eventTag.
-        int eventIndex = 0;
-        int comboIndex = -1;
-        for (int i : mEventTags) {
-            if (i == mDescriptor.eventTag) {
-                comboIndex = eventIndex;
-                break;
-            }
-            eventIndex++;
-        }
-        
-        if (comboIndex == -1) {
-            mEventCombo.clearSelection();
-        } else {
-            mEventCombo.select(comboIndex);
-        }
-
-        // get the event from the descriptor
-        handleEventComboSelection();
-    }
-    
-    private void checkValidity() {
-        mOkButton.setEnabled(mEventCombo.getSelectionIndex() != -1 &&
-                (((mDescriptor instanceof ValueDisplayDescriptor) == false) ||
-                        mValueCombo.getSelectionIndex() != -1));
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/OccurrenceRenderer.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/OccurrenceRenderer.java
deleted file mode 100644
index 3af1447..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/OccurrenceRenderer.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.android.ddmuilib.log.event;
-
-import org.jfree.chart.axis.ValueAxis;
-import org.jfree.chart.plot.CrosshairState;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.chart.plot.PlotRenderingInfo;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYItemRendererState;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
-import org.jfree.data.time.TimeSeriesCollection;
-import org.jfree.data.xy.XYDataset;
-import org.jfree.ui.RectangleEdge;
-
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.Stroke;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Custom renderer to render event occurrence. This rendered ignores the y value, and simply
- * draws a line from min to max at the time of the item.
- */
-public class OccurrenceRenderer extends XYLineAndShapeRenderer {
-
-    private static final long serialVersionUID = 1L;
-
-    @Override
-    public void drawItem(Graphics2D g2, 
-                         XYItemRendererState state,
-                         Rectangle2D dataArea,
-                         PlotRenderingInfo info,
-                         XYPlot plot, 
-                         ValueAxis domainAxis, 
-                         ValueAxis rangeAxis,
-                         XYDataset dataset, 
-                         int series, 
-                         int item,
-                         CrosshairState crosshairState, 
-                         int pass) {
-        TimeSeriesCollection timeDataSet = (TimeSeriesCollection)dataset;
-        
-        // get the x value for the series/item.
-        double x = timeDataSet.getX(series, item).doubleValue();
-
-        // get the min/max of the range axis
-        double yMin = rangeAxis.getLowerBound();
-        double yMax = rangeAxis.getUpperBound();
-
-        RectangleEdge domainEdge = plot.getDomainAxisEdge();
-        RectangleEdge rangeEdge = plot.getRangeAxisEdge();
-
-        // convert the coordinates to java2d.
-        double x2D = domainAxis.valueToJava2D(x, dataArea, domainEdge);
-        double yMin2D = rangeAxis.valueToJava2D(yMin, dataArea, rangeEdge);
-        double yMax2D = rangeAxis.valueToJava2D(yMax, dataArea, rangeEdge);
-
-        // get the paint information for the series/item
-        Paint p = getItemPaint(series, item);
-        Stroke s = getItemStroke(series, item);
-        
-        Line2D line = null;
-        PlotOrientation orientation = plot.getOrientation();
-        if (orientation == PlotOrientation.HORIZONTAL) {
-            line = new Line2D.Double(yMin2D, x2D, yMax2D, x2D);
-        }
-        else if (orientation == PlotOrientation.VERTICAL) {
-            line = new Line2D.Double(x2D, yMin2D, x2D, yMax2D);
-        }
-        g2.setPaint(p);
-        g2.setStroke(s);
-        g2.draw(line);
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/SyncCommon.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/SyncCommon.java
deleted file mode 100644
index 0a355d1..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/SyncCommon.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmuilib.log.event;
-
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.InvalidTypeException;
-
-import java.awt.Color;
-
-abstract public class SyncCommon extends EventDisplay {
-
-    // State information while processing the event stream
-    private int mLastState; // 0 if event started, 1 if event stopped
-    private long mLastStartTime; // ms
-    private long mLastStopTime; //ms
-    private String mLastDetails;
-    private int mLastSyncSource; // poll, server, user, etc.
-
-    // Some common variables for sync display.  These define the sync backends
-    //and how they should be displayed.
-    protected static final int CALENDAR = 0;
-    protected static final int GMAIL = 1;
-    protected static final int FEEDS = 2;
-    protected static final int CONTACTS = 3;
-    protected static final int ERRORS = 4;
-    protected static final int NUM_AUTHS = (CONTACTS + 1);
-    protected static final String AUTH_NAMES[] = {"Calendar", "Gmail", "Feeds", "Contacts",
-            "Errors"};
-    protected static final Color AUTH_COLORS[] = {Color.MAGENTA, Color.GREEN, Color.BLUE,
-            Color.ORANGE, Color.RED};
-
-    // Values from data/etc/event-log-tags
-    final int EVENT_SYNC = 2720;
-    final int EVENT_TICKLE = 2742;
-    final int EVENT_SYNC_DETAILS = 2743;
-    final int EVENT_CONTACTS_AGGREGATION = 2747;
-
-    protected SyncCommon(String name) {
-        super(name);
-    }
-
-    /**
-     * Resets the display.
-     */
-    @Override
-    void resetUI() {
-        mLastStartTime = 0;
-        mLastStopTime = 0;
-        mLastState = -1;
-        mLastSyncSource = -1;
-        mLastDetails = "";
-    }
-
-    /**
-     * Updates the display with a new event.  This is the main entry point for
-     * each event.  This method has the logic to tie together the start event,
-     * stop event, and details event into one graph item.  The combined sync event
-     * is handed to the subclass via processSycnEvent.  Note that the details
-     * can happen before or after the stop event.
-     *
-     * @param event     The event
-     * @param logParser The parser providing the event.
-     */
-    @Override
-    void newEvent(EventContainer event, EventLogParser logParser) {
-        try {
-            if (event.mTag == EVENT_SYNC) {
-                int state = Integer.parseInt(event.getValueAsString(1));
-                if (state == 0) { // start
-                    mLastStartTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
-                    mLastState = 0;
-                    mLastSyncSource = Integer.parseInt(event.getValueAsString(2));                    
-                    mLastDetails = "";
-                } else if (state == 1) { // stop
-                    if (mLastState == 0) {
-                        mLastStopTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
-                        if (mLastStartTime == 0) {
-                            // Log starts with a stop event
-                            mLastStartTime = mLastStopTime;
-                        }
-                        int auth = getAuth(event.getValueAsString(0));
-                        processSyncEvent(event, auth, mLastStartTime, mLastStopTime, mLastDetails,
-                                true, mLastSyncSource);
-                        mLastState = 1;
-                    }
-                }
-            } else if (event.mTag == EVENT_SYNC_DETAILS) {
-                mLastDetails = event.getValueAsString(3);
-                if (mLastState != 0) { // Not inside event
-                    long updateTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
-                    if (updateTime - mLastStopTime <= 250) {
-                        // Got details within 250ms after event, so delete and re-insert
-                        // Details later than 250ms (arbitrary) are discarded as probably
-                        // unrelated.
-                        int auth = getAuth(event.getValueAsString(0));
-                        processSyncEvent(event, auth, mLastStartTime, mLastStopTime, mLastDetails,
-                                false, mLastSyncSource);
-                    }
-                }
-            } else if (event.mTag == EVENT_CONTACTS_AGGREGATION) {
-                long stopTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
-                long startTime = stopTime - Long.parseLong(event.getValueAsString(0));
-                String details;
-                int count = Integer.parseInt(event.getValueAsString(1));
-                if (count < 0) {
-                    details = "g" + (-count);
-                } else {
-                    details = "G" + count;
-                }
-                processSyncEvent(event, CONTACTS, startTime, stopTime, details,
-                        true /* newEvent */, mLastSyncSource);
-            }
-        } catch (InvalidTypeException e) {
-        }
-    }
-
-    /**
-     * Callback hook for subclass to process a sync event.  newEvent has the logic
-     * to combine start and stop events and passes a processed event to the
-     * subclass.
-     *
-     * @param event     The sync event
-     * @param auth      The sync authority
-     * @param startTime Start time (ms) of events
-     * @param stopTime  Stop time (ms) of events
-     * @param details   Details associated with the event.
-     * @param newEvent  True if this event is a new sync event.  False if this event
-     * @param syncSource Poll, user, server, etc.
-     */
-    abstract void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
-            String details, boolean newEvent, int syncSource);
-     
-    /**
-     * Converts authority name to auth number.
-     *
-     * @param authname "calendar", etc.
-     * @return number series number associated with the authority
-     */
-    protected int getAuth(String authname) throws InvalidTypeException {
-        if ("calendar".equals(authname) || "cl".equals(authname)) {
-            return CALENDAR;
-        } else if ("contacts".equals(authname) || "cp".equals(authname) ||
-                "com.android.contacts".equals(authname)) {
-            return CONTACTS;
-        } else if ("subscribedfeeds".equals(authname)) {
-            return FEEDS;
-        } else if ("gmail-ls".equals(authname) || "mail".equals(authname)) {
-            return GMAIL;
-        } else if ("gmail-live".equals(authname)) {
-            return GMAIL;
-        } else if ("unknown".equals(authname)) {
-            return -1; // Unknown tickles; discard
-        } else {
-            throw new InvalidTypeException("Unknown authname " + authname);
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/EditFilterDialog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/EditFilterDialog.java
deleted file mode 100644
index c66fe48..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/EditFilterDialog.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * 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.android.ddmuilib.logcat;
-
-import com.android.ddmuilib.IImageLoader;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Small dialog box to edit a static port number.
- */
-public class EditFilterDialog extends Dialog {
-
-    private static final int DLG_WIDTH = 400;
-    private static final int DLG_HEIGHT = 250;
-
-    private Shell mParent;
-
-    private Shell mShell;
-
-    private boolean mOk = false;
-
-    private IImageLoader mImageLoader;
-
-    /**
-     * Filter being edited or created
-     */
-    private LogFilter mFilter;
-
-    private String mName;
-    private String mTag;
-    private String mPid;
-
-    /** Log level as an index of the drop-down combo
-     * @see getLogLevel
-     * @see getComboIndex
-     */
-    private int mLogLevel;
-
-    private Button mOkButton;
-
-    private Label mPidWarning;
-
-    public EditFilterDialog(IImageLoader imageLoader, Shell parent) {
-        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-        mImageLoader = imageLoader;
-    }
-
-    public EditFilterDialog(IImageLoader imageLoader, Shell shell,
-            LogFilter filter) {
-        this(imageLoader, shell);
-        mFilter = filter;
-    }
-
-    /**
-     * Opens the dialog. The method will return when the user closes the dialog
-     * somehow.
-     *
-     * @return true if ok was pressed, false if cancelled.
-     */
-    public boolean open() {
-        createUI();
-
-        if (mParent == null || mShell == null) {
-            return false;
-        }
-
-        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
-        Rectangle r = mParent.getBounds();
-        // get the center new top left.
-        int cx = r.x + r.width/2;
-        int x = cx - DLG_WIDTH / 2;
-        int cy = r.y + r.height/2;
-        int y = cy - DLG_HEIGHT / 2;
-        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
-
-        mShell.open();
-
-        Display display = mParent.getDisplay();
-        while (!mShell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-
-        // we're quitting with OK.
-        // Lets update the filter if needed
-        if (mOk) {
-            // if it was a "Create filter" action we need to create it first.
-            if (mFilter == null) {
-                mFilter = new LogFilter(mName);
-            }
-
-            // setup the filter
-            mFilter.setTagMode(mTag);
-
-            if (mPid != null && mPid.length() > 0) {
-                mFilter.setPidMode(Integer.parseInt(mPid));
-            } else {
-                mFilter.setPidMode(-1);
-            }
-
-            mFilter.setLogLevel(getLogLevel(mLogLevel));
-        }
-
-        return mOk;
-    }
-
-    public LogFilter getFilter() {
-        return mFilter;
-    }
-
-    private void createUI() {
-        mParent = getParent();
-        mShell = new Shell(mParent, getStyle());
-        mShell.setText("Log Filter");
-
-        mShell.setLayout(new GridLayout(1, false));
-
-        mShell.addListener(SWT.Close, new Listener() {
-            public void handleEvent(Event event) {
-            }
-        });
-
-        // top part with the filter name
-        Composite nameComposite = new Composite(mShell, SWT.NONE);
-        nameComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        nameComposite.setLayout(new GridLayout(2, false));
-
-        Label l = new Label(nameComposite, SWT.NONE);
-        l.setText("Filter Name:");
-
-        final Text filterNameText = new Text(nameComposite,
-                SWT.SINGLE | SWT.BORDER);
-        if (mFilter != null) {
-            mName = mFilter.getName();
-            if (mName != null) {
-                filterNameText.setText(mName);
-            }
-        }
-        filterNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        filterNameText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mName = filterNameText.getText().trim();
-                validate();
-            }
-        });
-
-        // separator
-        l = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-
-        // center part with the filter parameters
-        Composite main = new Composite(mShell, SWT.NONE);
-        main.setLayoutData(new GridData(GridData.FILL_BOTH));
-        main.setLayout(new GridLayout(3, false));
-
-        l = new Label(main, SWT.NONE);
-        l.setText("by Log Tag:");
-
-        final Text tagText = new Text(main, SWT.SINGLE | SWT.BORDER);
-        if (mFilter != null) {
-            mTag = mFilter.getTagFilter();
-            if (mTag != null) {
-                tagText.setText(mTag);
-            }
-        }
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        tagText.setLayoutData(gd);
-        tagText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mTag = tagText.getText().trim();
-                validate();
-            }
-        });
-
-        l = new Label(main, SWT.NONE);
-        l.setText("by pid:");
-
-        final Text pidText = new Text(main, SWT.SINGLE | SWT.BORDER);
-        if (mFilter != null) {
-            if (mFilter.getPidFilter() != -1) {
-                mPid = Integer.toString(mFilter.getPidFilter());
-            } else {
-                mPid = "";
-            }
-            pidText.setText(mPid);
-        }
-        pidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        pidText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mPid = pidText.getText().trim();
-                validate();
-            }
-        });
-
-        mPidWarning = new Label(main, SWT.NONE);
-        mPidWarning.setImage(mImageLoader.loadImage("empty.png", // $NON-NLS-1$
-                mShell.getDisplay()));
-
-        l = new Label(main, SWT.NONE);
-        l.setText("by Log level:");
-
-        final Combo logCombo = new Combo(main, SWT.DROP_DOWN | SWT.READ_ONLY);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        logCombo.setLayoutData(gd);
-
-        // add the labels
-        logCombo.add("<none>");
-        logCombo.add("Error");
-        logCombo.add("Warning");
-        logCombo.add("Info");
-        logCombo.add("Debug");
-        logCombo.add("Verbose");
-
-        if (mFilter != null) {
-            mLogLevel = getComboIndex(mFilter.getLogLevel());
-            logCombo.select(mLogLevel);
-        } else {
-            logCombo.select(0);
-        }
-
-        logCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // get the selection
-                mLogLevel = logCombo.getSelectionIndex();
-                validate();
-            }
-        });
-
-        // separator
-        l = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        // bottom part with the ok/cancel
-        Composite bottomComp = new Composite(mShell, SWT.NONE);
-        bottomComp
-                .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
-        bottomComp.setLayout(new GridLayout(2, true));
-
-        mOkButton = new Button(bottomComp, SWT.NONE);
-        mOkButton.setText("OK");
-        mOkButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mOk = true;
-                mShell.close();
-            }
-        });
-        mOkButton.setEnabled(false);
-        mShell.setDefaultButton(mOkButton);
-
-        Button cancelButton = new Button(bottomComp, SWT.NONE);
-        cancelButton.setText("Cancel");
-        cancelButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mShell.close();
-            }
-        });
-
-        validate();
-    }
-
-    /**
-     * Returns the log level from a combo index.
-     * @param index the Combo index
-     * @return a log level valid for the Log class.
-     */
-    protected int getLogLevel(int index) {
-        if (index == 0) {
-            return -1;
-        }
-
-        return 7 - index;
-    }
-
-    /**
-     * Returns the index in the combo that matches the log level
-     * @param logLevel The Log level.
-     * @return the combo index
-     */
-    private int getComboIndex(int logLevel) {
-        if (logLevel == -1) {
-            return 0;
-        }
-
-        return 7 - logLevel;
-    }
-
-    /**
-     * Validates the content of the 2 text fields and enable/disable "ok", while
-     * setting up the warning/error message.
-     */
-    private void validate() {
-
-        // then we check it only contains digits.
-        if (mPid != null) {
-            if (mPid.matches("[0-9]*") == false) { // $NON-NLS-1$
-                mOkButton.setEnabled(false);
-                mPidWarning.setImage(mImageLoader.loadImage(
-                        "warning.png", // $NON-NLS-1$
-                        mShell.getDisplay()));
-                return;
-            } else {
-                mPidWarning.setImage(mImageLoader.loadImage(
-                        "empty.png", // $NON-NLS-1$
-                        mShell.getDisplay()));
-            }
-        }
-
-        if (mName == null || mName.length() == 0) {
-            mOkButton.setEnabled(false);
-            return;
-        }
-
-        mOkButton.setEnabled(true);
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogColors.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogColors.java
deleted file mode 100644
index 9cff656..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogColors.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.android.ddmuilib.logcat;
-
-import org.eclipse.swt.graphics.Color;
-
-public class LogColors {
-    public Color infoColor;
-    public Color debugColor;
-    public Color errorColor;
-    public Color warningColor;
-    public Color verboseColor;
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogFilter.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogFilter.java
deleted file mode 100644
index a32de2f..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogFilter.java
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * 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.android.ddmuilib.logcat;
-
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmuilib.annotation.UiThread;
-import com.android.ddmuilib.logcat.LogPanel.LogMessage;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.widgets.ScrollBar;
-import org.eclipse.swt.widgets.TabItem;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-import java.util.ArrayList;
-import java.util.regex.PatternSyntaxException;
-
-/** logcat output filter class */
-public class LogFilter {
-
-    public final static int MODE_PID = 0x01;
-    public final static int MODE_TAG = 0x02;
-    public final static int MODE_LEVEL = 0x04;
-
-    private String mName;
-
-    /**
-     * Filtering mode. Value can be a mix of MODE_PID, MODE_TAG, MODE_LEVEL
-     */
-    private int mMode = 0;
-
-    /**
-     * pid used for filtering. Only valid if mMode is MODE_PID.
-     */
-    private int mPid;
-
-    /** Single level log level as defined in Log.mLevelChar. Only valid
-     * if mMode is MODE_LEVEL */
-    private int mLogLevel;
-
-    /**
-     * log tag filtering. Only valid if mMode is MODE_TAG
-     */
-    private String mTag;
-
-    private Table mTable;
-    private TabItem mTabItem;
-    private boolean mIsCurrentTabItem = false;
-    private int mUnreadCount = 0;
-
-    /** Temp keyword filtering */
-    private String[] mTempKeywordFilters;
-
-    /** temp pid filtering */
-    private int mTempPid = -1;
-
-    /** temp tag filtering */
-    private String mTempTag;
-
-    /** temp log level filtering */
-    private int mTempLogLevel = -1;
-
-    private LogColors mColors;
-
-    private boolean mTempFilteringStatus = false;
-    
-    private final ArrayList<LogMessage> mMessages = new ArrayList<LogMessage>();
-    private final ArrayList<LogMessage> mNewMessages = new ArrayList<LogMessage>();
-
-    private boolean mSupportsDelete = true;
-    private boolean mSupportsEdit = true;
-    private int mRemovedMessageCount = 0;
-
-    /**
-     * Creates a filter with a particular mode.
-     * @param name The name to be displayed in the UI
-     */
-    public LogFilter(String name) {
-        mName = name;
-    }
-
-    public LogFilter() {
-
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(mName);
-
-        sb.append(':');
-        sb.append(mMode);
-        if ((mMode & MODE_PID) == MODE_PID) {
-            sb.append(':');
-            sb.append(mPid);
-        }
-
-        if ((mMode & MODE_LEVEL) == MODE_LEVEL) {
-            sb.append(':');
-            sb.append(mLogLevel);
-        }
-
-        if ((mMode & MODE_TAG) == MODE_TAG) {
-            sb.append(':');
-            sb.append(mTag);
-        }
-
-        return sb.toString();
-    }
-
-    public boolean loadFromString(String string) {
-        String[] segments = string.split(":"); // $NON-NLS-1$
-        int index = 0;
-
-        // get the name
-        mName = segments[index++];
-
-        // get the mode
-        mMode = Integer.parseInt(segments[index++]);
-
-        if ((mMode & MODE_PID) == MODE_PID) {
-            mPid = Integer.parseInt(segments[index++]);
-        }
-
-        if ((mMode & MODE_LEVEL) == MODE_LEVEL) {
-            mLogLevel = Integer.parseInt(segments[index++]);
-        }
-
-        if ((mMode & MODE_TAG) == MODE_TAG) {
-            mTag = segments[index++];
-        }
-
-        return true;
-    }
-
-
-    /** Sets the name of the filter. */
-    void setName(String name) {
-        mName = name;
-    }
-
-    /**
-     * Returns the UI display name.
-     */
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * Set the Table ui widget associated with this filter.
-     * @param tabItem The item in the TabFolder
-     * @param table The Table object
-     */
-    public void setWidgets(TabItem tabItem, Table table) {
-        mTable = table;
-        mTabItem = tabItem;
-    }
-
-    /**
-     * Returns true if the filter is ready for ui.
-     */
-    public boolean uiReady() {
-        return (mTable != null && mTabItem != null);
-    }
-
-    /**
-     * Returns the UI table object.
-     * @return
-     */
-    public Table getTable() {
-        return mTable;
-    }
-
-    public void dispose() {
-        mTable.dispose();
-        mTabItem.dispose();
-        mTable = null;
-        mTabItem = null;
-    }
-
-    /**
-     * Resets the filtering mode to be 0 (i.e. no filter).
-     */
-    public void resetFilteringMode() {
-        mMode = 0;
-    }
-
-    /**
-     * Returns the current filtering mode.
-     * @return A bitmask. Possible values are MODE_PID, MODE_TAG, MODE_LEVEL
-     */
-    public int getFilteringMode() {
-        return mMode;
-    }
-
-    /**
-     * Adds PID to the current filtering mode.
-     * @param pid
-     */
-    public void setPidMode(int pid) {
-        if (pid != -1) {
-            mMode |= MODE_PID;
-        } else {
-            mMode &= ~MODE_PID;
-        }
-        mPid = pid;
-    }
-
-    /** Returns the pid filter if valid, otherwise -1 */
-    public int getPidFilter() {
-        if ((mMode & MODE_PID) == MODE_PID)
-            return mPid;
-        return -1;
-    }
-
-    public void setTagMode(String tag) {
-        if (tag != null && tag.length() > 0) {
-            mMode |= MODE_TAG;
-        } else {
-            mMode &= ~MODE_TAG;
-        }
-        mTag = tag;
-    }
-
-    public String getTagFilter() {
-        if ((mMode & MODE_TAG) == MODE_TAG)
-            return mTag;
-        return null;
-    }
-
-    public void setLogLevel(int level) {
-        if (level == -1) {
-            mMode &= ~MODE_LEVEL;
-        } else {
-            mMode |= MODE_LEVEL;
-            mLogLevel = level;
-        }
-
-    }
-
-    public int getLogLevel() {
-        if ((mMode & MODE_LEVEL) == MODE_LEVEL) {
-            return mLogLevel;
-        }
-
-        return -1;
-    }
-
-
-    public boolean supportsDelete() {
-        return mSupportsDelete ;
-    }
-
-    public boolean supportsEdit() {
-        return mSupportsEdit;
-    }
-
-    /**
-     * Sets the selected state of the filter.
-     * @param selected selection state.
-     */
-    public void setSelectedState(boolean selected) {
-        if (selected) {
-            if (mTabItem != null) {
-                mTabItem.setText(mName);
-            }
-            mUnreadCount = 0;
-        }
-        mIsCurrentTabItem = selected;
-    }
-    
-    /**
-     * Adds a new message and optionally removes an old message.
-     * <p/>The new message is filtered through {@link #accept(LogMessage)}.
-     * Calls to {@link #flush()} from a UI thread will display it (and other
-     * pending messages) to the associated {@link Table}.
-     * @param logMessage the MessageData object to filter
-     * @return true if the message was accepted.
-     */
-    public boolean addMessage(LogMessage newMessage, LogMessage oldMessage) {
-        synchronized (mMessages) {
-            if (oldMessage != null) {
-                int index = mMessages.indexOf(oldMessage);
-                if (index != -1) {
-                    // TODO check that index will always be -1 or 0, as only the oldest message is ever removed.
-                    mMessages.remove(index);
-                    mRemovedMessageCount++;
-                }
-                
-                // now we look for it in mNewMessages. This can happen if the new message is added
-                // and then removed because too many messages are added between calls to #flush()
-                index = mNewMessages.indexOf(oldMessage);
-                if (index != -1) {
-                    // TODO check that index will always be -1 or 0, as only the oldest message is ever removed.
-                    mNewMessages.remove(index);
-                }
-            }
-
-            boolean filter = accept(newMessage);
-
-            if (filter) {
-                // at this point the message is accepted, we add it to the list
-                mMessages.add(newMessage);
-                mNewMessages.add(newMessage);
-            }
-
-            return filter;
-        }
-    }
-    
-    /**
-     * Removes all the items in the filter and its {@link Table}.
-     */
-    public void clear() {
-        mRemovedMessageCount = 0;
-        mNewMessages.clear();
-        mMessages.clear();
-        mTable.removeAll();
-    }
-    
-    /**
-     * Filters a message.
-     * @param logMessage the Message
-     * @return true if the message is accepted by the filter.
-     */
-    boolean accept(LogMessage logMessage) {
-        // do the regular filtering now
-        if ((mMode & MODE_PID) == MODE_PID && mPid != logMessage.data.pid) {
-            return false;
-        }
-
-        if ((mMode & MODE_TAG) == MODE_TAG && (
-                logMessage.data.tag == null ||
-                logMessage.data.tag.equals(mTag) == false)) {
-            return false;
-        }
-
-        int msgLogLevel = logMessage.data.logLevel.getPriority();
-
-        // test the temp log filtering first, as it replaces the old one
-        if (mTempLogLevel != -1) {
-            if (mTempLogLevel > msgLogLevel) {
-                return false;
-            }
-        } else if ((mMode & MODE_LEVEL) == MODE_LEVEL &&
-                mLogLevel > msgLogLevel) {
-            return false;
-        }
-
-        // do the temp filtering now.
-        if (mTempKeywordFilters != null) {
-            String msg = logMessage.msg;
-
-            for (String kw : mTempKeywordFilters) {
-                try {
-                    if (msg.contains(kw) == false && msg.matches(kw) == false) {
-                        return false;
-                    }
-                } catch (PatternSyntaxException e) {
-                    // if the string is not a valid regular expression,
-                    // this exception is thrown.
-                    return false;
-                }
-            }
-        }
-
-        if (mTempPid != -1 && mTempPid != logMessage.data.pid) {
-           return false;
-        }
-
-        if (mTempTag != null && mTempTag.length() > 0) {
-            if (mTempTag.equals(logMessage.data.tag) == false) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Takes all the accepted messages and display them.
-     * This must be called from a UI thread.
-     */
-    @UiThread
-    public void flush() {
-        // if scroll bar is at the bottom, we will scroll
-        ScrollBar bar = mTable.getVerticalBar();
-        boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
-        
-        // if we are not going to scroll, get the current first item being shown.
-        int topIndex = mTable.getTopIndex();
-
-        // disable drawing
-        mTable.setRedraw(false);
-        
-        int totalCount = mNewMessages.size();
-
-        try {
-            // remove the items of the old messages.
-            for (int i = 0 ; i < mRemovedMessageCount && mTable.getItemCount() > 0 ; i++) {
-                mTable.remove(0);
-            }
-    
-            if (mUnreadCount > mTable.getItemCount()) {
-                mUnreadCount = mTable.getItemCount();
-            }
-    
-            // add the new items
-            for (int i = 0  ; i < totalCount ; i++) {
-                LogMessage msg = mNewMessages.get(i);
-                addTableItem(msg);
-            }
-        } catch (SWTException e) {
-            // log the error and keep going. Content of the logcat table maybe unexpected
-            // but at least ddms won't crash.
-            Log.e("LogFilter", e);
-        }
-        
-        // redraw
-        mTable.setRedraw(true);
-
-        // scroll if needed, by showing the last item
-        if (scroll) {
-            totalCount = mTable.getItemCount();
-            if (totalCount > 0) {
-                mTable.showItem(mTable.getItem(totalCount-1));
-            }
-        } else if (mRemovedMessageCount > 0) {
-            // we need to make sure the topIndex is still visible.
-            // Because really old items are removed from the list, this could make it disappear
-            // if we don't change the scroll value at all.
-
-            topIndex -= mRemovedMessageCount;
-            if (topIndex < 0) {
-                // looks like it disappeared. Lets just show the first item
-                mTable.showItem(mTable.getItem(0));
-            } else {
-                mTable.showItem(mTable.getItem(topIndex));
-            }
-        }
-
-        // if this filter is not the current one, we update the tab text
-        // with the amount of unread message
-        if (mIsCurrentTabItem == false) {
-            mUnreadCount += mNewMessages.size();
-            totalCount = mTable.getItemCount();
-            if (mUnreadCount > 0) {
-                mTabItem.setText(mName + " (" // $NON-NLS-1$
-                        + (mUnreadCount > totalCount ? totalCount : mUnreadCount)
-                        + ")");  // $NON-NLS-1$
-            } else {
-                mTabItem.setText(mName);  // $NON-NLS-1$
-            }
-        }
-        
-        mNewMessages.clear();
-    }
-
-    void setColors(LogColors colors) {
-        mColors = colors;
-    }
-
-    int getUnreadCount() {
-        return mUnreadCount;
-    }
-
-    void setUnreadCount(int unreadCount) {
-        mUnreadCount = unreadCount;
-    }
-
-    void setSupportsDelete(boolean support) {
-        mSupportsDelete = support;
-    }
-
-    void setSupportsEdit(boolean support) {
-        mSupportsEdit = support;
-    }
-
-    void setTempKeywordFiltering(String[] segments) {
-        mTempKeywordFilters = segments;
-        mTempFilteringStatus = true;
-    }
-
-    void setTempPidFiltering(int pid) {
-        mTempPid = pid;
-        mTempFilteringStatus = true;
-    }
-
-    void setTempTagFiltering(String tag) {
-        mTempTag = tag;
-        mTempFilteringStatus = true;
-    }
-
-    void resetTempFiltering() {
-        if (mTempPid != -1 || mTempTag != null || mTempKeywordFilters != null) {
-            mTempFilteringStatus = true;
-        }
-
-        mTempPid = -1;
-        mTempTag = null;
-        mTempKeywordFilters = null;
-    }
-
-    void resetTempFilteringStatus() {
-        mTempFilteringStatus = false;
-    }
-
-    boolean getTempFilterStatus() {
-        return mTempFilteringStatus;
-    }
-
-
-    /**
-     * Add a TableItem for the index-th item of the buffer
-     * @param filter The index of the table in which to insert the item.
-     */
-    private void addTableItem(LogMessage msg) {
-        TableItem item = new TableItem(mTable, SWT.NONE);
-        item.setText(0, msg.data.time);
-        item.setText(1, new String(new char[] { msg.data.logLevel.getPriorityLetter() }));
-        item.setText(2, msg.data.pidString);
-        item.setText(3, msg.data.tag);
-        item.setText(4, msg.msg);
-
-        // add the buffer index as data
-        item.setData(msg);
-
-        if (msg.data.logLevel == LogLevel.INFO) {
-            item.setForeground(mColors.infoColor);
-        } else if (msg.data.logLevel == LogLevel.DEBUG) {
-            item.setForeground(mColors.debugColor);
-        } else if (msg.data.logLevel == LogLevel.ERROR) {
-            item.setForeground(mColors.errorColor);
-        } else if (msg.data.logLevel == LogLevel.WARN) {
-            item.setForeground(mColors.warningColor);
-        } else {
-            item.setForeground(mColors.verboseColor);
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
deleted file mode 100644
index 154e2fa..0000000
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
+++ /dev/null
@@ -1,1571 +0,0 @@
-/*
- * 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.android.ddmuilib.logcat;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.IImageLoader;
-import com.android.ddmuilib.ITableFocusListener;
-import com.android.ddmuilib.SelectionDependentPanel;
-import com.android.ddmuilib.TableHelper;
-import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator;
-import com.android.ddmuilib.actions.ICommonAction;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.swt.widgets.TabItem;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class LogPanel extends SelectionDependentPanel {
-
-    private static final int STRING_BUFFER_LENGTH = 10000;
-
-    /** no filtering. Only one tab with everything. */
-    public static final int FILTER_NONE = 0;
-    /** manual mode for filter. all filters are manually created. */
-    public static final int FILTER_MANUAL = 1;
-    /** automatic mode for filter (pid mode).
-     * All filters are automatically created. */
-    public static final int FILTER_AUTO_PID = 2;
-    /** automatic mode for filter (tag mode).
-     * All filters are automatically created. */
-    public static final int FILTER_AUTO_TAG = 3;
-    /** Manual filtering mode + new filter for debug app, if needed */
-    public static final int FILTER_DEBUG = 4;
-
-    public static final int COLUMN_MODE_MANUAL = 0;
-    public static final int COLUMN_MODE_AUTO = 1;
-
-    public static String PREFS_TIME;
-    public static String PREFS_LEVEL;
-    public static String PREFS_PID;
-    public static String PREFS_TAG;
-    public static String PREFS_MESSAGE;
-
-    /**
-     * This pattern is meant to parse the first line of a log message with the option
-     * 'logcat -v long'. The first line represents the date, tag, severity, etc.. while the
-     * following lines are the message (can be several line).<br>
-     * This first line looks something like<br>
-     * <code>"[ 00-00 00:00:00.000 &lt;pid&gt;:0x&lt;???&gt; &lt;severity&gt;/&lt;tag&gt;]"</code>
-     * <br>
-     * Note: severity is one of V, D, I, W, or EM<br>
-     * Note: the fraction of second value can have any number of digit.
-     * Note the tag should be trim as it may have spaces at the end.
-     */
-    private static Pattern sLogPattern = Pattern.compile(
-            "^\\[\\s(\\d\\d-\\d\\d\\s\\d\\d:\\d\\d:\\d\\d\\.\\d+)" + //$NON-NLS-1$
-            "\\s+(\\d*):(0x[0-9a-fA-F]+)\\s([VDIWE])/(.*)\\]$"); //$NON-NLS-1$
-
-    /**
-     * Interface for Storage Filter manager. Implementation of this interface
-     * provide a custom way to archive an reload filters.
-     */
-    public interface ILogFilterStorageManager {
-
-        public LogFilter[] getFilterFromStore();
-
-        public void saveFilters(LogFilter[] filters);
-
-        public boolean requiresDefaultFilter();
-    }
-
-    private Composite mParent;
-    private IPreferenceStore mStore;
-
-    /** top object in the view */
-    private TabFolder mFolders;
-
-    private LogColors mColors;
-
-    private ILogFilterStorageManager mFilterStorage;
-
-    private LogCatOuputReceiver mCurrentLogCat;
-
-    /**
-     * Circular buffer containing the logcat output. This is unfiltered.
-     * The valid content goes from <code>mBufferStart</code> to
-     * <code>mBufferEnd - 1</code>. Therefore its number of item is
-     * <code>mBufferEnd - mBufferStart</code>.
-     */
-    private LogMessage[] mBuffer = new LogMessage[STRING_BUFFER_LENGTH];
-
-    /** Represents the oldest message in the buffer */
-    private int mBufferStart = -1;
-
-    /**
-     * Represents the next usable item in the buffer to receive new message.
-     * This can be equal to mBufferStart, but when used mBufferStart will be
-     * incremented as well.
-     */
-    private int mBufferEnd = -1;
-
-    /** Filter list */
-    private LogFilter[] mFilters;
-
-    /** Default filter */
-    private LogFilter mDefaultFilter;
-
-    /** Current filter being displayed */
-    private LogFilter mCurrentFilter;
-
-    /** Filtering mode */
-    private int mFilterMode = FILTER_NONE;
-
-    /** Device currently running logcat */
-    private IDevice mCurrentLoggedDevice = null;
-
-    private ICommonAction mDeleteFilterAction;
-    private ICommonAction mEditFilterAction;
-
-    private ICommonAction[] mLogLevelActions;
-
-    /** message data, separated from content for multi line messages */
-    protected static class LogMessageInfo {
-        public LogLevel logLevel;
-        public int pid;
-        public String pidString;
-        public String tag;
-        public String time;
-    }
-
-    /** pointer to the latest LogMessageInfo. this is used for multi line
-     * log message, to reuse the info regarding level, pid, etc...
-     */
-    private LogMessageInfo mLastMessageInfo = null;
-
-    private boolean mPendingAsyncRefresh = false;
-
-    /** loader for the images. the implementation will varie between standalone
-     * app and eclipse plugin app and eclipse plugin. */
-    private IImageLoader mImageLoader;
-
-    private String mDefaultLogSave;
-
-    private int mColumnMode = COLUMN_MODE_MANUAL;
-    private Font mDisplayFont;
-
-    private ITableFocusListener mGlobalListener;
-
-    /** message data, separated from content for multi line messages */
-    protected static class LogMessage {
-        public LogMessageInfo data;
-        public String msg;
-
-        @Override
-        public String toString() {
-            return data.time + ": " //$NON-NLS-1$
-                + data.logLevel + "/" //$NON-NLS-1$
-                + data.tag + "(" //$NON-NLS-1$
-                + data.pidString + "): " //$NON-NLS-1$
-                + msg;
-        }
-    }
-
-    /**
-     * objects able to receive the output of a remote shell command,
-     * specifically a logcat command in this case
-     */
-    private final class LogCatOuputReceiver extends MultiLineReceiver {
-
-        public boolean isCancelled = false;
-
-        public LogCatOuputReceiver() {
-            super();
-
-            setTrimLine(false);
-        }
-
-        @Override
-        public void processNewLines(String[] lines) {
-            if (isCancelled == false) {
-                processLogLines(lines);
-            }
-        }
-
-        public boolean isCancelled() {
-            return isCancelled;
-        }
-    }
-
-    /**
-     * Parser class for the output of a "ps" shell command executed on a device.
-     * This class looks for a specific pid to find the process name from it.
-     * Once found, the name is used to update a filter and a tab object
-     *
-     */
-    private class PsOutputReceiver extends MultiLineReceiver {
-
-        private LogFilter mFilter;
-
-        private TabItem mTabItem;
-
-        private int mPid;
-
-        /** set to true when we've found the pid we're looking for */
-        private boolean mDone = false;
-
-        PsOutputReceiver(int pid, LogFilter filter, TabItem tabItem) {
-            mPid = pid;
-            mFilter = filter;
-            mTabItem = tabItem;
-        }
-
-        public boolean isCancelled() {
-            return mDone;
-        }
-
-        @Override
-        public void processNewLines(String[] lines) {
-            for (String line : lines) {
-                if (line.startsWith("USER")) { //$NON-NLS-1$
-                    continue;
-                }
-                // get the pid.
-                int index = line.indexOf(' ');
-                if (index == -1) {
-                    continue;
-                }
-                // look for the next non blank char
-                index++;
-                while (line.charAt(index) == ' ') {
-                    index++;
-                }
-
-                // this is the start of the pid.
-                // look for the end.
-                int index2 = line.indexOf(' ', index);
-
-                // get the line
-                String pidStr = line.substring(index, index2);
-                int pid = Integer.parseInt(pidStr);
-                if (pid != mPid) {
-                    continue;
-                } else {
-                    // get the process name
-                    index = line.lastIndexOf(' ');
-                    final String name = line.substring(index + 1);
-
-                    mFilter.setName(name);
-
-                    // update the tab
-                    Display d = mFolders.getDisplay();
-                    d.asyncExec(new Runnable() {
-                       public void run() {
-                           mTabItem.setText(name);
-                       }
-                    });
-
-                    // we're done with this ps.
-                    mDone = true;
-                    return;
-                }
-            }
-        }
-
-    }
-
-
-    /**
-     * Create the log view with some default parameters
-     * @param imageLoader the image loader.
-     * @param colors The display color object
-     * @param filterStorage the storage for user defined filters.
-     * @param mode The filtering mode
-     */
-    public LogPanel(IImageLoader imageLoader, LogColors colors,
-            ILogFilterStorageManager filterStorage, int mode) {
-        mImageLoader = imageLoader;
-        mColors = colors;
-        mFilterMode = mode;
-        mFilterStorage = filterStorage;
-        mStore = DdmUiPreferences.getStore();
-    }
-
-    public void setActions(ICommonAction deleteAction, ICommonAction editAction,
-            ICommonAction[] logLevelActions) {
-        mDeleteFilterAction = deleteAction;
-        mEditFilterAction = editAction;
-        mLogLevelActions = logLevelActions;
-    }
-
-    /**
-     * Sets the column mode. Must be called before creatUI
-     * @param mode the column mode. Valid values are COLUMN_MOD_MANUAL and
-     *  COLUMN_MODE_AUTO
-     */
-    public void setColumnMode(int mode) {
-        mColumnMode  = mode;
-    }
-
-    /**
-     * Sets the display font.
-     * @param font The display font.
-     */
-    public void setFont(Font font) {
-        mDisplayFont = font;
-
-        if (mFilters != null) {
-            for (LogFilter f : mFilters) {
-                Table table = f.getTable();
-                if (table != null) {
-                    table.setFont(font);
-                }
-            }
-        }
-
-        if (mDefaultFilter != null) {
-            Table table = mDefaultFilter.getTable();
-            if (table != null) {
-                table.setFont(font);
-            }
-        }
-    }
-
-    /**
-     * Sent when a new device is selected. The new device can be accessed
-     * with {@link #getCurrentDevice()}.
-     */
-    @Override
-    public void deviceSelected() {
-        startLogCat(getCurrentDevice());
-    }
-
-    /**
-     * Sent when a new client is selected. The new client can be accessed
-     * with {@link #getCurrentClient()}.
-     */
-    @Override
-    public void clientSelected() {
-        // pass
-    }
-
-
-    /**
-     * Creates a control capable of displaying some information.  This is
-     * called once, when the application is initializing, from the UI thread.
-     */
-    @Override
-    protected Control createControl(Composite parent) {
-        mParent = parent;
-
-        Composite top = new Composite(parent, SWT.NONE);
-        top.setLayoutData(new GridData(GridData.FILL_BOTH));
-        top.setLayout(new GridLayout(1, false));
-
-        // create the tab folder
-        mFolders = new TabFolder(top, SWT.NONE);
-        mFolders.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mFolders.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mCurrentFilter != null) {
-                    mCurrentFilter.setSelectedState(false);
-                }
-                mCurrentFilter = getCurrentFilter();
-                mCurrentFilter.setSelectedState(true);
-                updateColumns(mCurrentFilter.getTable());
-                if (mCurrentFilter.getTempFilterStatus()) {
-                    initFilter(mCurrentFilter);
-                }
-                selectionChanged(mCurrentFilter);
-            }
-        });
-
-
-        Composite bottom = new Composite(top, SWT.NONE);
-        bottom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        bottom.setLayout(new GridLayout(3, false));
-
-        Label label = new Label(bottom, SWT.NONE);
-        label.setText("Filter:");
-
-        final Text filterText = new Text(bottom, SWT.SINGLE | SWT.BORDER);
-        filterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        filterText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                updateFilteringWith(filterText.getText());
-            }
-        });
-
-        /*
-        Button addFilterBtn = new Button(bottom, SWT.NONE);
-        addFilterBtn.setImage(mImageLoader.loadImage("add.png", //$NON-NLS-1$
-                addFilterBtn.getDisplay()));
-        */
-
-        // get the filters
-        createFilters();
-
-        // for each filter, create a tab.
-        int index = 0;
-
-        if (mDefaultFilter != null) {
-            createTab(mDefaultFilter, index++, false);
-        }
-
-        if (mFilters != null) {
-            for (LogFilter f : mFilters) {
-                createTab(f, index++, false);
-            }
-        }
-
-        return top;
-    }
-
-    @Override
-    protected void postCreation() {
-        // pass
-    }
-
-    /**
-     * Sets the focus to the proper object.
-     */
-    @Override
-    public void setFocus() {
-        mFolders.setFocus();
-    }
-
-
-    /**
-     * Starts a new logcat and set mCurrentLogCat as the current receiver.
-     * @param device the device to connect logcat to.
-     */
-    public void startLogCat(final IDevice device) {
-        if (device == mCurrentLoggedDevice) {
-            return;
-        }
-
-        // if we have a logcat already running
-        if (mCurrentLoggedDevice != null) {
-            stopLogCat(false);
-            mCurrentLoggedDevice = null;
-        }
-
-        resetUI(false);
-
-        if (device != null) {
-            // create a new output receiver
-            mCurrentLogCat = new LogCatOuputReceiver();
-
-            // start the logcat in a different thread
-            new Thread("Logcat")  { //$NON-NLS-1$
-                @Override
-                public void run() {
-
-                    while (device.isOnline() == false &&
-                            mCurrentLogCat != null &&
-                            mCurrentLogCat.isCancelled == false) {
-                        try {
-                            sleep(2000);
-                        } catch (InterruptedException e) {
-                            return;
-                        }
-                    }
-
-                    if (mCurrentLogCat == null || mCurrentLogCat.isCancelled) {
-                        // logcat was stopped/cancelled before the device became ready.
-                        return;
-                    }
-
-                    try {
-                        mCurrentLoggedDevice = device;
-                        device.executeShellCommand("logcat -v long", mCurrentLogCat); //$NON-NLS-1$
-                    } catch (Exception e) {
-                        Log.e("Logcat", e);
-                    } finally {
-                        // at this point the command is terminated.
-                        mCurrentLogCat = null;
-                        mCurrentLoggedDevice = null;
-                    }
-                }
-            }.start();
-        }
-    }
-
-    /** Stop the current logcat */
-    public void stopLogCat(boolean inUiThread) {
-        if (mCurrentLogCat != null) {
-            mCurrentLogCat.isCancelled = true;
-
-            // when the thread finishes, no one will reference that object
-            // and it'll be destroyed
-            mCurrentLogCat = null;
-
-            // reset the content buffer
-            for (int i = 0 ; i < STRING_BUFFER_LENGTH; i++) {
-                mBuffer[i] = null;
-            }
-
-            // because it's a circular buffer, it's hard to know if
-            // the array is empty with both start/end at 0 or if it's full
-            // with both start/end at 0 as well. So to mean empty, we use -1
-            mBufferStart = -1;
-            mBufferEnd = -1;
-
-            resetFilters();
-            resetUI(inUiThread);
-        }
-    }
-
-    /**
-     * Adds a new Filter. This methods displays the UI to create the filter
-     * and set up its parameters.<br>
-     * <b>MUST</b> be called from the ui thread.
-     *
-     */
-    public void addFilter() {
-        EditFilterDialog dlg = new EditFilterDialog(mImageLoader,
-                mFolders.getShell());
-        if (dlg.open()) {
-            synchronized (mBuffer) {
-                // get the new filter in the array
-                LogFilter filter = dlg.getFilter();
-                addFilterToArray(filter);
-
-                int index = mFilters.length - 1;
-                if (mDefaultFilter != null) {
-                    index++;
-                }
-
-                if (false) {
-
-                    for (LogFilter f : mFilters) {
-                        if (f.uiReady()) {
-                            f.dispose();
-                        }
-                    }
-                    if (mDefaultFilter != null && mDefaultFilter.uiReady()) {
-                        mDefaultFilter.dispose();
-                    }
-
-                    // for each filter, create a tab.
-                    int i = 0;
-                    if (mFilters != null) {
-                        for (LogFilter f : mFilters) {
-                            createTab(f, i++, true);
-                        }
-                    }
-                    if (mDefaultFilter != null) {
-                        createTab(mDefaultFilter, i++, true);
-                    }
-                } else {
-
-                    // create ui for the filter.
-                    createTab(filter, index, true);
-
-                    // reset the default as it shouldn't contain the content of
-                    // this new filter.
-                    if (mDefaultFilter != null) {
-                        initDefaultFilter();
-                    }
-                }
-
-                // select the new filter
-                if (mCurrentFilter != null) {
-                    mCurrentFilter.setSelectedState(false);
-                }
-                mFolders.setSelection(index);
-                filter.setSelectedState(true);
-                mCurrentFilter = filter;
-
-                selectionChanged(filter);
-
-                // finally we update the filtering mode if needed
-                if (mFilterMode == FILTER_NONE) {
-                    mFilterMode = FILTER_MANUAL;
-                }
-
-                mFilterStorage.saveFilters(mFilters);
-
-            }
-        }
-    }
-
-    /**
-     * Edits the current filter. The method displays the UI to edit the filter.
-     */
-    public void editFilter() {
-        if (mCurrentFilter != null && mCurrentFilter != mDefaultFilter) {
-            EditFilterDialog dlg = new EditFilterDialog(mImageLoader,
-                    mFolders.getShell(),
-                    mCurrentFilter);
-            if (dlg.open()) {
-                synchronized (mBuffer) {
-                    // at this point the filter has been updated.
-                    // so we update its content
-                    initFilter(mCurrentFilter);
-
-                    // and the content of the "other" filter as well.
-                    if (mDefaultFilter != null) {
-                        initDefaultFilter();
-                    }
-
-                    mFilterStorage.saveFilters(mFilters);
-                }
-            }
-        }
-    }
-
-    /**
-     * Deletes the current filter.
-     */
-    public void deleteFilter() {
-        synchronized (mBuffer) {
-            if (mCurrentFilter != null && mCurrentFilter != mDefaultFilter) {
-                // remove the filter from the list
-                removeFilterFromArray(mCurrentFilter);
-                mCurrentFilter.dispose();
-
-                // select the new filter
-                mFolders.setSelection(0);
-                if (mFilters.length > 0) {
-                    mCurrentFilter = mFilters[0];
-                } else {
-                    mCurrentFilter = mDefaultFilter;
-                }
-
-                selectionChanged(mCurrentFilter);
-
-                // update the content of the "other" filter to include what was filtered out
-                // by the deleted filter.
-                if (mDefaultFilter != null) {
-                    initDefaultFilter();
-                }
-
-                mFilterStorage.saveFilters(mFilters);
-            }
-        }
-    }
-
-    /**
-     * saves the current selection in a text file.
-     * @return false if the saving failed.
-     */
-    public boolean save() {
-        synchronized (mBuffer) {
-            FileDialog dlg = new FileDialog(mParent.getShell(), SWT.SAVE);
-            String fileName;
-
-            dlg.setText("Save log...");
-            dlg.setFileName("log.txt");
-            String defaultPath = mDefaultLogSave;
-            if (defaultPath == null) {
-                defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
-            }
-            dlg.setFilterPath(defaultPath);
-            dlg.setFilterNames(new String[] {
-                "Text Files (*.txt)"
-            });
-            dlg.setFilterExtensions(new String[] {
-                "*.txt"
-            });
-
-            fileName = dlg.open();
-            if (fileName != null) {
-                mDefaultLogSave = dlg.getFilterPath();
-
-                // get the current table and its selection
-                Table currentTable = mCurrentFilter.getTable();
-
-                int[] selection = currentTable.getSelectionIndices();
-
-                // we need to sort the items to be sure.
-                Arrays.sort(selection);
-
-                // loop on the selection and output the file.
-                try {
-                    FileWriter writer = new FileWriter(fileName);
-
-                    for (int i : selection) {
-                        TableItem item = currentTable.getItem(i);
-                        LogMessage msg = (LogMessage)item.getData();
-                        String line = msg.toString();
-                        writer.write(line);
-                        writer.write('\n');
-                    }
-                    writer.flush();
-
-                } catch (IOException e) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Empty the current circular buffer.
-     */
-    public void clear() {
-        synchronized (mBuffer) {
-            for (int i = 0 ; i < STRING_BUFFER_LENGTH; i++) {
-                mBuffer[i] = null;
-            }
-
-            mBufferStart = -1;
-            mBufferEnd = -1;
-
-            // now we clear the existing filters
-            for (LogFilter filter : mFilters) {
-                filter.clear();
-            }
-
-            // and the default one
-            if (mDefaultFilter != null) {
-                mDefaultFilter.clear();
-            }
-        }
-    }
-
-    /**
-     * Copies the current selection of the current filter as multiline text.
-     *
-     * @param clipboard The clipboard to place the copied content.
-     */
-    public void copy(Clipboard clipboard) {
-        // get the current table and its selection
-        Table currentTable = mCurrentFilter.getTable();
-
-        copyTable(clipboard, currentTable);
-    }
-
-    /**
-     * Selects all lines.
-     */
-    public void selectAll() {
-        Table currentTable = mCurrentFilter.getTable();
-        currentTable.selectAll();
-    }
-
-    /**
-     * Sets a TableFocusListener which will be notified when one of the tables
-     * gets or loses focus.
-     *
-     * @param listener
-     */
-    public void setTableFocusListener(ITableFocusListener listener) {
-        // record the global listener, to make sure table created after
-        // this call will still be setup.
-        mGlobalListener = listener;
-
-        // now we setup the existing filters
-        for (LogFilter filter : mFilters) {
-            Table table = filter.getTable();
-
-            addTableToFocusListener(table);
-        }
-
-        // and the default one
-        if (mDefaultFilter != null) {
-            addTableToFocusListener(mDefaultFilter.getTable());
-        }
-    }
-
-    /**
-     * Sets up a Table object to notify the global Table Focus listener when it
-     * gets or loses the focus.
-     *
-     * @param table the Table object.
-     */
-    private void addTableToFocusListener(final Table table) {
-        // create the activator for this table
-        final IFocusedTableActivator activator = new IFocusedTableActivator() {
-            public void copy(Clipboard clipboard) {
-                copyTable(clipboard, table);
-            }
-
-            public void selectAll() {
-                table.selectAll();
-            }
-        };
-
-        // add the focus listener on the table to notify the global listener
-        table.addFocusListener(new FocusListener() {
-            public void focusGained(FocusEvent e) {
-                mGlobalListener.focusGained(activator);
-            }
-
-            public void focusLost(FocusEvent e) {
-                mGlobalListener.focusLost(activator);
-            }
-        });
-    }
-
-    /**
-     * Copies the current selection of a Table into the provided Clipboard, as
-     * multi-line text.
-     *
-     * @param clipboard The clipboard to place the copied content.
-     * @param table The table to copy from.
-     */
-    private static void copyTable(Clipboard clipboard, Table table) {
-        int[] selection = table.getSelectionIndices();
-
-        // we need to sort the items to be sure.
-        Arrays.sort(selection);
-
-        // all lines must be concatenated.
-        StringBuilder sb = new StringBuilder();
-
-        // loop on the selection and output the file.
-        for (int i : selection) {
-            TableItem item = table.getItem(i);
-            LogMessage msg = (LogMessage)item.getData();
-            String line = msg.toString();
-            sb.append(line);
-            sb.append('\n');
-        }
-
-        // now add that to the clipboard
-        clipboard.setContents(new Object[] {
-            sb.toString()
-        }, new Transfer[] {
-            TextTransfer.getInstance()
-        });
-    }
-
-    /**
-     * Sets the log level for the current filter, but does not save it.
-     * @param i
-     */
-    public void setCurrentFilterLogLevel(int i) {
-        LogFilter filter = getCurrentFilter();
-
-        filter.setLogLevel(i);
-
-        initFilter(filter);
-    }
-
-    /**
-     * Creates a new tab in the folderTab item. Must be called from the ui
-     *      thread.
-     * @param filter The filter associated with the tab.
-     * @param index the index of the tab. if -1, the tab will be added at the
-     *          end.
-     * @param fillTable If true the table is filled with the current content of
-     *          the buffer.
-     * @return The TabItem object that was created.
-     */
-    private TabItem createTab(LogFilter filter, int index, boolean fillTable) {
-        synchronized (mBuffer) {
-            TabItem item = null;
-            if (index != -1) {
-                item = new TabItem(mFolders, SWT.NONE, index);
-            } else {
-                item = new TabItem(mFolders, SWT.NONE);
-            }
-            item.setText(filter.getName());
-
-            // set the control (the parent is the TabFolder item, always)
-            Composite top = new Composite(mFolders, SWT.NONE);
-            item.setControl(top);
-
-            top.setLayout(new FillLayout());
-
-            // create the ui, first the table
-            final Table t = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
-
-            if (mDisplayFont != null) {
-                t.setFont(mDisplayFont);
-            }
-
-            // give the ui objects to the filters.
-            filter.setWidgets(item, t);
-
-            t.setHeaderVisible(true);
-            t.setLinesVisible(false);
-
-            if (mGlobalListener != null) {
-                addTableToFocusListener(t);
-            }
-
-            // create a controllistener that will handle the resizing of all the
-            // columns (except the last) and of the table itself.
-            ControlListener listener = null;
-            if (mColumnMode == COLUMN_MODE_AUTO) {
-                listener = new ControlListener() {
-                    public void controlMoved(ControlEvent e) {
-                    }
-
-                    public void controlResized(ControlEvent e) {
-                        Rectangle r = t.getClientArea();
-
-                        // get the size of all but the last column
-                        int total = t.getColumn(0).getWidth();
-                        total += t.getColumn(1).getWidth();
-                        total += t.getColumn(2).getWidth();
-                        total += t.getColumn(3).getWidth();
-
-                        if (r.width > total) {
-                            t.getColumn(4).setWidth(r.width-total);
-                        }
-                    }
-                };
-
-                t.addControlListener(listener);
-            }
-
-            // then its column
-            TableColumn col = TableHelper.createTableColumn(t, "Time", SWT.LEFT,
-                    "00-00 00:00:00", //$NON-NLS-1$
-                    PREFS_TIME, mStore);
-            if (mColumnMode == COLUMN_MODE_AUTO) {
-                col.addControlListener(listener);
-            }
-
-            col = TableHelper.createTableColumn(t, "", SWT.CENTER,
-                    "D", //$NON-NLS-1$
-                    PREFS_LEVEL, mStore);
-            if (mColumnMode == COLUMN_MODE_AUTO) {
-                col.addControlListener(listener);
-            }
-
-            col = TableHelper.createTableColumn(t, "pid", SWT.LEFT,
-                    "9999", //$NON-NLS-1$
-                    PREFS_PID, mStore);
-            if (mColumnMode == COLUMN_MODE_AUTO) {
-                col.addControlListener(listener);
-            }
-
-            col = TableHelper.createTableColumn(t, "tag", SWT.LEFT,
-                    "abcdefgh",  //$NON-NLS-1$
-                    PREFS_TAG, mStore);
-            if (mColumnMode == COLUMN_MODE_AUTO) {
-                col.addControlListener(listener);
-            }
-
-            col = TableHelper.createTableColumn(t, "Message", SWT.LEFT,
-                    "abcdefghijklmnopqrstuvwxyz0123456789",  //$NON-NLS-1$
-                    PREFS_MESSAGE, mStore);
-            if (mColumnMode == COLUMN_MODE_AUTO) {
-                // instead of listening on resize for the last column, we make
-                // it non resizable.
-                col.setResizable(false);
-            }
-
-            if (fillTable) {
-                initFilter(filter);
-            }
-            return item;
-        }
-    }
-
-    protected void updateColumns(Table table) {
-        if (table != null) {
-            int index = 0;
-            TableColumn col;
-
-            col = table.getColumn(index++);
-            col.setWidth(mStore.getInt(PREFS_TIME));
-
-            col = table.getColumn(index++);
-            col.setWidth(mStore.getInt(PREFS_LEVEL));
-
-            col = table.getColumn(index++);
-            col.setWidth(mStore.getInt(PREFS_PID));
-
-            col = table.getColumn(index++);
-            col.setWidth(mStore.getInt(PREFS_TAG));
-
-            col = table.getColumn(index++);
-            col.setWidth(mStore.getInt(PREFS_MESSAGE));
-        }
-    }
-
-    public void resetUI(boolean inUiThread) {
-        if (mFilterMode == FILTER_AUTO_PID || mFilterMode == FILTER_AUTO_TAG) {
-            if (inUiThread) {
-                mFolders.dispose();
-                mParent.pack(true);
-                createControl(mParent);
-            } else {
-                Display d = mFolders.getDisplay();
-
-                // run sync as we need to update right now.
-                d.syncExec(new Runnable() {
-                    public void run() {
-                        mFolders.dispose();
-                        mParent.pack(true);
-                        createControl(mParent);
-                    }
-                });
-            }
-        } else  {
-            // the ui is static we just empty it.
-            if (mFolders.isDisposed() == false) {
-                if (inUiThread) {
-                    emptyTables();
-                } else {
-                    Display d = mFolders.getDisplay();
-
-                    // run sync as we need to update right now.
-                    d.syncExec(new Runnable() {
-                        public void run() {
-                            if (mFolders.isDisposed() == false) {
-                                emptyTables();
-                            }
-                        }
-                    });
-                }
-            }
-        }
-    }
-
-    /**
-     * Process new Log lines coming from {@link LogCatOuputReceiver}.
-     * @param lines the new lines
-     */
-    protected void processLogLines(String[] lines) {
-        // WARNING: this will not work if the string contains more line than
-        // the buffer holds.
-
-        if (lines.length > STRING_BUFFER_LENGTH) {
-            Log.e("LogCat", "Receiving more lines than STRING_BUFFER_LENGTH");
-        }
-
-        // parse the lines and create LogMessage that are stored in a temporary list
-        final ArrayList<LogMessage> newMessages = new ArrayList<LogMessage>();
-
-        synchronized (mBuffer) {
-            for (String line : lines) {
-                // ignore empty lines.
-                if (line.length() > 0) {
-                    // check for header lines.
-                    Matcher matcher = sLogPattern.matcher(line);
-                    if (matcher.matches()) {
-                        // this is a header line, parse the header and keep it around.
-                        mLastMessageInfo = new LogMessageInfo();
-
-                        mLastMessageInfo.time = matcher.group(1);
-                        mLastMessageInfo.pidString = matcher.group(2);
-                        mLastMessageInfo.pid = Integer.valueOf(mLastMessageInfo.pidString);
-                        mLastMessageInfo.logLevel = LogLevel.getByLetterString(matcher.group(4));
-                        mLastMessageInfo.tag = matcher.group(5).trim();
-                    } else {
-                        // This is not a header line.
-                        // Create a new LogMessage and process it.
-                        LogMessage mc = new LogMessage();
-
-                        if (mLastMessageInfo == null) {
-                            // The first line of output wasn't preceded
-                            // by a header line; make something up so
-                            // that users of mc.data don't NPE.
-                            mLastMessageInfo = new LogMessageInfo();
-                            mLastMessageInfo.time = "??-?? ??:??:??.???"; //$NON-NLS1$
-                            mLastMessageInfo.pidString = "<unknown>"; //$NON-NLS1$
-                            mLastMessageInfo.pid = 0;
-                            mLastMessageInfo.logLevel = LogLevel.INFO;
-                            mLastMessageInfo.tag = "<unknown>"; //$NON-NLS1$
-                        }
-
-                        // If someone printed a log message with
-                        // embedded '\n' characters, there will
-                        // one header line followed by multiple text lines.
-                        // Use the last header that we saw.
-                        mc.data = mLastMessageInfo;
-
-                        // tabs seem to display as only 1 tab so we replace the leading tabs
-                        // by 4 spaces.
-                        mc.msg = line.replaceAll("\t", "    "); //$NON-NLS-1$ //$NON-NLS-2$
-
-                        // process the new LogMessage.
-                        processNewMessage(mc);
-
-                        // store the new LogMessage
-                        newMessages.add(mc);
-                    }
-                }
-            }
-
-            // if we don't have a pending Runnable that will do the refresh, we ask the Display
-            // to run one in the UI thread.
-            if (mPendingAsyncRefresh == false) {
-                mPendingAsyncRefresh = true;
-
-                try {
-                    Display display = mFolders.getDisplay();
-
-                    // run in sync because this will update the buffer start/end indices
-                    display.asyncExec(new Runnable() {
-                        public void run() {
-                            asyncRefresh();
-                        }
-                    });
-                } catch (SWTException e) {
-                    // display is disposed, we're probably quitting. Let's stop.
-                    stopLogCat(false);
-                }
-            }
-        }
-    }
-
-    /**
-     * Refreshes the UI with new messages.
-     */
-    private void asyncRefresh() {
-        if (mFolders.isDisposed() == false) {
-            synchronized (mBuffer) {
-                try {
-                    // the circular buffer has been updated, let have the filter flush their
-                    // display with the new messages.
-                    if (mFilters != null) {
-                        for (LogFilter f : mFilters) {
-                            f.flush();
-                        }
-                    }
-
-                    if (mDefaultFilter != null) {
-                        mDefaultFilter.flush();
-                    }
-                } finally {
-                    // the pending refresh is done.
-                    mPendingAsyncRefresh = false;
-                }
-            }
-        } else {
-            stopLogCat(true);
-        }
-    }
-
-    /**
-     * Processes a new Message.
-     * <p/>This adds the new message to the buffer, and gives it to the existing filters.
-     * @param newMessage
-     */
-    private void processNewMessage(LogMessage newMessage) {
-        // if we are in auto filtering mode, make sure we have
-        // a filter for this
-        if (mFilterMode == FILTER_AUTO_PID ||
-                mFilterMode == FILTER_AUTO_TAG) {
-           checkFilter(newMessage.data);
-        }
-
-        // compute the index where the message goes.
-        // was the buffer empty?
-        int messageIndex = -1;
-        if (mBufferStart == -1) {
-            messageIndex = mBufferStart = 0;
-            mBufferEnd = 1;
-        } else {
-            messageIndex = mBufferEnd;
-
-            // check we aren't overwriting start
-            if (mBufferEnd == mBufferStart) {
-                mBufferStart = (mBufferStart + 1) % STRING_BUFFER_LENGTH;
-            }
-
-            // increment the next usable slot index
-            mBufferEnd = (mBufferEnd + 1) % STRING_BUFFER_LENGTH;
-        }
-
-        LogMessage oldMessage = null;
-
-        // record the message that was there before
-        if (mBuffer[messageIndex] != null) {
-            oldMessage = mBuffer[messageIndex];
-        }
-
-        // then add the new one
-        mBuffer[messageIndex] = newMessage;
-
-        // give the new message to every filters.
-        boolean filtered = false;
-        if (mFilters != null) {
-            for (LogFilter f : mFilters) {
-                filtered |= f.addMessage(newMessage, oldMessage);
-            }
-        }
-        if (filtered == false && mDefaultFilter != null) {
-            mDefaultFilter.addMessage(newMessage, oldMessage);
-        }
-    }
-
-    private void createFilters() {
-        if (mFilterMode == FILTER_DEBUG || mFilterMode == FILTER_MANUAL) {
-            // unarchive the filters.
-            mFilters = mFilterStorage.getFilterFromStore();
-
-            // set the colors
-            if (mFilters != null) {
-                for (LogFilter f : mFilters) {
-                    f.setColors(mColors);
-                }
-            }
-
-            if (mFilterStorage.requiresDefaultFilter()) {
-                mDefaultFilter = new LogFilter("Log");
-                mDefaultFilter.setColors(mColors);
-                mDefaultFilter.setSupportsDelete(false);
-                mDefaultFilter.setSupportsEdit(false);
-            }
-        } else if (mFilterMode == FILTER_NONE) {
-            // if the filtering mode is "none", we create a single filter that
-            // will receive all
-            mDefaultFilter = new LogFilter("Log");
-            mDefaultFilter.setColors(mColors);
-            mDefaultFilter.setSupportsDelete(false);
-            mDefaultFilter.setSupportsEdit(false);
-        }
-    }
-
-    /** Checks if there's an automatic filter for this md and if not
-     * adds the filter and the ui.
-     * This must be called from the UI!
-     * @param md
-     * @return true if the filter existed already
-     */
-    private boolean checkFilter(final LogMessageInfo md) {
-        if (true)
-            return true;
-        // look for a filter that matches the pid
-        if (mFilterMode == FILTER_AUTO_PID) {
-            for (LogFilter f : mFilters) {
-                if (f.getPidFilter() == md.pid) {
-                    return true;
-                }
-            }
-        } else if (mFilterMode == FILTER_AUTO_TAG) {
-            for (LogFilter f : mFilters) {
-                if (f.getTagFilter().equals(md.tag)) {
-                    return true;
-                }
-            }
-        }
-
-        // if we reach this point, no filter was found.
-        // create a filter with a temporary name of the pid
-        final LogFilter newFilter = new LogFilter(md.pidString);
-        String name = null;
-        if (mFilterMode == FILTER_AUTO_PID) {
-            newFilter.setPidMode(md.pid);
-
-            // ask the monitor thread if it knows the pid.
-            name = mCurrentLoggedDevice.getClientName(md.pid);
-        } else {
-            newFilter.setTagMode(md.tag);
-            name = md.tag;
-        }
-        addFilterToArray(newFilter);
-
-        final String fname = name;
-
-        // create the tabitem
-        final TabItem newTabItem = createTab(newFilter, -1, true);
-
-        // if the name is unknown
-        if (fname == null) {
-            // we need to find the process running under that pid.
-            // launch a thread do a ps on the device
-            new Thread("remote PS") { //$NON-NLS-1$
-                @Override
-                public void run() {
-                    // create the receiver
-                    PsOutputReceiver psor = new PsOutputReceiver(md.pid,
-                            newFilter, newTabItem);
-
-                    // execute ps
-                    try {
-                        mCurrentLoggedDevice.executeShellCommand("ps", psor); //$NON-NLS-1$
-                    } catch (IOException e) {
-                        // hmm...
-                    }
-                }
-            }.start();
-        }
-
-        return false;
-    }
-
-    /**
-     * Adds a new filter to the current filter array, and set its colors
-     * @param newFilter The filter to add
-     */
-    private void addFilterToArray(LogFilter newFilter) {
-        // set the colors
-        newFilter.setColors(mColors);
-
-        // add it to the array.
-        if (mFilters != null && mFilters.length > 0) {
-            LogFilter[] newFilters = new LogFilter[mFilters.length+1];
-            System.arraycopy(mFilters, 0, newFilters, 0, mFilters.length);
-            newFilters[mFilters.length] = newFilter;
-            mFilters = newFilters;
-        } else {
-            mFilters = new LogFilter[1];
-            mFilters[0] = newFilter;
-        }
-    }
-
-    private void removeFilterFromArray(LogFilter oldFilter) {
-        // look for the index
-        int index = -1;
-        for (int i = 0 ; i < mFilters.length ; i++) {
-            if (mFilters[i] == oldFilter) {
-                index = i;
-                break;
-            }
-        }
-
-        if (index != -1) {
-            LogFilter[] newFilters = new LogFilter[mFilters.length-1];
-            System.arraycopy(mFilters, 0, newFilters, 0, index);
-            System.arraycopy(mFilters, index + 1, newFilters, index,
-                    newFilters.length-index);
-            mFilters = newFilters;
-        }
-    }
-
-    /**
-     * Initialize the filter with already existing buffer.
-     * @param filter
-     */
-    private void initFilter(LogFilter filter) {
-        // is it empty
-        if (filter.uiReady() == false) {
-            return;
-        }
-
-        if (filter == mDefaultFilter) {
-            initDefaultFilter();
-            return;
-        }
-
-        filter.clear();
-
-        if (mBufferStart != -1) {
-            int max = mBufferEnd;
-            if (mBufferEnd < mBufferStart) {
-                max += STRING_BUFFER_LENGTH;
-            }
-
-            for (int i = mBufferStart; i < max; i++) {
-                int realItemIndex = i % STRING_BUFFER_LENGTH;
-
-                filter.addMessage(mBuffer[realItemIndex], null /* old message */);
-            }
-        }
-
-        filter.flush();
-        filter.resetTempFilteringStatus();
-    }
-
-    /**
-     * Refill the default filter. Not to be called directly.
-     * @see initFilter()
-     */
-    private void initDefaultFilter() {
-        mDefaultFilter.clear();
-
-        if (mBufferStart != -1) {
-            int max = mBufferEnd;
-            if (mBufferEnd < mBufferStart) {
-                max += STRING_BUFFER_LENGTH;
-            }
-
-            for (int i = mBufferStart; i < max; i++) {
-                int realItemIndex = i % STRING_BUFFER_LENGTH;
-                LogMessage msg = mBuffer[realItemIndex];
-
-                // first we check that the other filters don't take this message
-                boolean filtered = false;
-                for (LogFilter f : mFilters) {
-                    filtered |= f.accept(msg);
-                }
-
-                if (filtered == false) {
-                    mDefaultFilter.addMessage(msg, null /* old message */);
-                }
-            }
-        }
-
-        mDefaultFilter.flush();
-        mDefaultFilter.resetTempFilteringStatus();
-    }
-
-    /**
-     * Reset the filters, to handle change in device in automatic filter mode
-     */
-    private void resetFilters() {
-        // if we are in automatic mode, then we need to rmove the current
-        // filter.
-        if (mFilterMode == FILTER_AUTO_PID || mFilterMode == FILTER_AUTO_TAG) {
-            mFilters = null;
-
-            // recreate the filters.
-            createFilters();
-        }
-    }
-
-
-    private LogFilter getCurrentFilter() {
-        int index = mFolders.getSelectionIndex();
-
-        // if mFilters is null or index is invalid, we return the default
-        // filter. It doesn't matter if that one is null as well, since we
-        // would return null anyway.
-        if (index == 0 || mFilters == null) {
-            return mDefaultFilter;
-        }
-
-        return mFilters[index-1];
-    }
-
-
-    private void emptyTables() {
-        for (LogFilter f : mFilters) {
-            f.getTable().removeAll();
-        }
-
-        if (mDefaultFilter != null) {
-            mDefaultFilter.getTable().removeAll();
-        }
-    }
-
-    protected void updateFilteringWith(String text) {
-        synchronized (mBuffer) {
-            // reset the temp filtering for all the filters
-            for (LogFilter f : mFilters) {
-                f.resetTempFiltering();
-            }
-            if (mDefaultFilter != null) {
-                mDefaultFilter.resetTempFiltering();
-            }
-
-            // now we need to figure out the new temp filtering
-            // split each word
-            String[] segments = text.split(" "); //$NON-NLS-1$
-
-            ArrayList<String> keywords = new ArrayList<String>(segments.length);
-
-            // loop and look for temp id/tag
-            int tempPid = -1;
-            String tempTag = null;
-            for (int i = 0 ; i < segments.length; i++) {
-                String s = segments[i];
-                if (tempPid == -1 && s.startsWith("pid:")) { //$NON-NLS-1$
-                    // get the pid
-                    String[] seg = s.split(":"); //$NON-NLS-1$
-                    if (seg.length == 2) {
-                        if (seg[1].matches("^[0-9]*$")) { //$NON-NLS-1$
-                            tempPid = Integer.valueOf(seg[1]);
-                        }
-                    }
-                } else if (tempTag == null && s.startsWith("tag:")) { //$NON-NLS-1$
-                    String seg[] = segments[i].split(":"); //$NON-NLS-1$
-                    if (seg.length == 2) {
-                        tempTag = seg[1];
-                    }
-                } else {
-                    keywords.add(s);
-                }
-            }
-
-            // set the temp filtering in the filters
-            if (tempPid != -1 || tempTag != null || keywords.size() > 0) {
-                String[] keywordsArray = keywords.toArray(
-                        new String[keywords.size()]);
-
-                for (LogFilter f : mFilters) {
-                    if (tempPid != -1) {
-                        f.setTempPidFiltering(tempPid);
-                    }
-                    if (tempTag != null) {
-                        f.setTempTagFiltering(tempTag);
-                    }
-                    f.setTempKeywordFiltering(keywordsArray);
-                }
-
-                if (mDefaultFilter != null) {
-                    if (tempPid != -1) {
-                        mDefaultFilter.setTempPidFiltering(tempPid);
-                    }
-                    if (tempTag != null) {
-                        mDefaultFilter.setTempTagFiltering(tempTag);
-                    }
-                    mDefaultFilter.setTempKeywordFiltering(keywordsArray);
-
-                }
-            }
-
-            initFilter(mCurrentFilter);
-        }
-    }
-
-    /**
-     * Called when the current filter selection changes.
-     * @param selectedFilter
-     */
-    private void selectionChanged(LogFilter selectedFilter) {
-        if (mLogLevelActions != null) {
-            // get the log level
-            int level = selectedFilter.getLogLevel();
-            for (int i = 0 ; i < mLogLevelActions.length; i++) {
-                ICommonAction a = mLogLevelActions[i];
-                if (i == level - 2) {
-                    a.setChecked(true);
-                } else {
-                    a.setChecked(false);
-                }
-            }
-        }
-
-        if (mDeleteFilterAction != null) {
-            mDeleteFilterAction.setEnabled(selectedFilter.supportsDelete());
-        }
-        if (mEditFilterAction != null) {
-            mEditFilterAction.setEnabled(selectedFilter.supportsEdit());
-        }
-    }
-}
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/add.png b/tools/ddms/libs/ddmuilib/src/resources/images/add.png
deleted file mode 100644
index eefc2ca..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/add.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/android.png b/tools/ddms/libs/ddmuilib/src/resources/images/android.png
deleted file mode 100644
index 3779d4d..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/android.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/backward.png b/tools/ddms/libs/ddmuilib/src/resources/images/backward.png
deleted file mode 100644
index 90a9713..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/backward.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/clear.png b/tools/ddms/libs/ddmuilib/src/resources/images/clear.png
deleted file mode 100644
index 0009cf6..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/clear.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/d.png b/tools/ddms/libs/ddmuilib/src/resources/images/d.png
deleted file mode 100644
index d45506e..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/d.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/debug-attach.png b/tools/ddms/libs/ddmuilib/src/resources/images/debug-attach.png
deleted file mode 100644
index 9b8a11c..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/debug-attach.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/debug-error.png b/tools/ddms/libs/ddmuilib/src/resources/images/debug-error.png
deleted file mode 100644
index f22da1f..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/debug-error.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/debug-wait.png b/tools/ddms/libs/ddmuilib/src/resources/images/debug-wait.png
deleted file mode 100644
index 322be63..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/debug-wait.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/delete.png b/tools/ddms/libs/ddmuilib/src/resources/images/delete.png
deleted file mode 100644
index db5fab8..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/delete.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/device.png b/tools/ddms/libs/ddmuilib/src/resources/images/device.png
deleted file mode 100644
index 7dbbbb6..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/device.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/down.png b/tools/ddms/libs/ddmuilib/src/resources/images/down.png
deleted file mode 100644
index f9426cb..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/down.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/e.png b/tools/ddms/libs/ddmuilib/src/resources/images/e.png
deleted file mode 100644
index dee7c97..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/e.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/edit.png b/tools/ddms/libs/ddmuilib/src/resources/images/edit.png
deleted file mode 100644
index b8f65bc..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/edit.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/empty.png b/tools/ddms/libs/ddmuilib/src/resources/images/empty.png
deleted file mode 100644
index f021542..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/empty.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/emulator.png b/tools/ddms/libs/ddmuilib/src/resources/images/emulator.png
deleted file mode 100644
index a718042..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/emulator.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/file.png b/tools/ddms/libs/ddmuilib/src/resources/images/file.png
deleted file mode 100644
index 043a814..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/file.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/folder.png b/tools/ddms/libs/ddmuilib/src/resources/images/folder.png
deleted file mode 100644
index 7e29b1a..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/folder.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/forward.png b/tools/ddms/libs/ddmuilib/src/resources/images/forward.png
deleted file mode 100644
index a97a605..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/forward.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/gc.png b/tools/ddms/libs/ddmuilib/src/resources/images/gc.png
deleted file mode 100644
index 5194806..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/gc.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/halt.png b/tools/ddms/libs/ddmuilib/src/resources/images/halt.png
deleted file mode 100644
index 10e3720..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/halt.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/heap.png b/tools/ddms/libs/ddmuilib/src/resources/images/heap.png
deleted file mode 100644
index e3aa3f0..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/heap.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/hprof.png b/tools/ddms/libs/ddmuilib/src/resources/images/hprof.png
deleted file mode 100644
index 123d062..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/hprof.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/i.png b/tools/ddms/libs/ddmuilib/src/resources/images/i.png
deleted file mode 100644
index 98385c5..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/i.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/importBug.png b/tools/ddms/libs/ddmuilib/src/resources/images/importBug.png
deleted file mode 100644
index f5da179..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/importBug.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/load.png b/tools/ddms/libs/ddmuilib/src/resources/images/load.png
deleted file mode 100644
index 9e7bf6e..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/load.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/pause.png b/tools/ddms/libs/ddmuilib/src/resources/images/pause.png
deleted file mode 100644
index 19d286d..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/pause.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/play.png b/tools/ddms/libs/ddmuilib/src/resources/images/play.png
deleted file mode 100644
index d54f013..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/play.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/pull.png b/tools/ddms/libs/ddmuilib/src/resources/images/pull.png
deleted file mode 100644
index f48f1b1..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/pull.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/push.png b/tools/ddms/libs/ddmuilib/src/resources/images/push.png
deleted file mode 100644
index 6222864..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/push.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/save.png b/tools/ddms/libs/ddmuilib/src/resources/images/save.png
deleted file mode 100644
index 040ebda..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/save.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/thread.png b/tools/ddms/libs/ddmuilib/src/resources/images/thread.png
deleted file mode 100644
index ac839e8..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/thread.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/tracing_start.png b/tools/ddms/libs/ddmuilib/src/resources/images/tracing_start.png
deleted file mode 100644
index 88771cc..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/tracing_start.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/tracing_stop.png b/tools/ddms/libs/ddmuilib/src/resources/images/tracing_stop.png
deleted file mode 100644
index 71bd215..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/tracing_stop.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/up.png b/tools/ddms/libs/ddmuilib/src/resources/images/up.png
deleted file mode 100644
index 92edf5a..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/up.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/v.png b/tools/ddms/libs/ddmuilib/src/resources/images/v.png
deleted file mode 100644
index 8044051..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/v.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/w.png b/tools/ddms/libs/ddmuilib/src/resources/images/w.png
deleted file mode 100644
index 129d0f9..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/w.png
+++ /dev/null
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/warning.png b/tools/ddms/libs/ddmuilib/src/resources/images/warning.png
deleted file mode 100644
index ca3b6ed..0000000
--- a/tools/ddms/libs/ddmuilib/src/resources/images/warning.png
+++ /dev/null
Binary files differ
diff --git a/tools/draw9patch/Android.mk b/tools/draw9patch/Android.mk
deleted file mode 100644
index 934495d..0000000
--- a/tools/draw9patch/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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.
-
-DRAW9PATCH_LOCAL_DIR := $(call my-dir)
-include $(DRAW9PATCH_LOCAL_DIR)/etc/Android.mk
-include $(DRAW9PATCH_LOCAL_DIR)/src/Android.mk
diff --git a/tools/draw9patch/MODULE_LICENSE_APACHE2 b/tools/draw9patch/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/draw9patch/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/draw9patch/etc/Android.mk b/tools/draw9patch/etc/Android.mk
deleted file mode 100644
index 8d7d080..0000000
--- a/tools/draw9patch/etc/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := draw9patch
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/draw9patch/etc/draw9patch b/tools/draw9patch/etc/draw9patch
deleted file mode 100755
index 5d272a6..0000000
--- a/tools/draw9patch/etc/draw9patch
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-# Copyright 2008, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=draw9patch.jar
-frameworkdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Djava.ext.dirs="$frameworkdir" -jar "$jarpath" "$@"
diff --git a/tools/draw9patch/etc/draw9patch.bat b/tools/draw9patch/etc/draw9patch.bat
deleted file mode 100755
index e267b06..0000000
--- a/tools/draw9patch/etc/draw9patch.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-@echo off
-rem Copyright (C) 2008 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-set jarfile=draw9patch.jar
-set frameworkdir=
-set libdir=
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=lib\
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=..\framework\
-
-:JarFileOk
-
-set jarpath=%frameworkdir%%jarfile%
-
-call java -Djava.ext.dirs=%frameworkdir% -jar %jarpath% %*
diff --git a/tools/draw9patch/etc/manifest.txt b/tools/draw9patch/etc/manifest.txt
deleted file mode 100644
index b2e3528..0000000
--- a/tools/draw9patch/etc/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Main-Class: com.android.draw9patch.Application
-Class-Path: swing-worker-1.1.jar
diff --git a/tools/draw9patch/src/Android.mk b/tools/draw9patch/src/Android.mk
deleted file mode 100644
index 3dc9db4..0000000
--- a/tools/draw9patch/src/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	swing-worker-1.1
-LOCAL_MODULE := draw9patch
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/draw9patch/src/com/android/draw9patch/Application.java b/tools/draw9patch/src/com/android/draw9patch/Application.java
deleted file mode 100644
index 68c792a..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/Application.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.android.draw9patch;
-
-import com.android.draw9patch.ui.MainFrame;
-
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-
-public class Application {
-    private static void initUserInterface() {
-        System.setProperty("apple.laf.useScreenMenuBar", "true");
-        System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Draw 9-patch");
-
-        try {
-            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-        } catch (ClassNotFoundException e) {
-            e.printStackTrace();
-        } catch (InstantiationException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (UnsupportedLookAndFeelException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public static void main(final String... args) {
-        initUserInterface();
-        SwingUtilities.invokeLater(new Runnable() {
-            public void run() {
-                String arg = args.length > 0 ? args[0] : null;
-                MainFrame frame = new MainFrame(arg);
-                frame.setDefaultCloseOperation(MainFrame.EXIT_ON_CLOSE);
-                frame.setLocationRelativeTo(null);
-                frame.setVisible(true);
-            }
-        });
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/graphics/GraphicsUtilities.java b/tools/draw9patch/src/com/android/draw9patch/graphics/GraphicsUtilities.java
deleted file mode 100644
index c6c182c..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/graphics/GraphicsUtilities.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.android.draw9patch.graphics;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.awt.image.Raster;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsEnvironment;
-import java.awt.Graphics;
-import java.awt.Transparency;
-import java.net.URL;
-import java.io.IOException;
-
-public class GraphicsUtilities {
-    public static BufferedImage loadCompatibleImage(URL resource) throws IOException {
-        BufferedImage image = ImageIO.read(resource);
-        return toCompatibleImage(image);
-    }
-
-    public static BufferedImage createCompatibleImage(int width, int height) {
-        return getGraphicsConfiguration().createCompatibleImage(width, height);
-    }
-
-    public static BufferedImage toCompatibleImage(BufferedImage image) {
-        if (isHeadless()) {
-            return image;
-        }
-
-        if (image.getColorModel().equals(getGraphicsConfiguration().getColorModel())) {
-            return image;
-        }
-
-        BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(
-                    image.getWidth(), image.getHeight(), image.getTransparency());
-        Graphics g = compatibleImage.getGraphics();
-        g.drawImage(image, 0, 0, null);
-        g.dispose();
-
-        return compatibleImage;
-    }
-
-    public static BufferedImage createCompatibleImage(BufferedImage image, int width, int height) {
-        return getGraphicsConfiguration().createCompatibleImage(width, height,
-                                                   image.getTransparency());
-    }
-
-    private static GraphicsConfiguration getGraphicsConfiguration() {
-        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
-        return environment.getDefaultScreenDevice().getDefaultConfiguration();
-    }
-
-    private static boolean isHeadless() {
-        return GraphicsEnvironment.isHeadless();
-    }
-
-    public static BufferedImage createTranslucentCompatibleImage(int width, int height) {
-        return getGraphicsConfiguration().createCompatibleImage(width, height,
-                Transparency.TRANSLUCENT);
-    }
-
-    public static int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
-        if (w == 0 || h == 0) {
-            return new int[0];
-        }
-
-        if (pixels == null) {
-            pixels = new int[w * h];
-        } else if (pixels.length < w * h) {
-            throw new IllegalArgumentException("Pixels array must have a length >= w * h");
-        }
-
-        int imageType = img.getType();
-        if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) {
-            Raster raster = img.getRaster();
-            return (int[]) raster.getDataElements(x, y, w, h, pixels);
-        }
-
-        // Unmanages the image
-        return img.getRGB(x, y, w, h, pixels, 0, w);
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/GradientPanel.java b/tools/draw9patch/src/com/android/draw9patch/ui/GradientPanel.java
deleted file mode 100644
index bc1465f..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/GradientPanel.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.android.draw9patch.ui;
-
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.GradientPaint;
-import java.awt.Color;
-import java.awt.Rectangle;
-import java.awt.BorderLayout;
-import javax.swing.JPanel;
-
-class GradientPanel extends JPanel {
-    private static final int DARK_BLUE = 0x202737;
-
-    GradientPanel() {
-        super(new BorderLayout());
-    }
-
-    @Override
-    protected void paintComponent(Graphics g) {
-        Graphics2D g2 = (Graphics2D) g;
-        Rectangle clip = g2.getClipBounds();
-        Paint paint = g2.getPaint();
-
-        g2.setPaint(new GradientPaint(0.0f, getHeight() * 0.22f, new Color(DARK_BLUE),
-                                      0.0f, getHeight() * 0.9f, Color.BLACK));
-        g2.fillRect(clip.x, clip.y, clip.width, clip.height);
-
-        g2.setPaint(paint);
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/ImageEditorPanel.java b/tools/draw9patch/src/com/android/draw9patch/ui/ImageEditorPanel.java
deleted file mode 100644
index 84b96a5..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/ImageEditorPanel.java
+++ /dev/null
@@ -1,1180 +0,0 @@
-/*
- * 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.android.draw9patch.ui;
-
-import com.android.draw9patch.graphics.GraphicsUtilities;
-
-import javax.swing.JPanel;
-import javax.swing.JLabel;
-import javax.swing.BorderFactory;
-import javax.swing.JSlider;
-import javax.swing.JComponent;
-import javax.swing.JScrollPane;
-import javax.swing.JCheckBox;
-import javax.swing.Box;
-import javax.swing.JFileChooser;
-import javax.swing.JSplitPane;
-import javax.swing.JButton;
-import javax.swing.border.EmptyBorder;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.ChangeEvent;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.awt.Graphics2D;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Dimension;
-import java.awt.TexturePaint;
-import java.awt.Shape;
-import java.awt.BasicStroke;
-import java.awt.RenderingHints;
-import java.awt.Rectangle;
-import java.awt.GridBagLayout;
-import java.awt.GridBagConstraints;
-import java.awt.Insets;
-import java.awt.Toolkit;
-import java.awt.AWTEvent;
-import java.awt.event.MouseMotionAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.AWTEventListener;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.Line2D;
-import java.awt.geom.Area;
-import java.awt.geom.RoundRectangle2D;
-import java.io.IOException;
-import java.io.File;
-import java.net.URL;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-class ImageEditorPanel extends JPanel {
-    private static final String EXTENSION_9PATCH = ".9.png";
-    private static final int DEFAULT_ZOOM = 8;
-    private static final float DEFAULT_SCALE = 2.0f;
-
-    private String name;
-    private BufferedImage image;
-    private boolean is9Patch;
-
-    private ImageViewer viewer;
-    private StretchesViewer stretchesViewer;
-    private JLabel xLabel;
-    private JLabel yLabel;
-
-    private TexturePaint texture;    
-
-    private List<Rectangle> patches;
-    private List<Rectangle> horizontalPatches;
-    private List<Rectangle> verticalPatches;
-    private List<Rectangle> fixed;
-    private boolean verticalStartWithPatch;
-    private boolean horizontalStartWithPatch;
-
-    private Pair<Integer> horizontalPadding;
-    private Pair<Integer> verticalPadding;    
-
-    ImageEditorPanel(MainFrame mainFrame, BufferedImage image, String name) {
-        this.image = image;
-        this.name = name;
-
-        setTransferHandler(new ImageTransferHandler(mainFrame));
-
-        checkImage();
-
-        setOpaque(false);
-        setLayout(new BorderLayout());
-
-        loadSupport();
-        buildImageViewer();
-        buildStatusPanel();
-    }
-
-    private void loadSupport() {
-        try {
-            URL resource = getClass().getResource("/images/checker.png");
-            BufferedImage checker = GraphicsUtilities.loadCompatibleImage(resource);
-            texture = new TexturePaint(checker, new Rectangle2D.Double(0, 0,
-                    checker.getWidth(), checker.getHeight()));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void buildImageViewer() {
-        viewer = new ImageViewer();
-
-        JSplitPane splitter = new JSplitPane();
-        splitter.setContinuousLayout(true);
-        splitter.setResizeWeight(0.8);
-        splitter.setBorder(null);
-
-        JScrollPane scroller = new JScrollPane(viewer);
-        scroller.setOpaque(false);
-        scroller.setBorder(null);
-        scroller.getViewport().setBorder(null);
-        scroller.getViewport().setOpaque(false);
-
-        splitter.setLeftComponent(scroller);
-        splitter.setRightComponent(buildStretchesViewer());
-
-        add(splitter);
-    }
-
-    private JComponent buildStretchesViewer() {
-        stretchesViewer = new StretchesViewer();
-        JScrollPane scroller = new JScrollPane(stretchesViewer);
-        scroller.setBorder(null);
-        scroller.getViewport().setBorder(null);
-        scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
-        scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
-        return scroller;
-    }
-
-    private void buildStatusPanel() {
-        JPanel status = new JPanel(new GridBagLayout());
-        status.setOpaque(false);
-
-        JLabel label = new JLabel();
-        label.setForeground(Color.WHITE);
-        label.setText("Zoom: ");
-        label.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(label, new GridBagConstraints(0, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                new Insets(0, 6, 0, 0), 0, 0));
-
-        label = new JLabel();
-        label.setForeground(Color.WHITE);
-        label.setText("100%");
-        label.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(label, new GridBagConstraints(1, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        JSlider zoomSlider = new JSlider(1, 16, DEFAULT_ZOOM);
-        zoomSlider.setSnapToTicks(true);
-        zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
-        zoomSlider.addChangeListener(new ChangeListener() {
-            public void stateChanged(ChangeEvent evt) {
-                viewer.setZoom(((JSlider) evt.getSource()).getValue());
-            }
-        });
-        status.add(zoomSlider, new GridBagConstraints(2, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        JLabel maxZoomLabel = new JLabel();
-        maxZoomLabel.setForeground(Color.WHITE);
-        maxZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
-        maxZoomLabel.setText("800%");
-        status.add(maxZoomLabel, new GridBagConstraints(3, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        label = new JLabel();
-        label.setForeground(Color.WHITE);
-        label.setText("Patch scale: ");
-        label.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(label, new GridBagConstraints(0, 1, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 6, 0, 0), 0, 0));
-
-        label = new JLabel();
-        label.setForeground(Color.WHITE);
-        label.setText("2x");
-        label.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(label, new GridBagConstraints(1, 1, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        zoomSlider = new JSlider(200, 600, (int) (DEFAULT_SCALE * 100.0f));
-        zoomSlider.setSnapToTicks(true);
-        zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
-        zoomSlider.addChangeListener(new ChangeListener() {
-            public void stateChanged(ChangeEvent evt) {
-                stretchesViewer.setScale(((JSlider) evt.getSource()).getValue() / 100.0f);
-            }
-        });
-        status.add(zoomSlider, new GridBagConstraints(2, 1, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        maxZoomLabel = new JLabel();
-        maxZoomLabel.setForeground(Color.WHITE);
-        maxZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
-        maxZoomLabel.setText("6x");
-        status.add(maxZoomLabel, new GridBagConstraints(3, 1, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        JCheckBox showLock = new JCheckBox("Show lock");
-        showLock.setOpaque(false);
-        showLock.setForeground(Color.WHITE);
-        showLock.setSelected(true);
-        showLock.putClientProperty("JComponent.sizeVariant", "small");
-        showLock.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent event) {
-                viewer.setLockVisible(((JCheckBox) event.getSource()).isSelected());
-            }
-        });
-        status.add(showLock, new GridBagConstraints(4, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 12, 0, 0), 0, 0));
-
-        JCheckBox showPatches = new JCheckBox("Show patches");
-        showPatches.setOpaque(false);
-        showPatches.setForeground(Color.WHITE);
-        showPatches.putClientProperty("JComponent.sizeVariant", "small");
-        showPatches.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent event) {
-                viewer.setPatchesVisible(((JCheckBox) event.getSource()).isSelected());
-            }
-        });
-        status.add(showPatches, new GridBagConstraints(4, 1, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 12, 0, 0), 0, 0));
-
-        JCheckBox showPadding = new JCheckBox("Show content");
-        showPadding.setOpaque(false);
-        showPadding.setForeground(Color.WHITE);
-        showPadding.putClientProperty("JComponent.sizeVariant", "small");
-        showPadding.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent event) {
-                stretchesViewer.setPaddingVisible(((JCheckBox) event.getSource()).isSelected());
-            }
-        });
-        status.add(showPadding, new GridBagConstraints(5, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                new Insets(0, 12, 0, 0), 0, 0));
-
-        status.add(Box.createHorizontalGlue(), new GridBagConstraints(6, 0, 1, 1, 1.0f, 1.0f,
-                GridBagConstraints.LINE_START, GridBagConstraints.BOTH,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        label = new JLabel("X: ");
-        label.setForeground(Color.WHITE);
-        label.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(label, new GridBagConstraints(7, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        xLabel = new JLabel("0px");
-        xLabel.setForeground(Color.WHITE);
-        xLabel.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(xLabel, new GridBagConstraints(8, 0, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 6), 0, 0));
-
-        label = new JLabel("Y: ");
-        label.setForeground(Color.WHITE);
-        label.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(label, new GridBagConstraints(7, 1, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 0), 0, 0));
-
-        yLabel = new JLabel("0px");
-        yLabel.setForeground(Color.WHITE);
-        yLabel.putClientProperty("JComponent.sizeVariant", "small");
-        status.add(yLabel, new GridBagConstraints(8, 1, 1, 1, 0.0f, 0.0f,
-                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                new Insets(0, 0, 0, 6), 0, 0));
-
-        add(status, BorderLayout.SOUTH);
-    }
-
-    private void checkImage() {
-        is9Patch = name.endsWith(EXTENSION_9PATCH);
-        if (!is9Patch) {
-            convertTo9Patch();
-        } else {
-            ensure9Patch();
-        }
-    }
-
-    private void ensure9Patch() {
-        int width = image.getWidth();
-        int height = image.getHeight();
-        for (int i = 0; i < width; i++) {
-            int pixel = image.getRGB(i, 0);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(i, 0, 0);
-            }
-            pixel = image.getRGB(i, height - 1);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(i, height - 1, 0);
-            }
-        }
-        for (int i = 0; i < height; i++) {
-            int pixel = image.getRGB(0, i);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(0, i, 0);
-            }
-            pixel = image.getRGB(width - 1, i);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(width - 1, i, 0);
-            }
-        }
-    }
-
-    private void convertTo9Patch() {
-        BufferedImage buffer = GraphicsUtilities.createTranslucentCompatibleImage(
-                image.getWidth() + 2, image.getHeight() + 2);
-
-        Graphics2D g2 = buffer.createGraphics();
-        g2.drawImage(image, 1, 1, null);
-        g2.dispose();
-
-        image = buffer;
-        name = name.substring(0, name.lastIndexOf('.')) + ".9.png";
-    }
-
-    File chooseSaveFile() {
-        if (is9Patch) {
-            return new File(name);
-        } else {
-            JFileChooser chooser = new JFileChooser();
-            chooser.setFileFilter(new PngFileFilter());
-            int choice = chooser.showSaveDialog(this);
-            if (choice == JFileChooser.APPROVE_OPTION) {
-                File file = chooser.getSelectedFile();
-                if (!file.getAbsolutePath().endsWith(EXTENSION_9PATCH)) {
-                    String path = file.getAbsolutePath();
-                    if (path.endsWith(".png")) {
-                        path = path.substring(0, path.lastIndexOf(".png")) + EXTENSION_9PATCH;
-                    } else {
-                        path = path + EXTENSION_9PATCH;
-                    }
-                    name = path;
-                    is9Patch = true;
-                    return new File(path);
-                }
-                is9Patch = true;
-                return file;
-            }
-        }
-        return null;
-    }
-
-    RenderedImage getImage() {
-        return image;
-    }
-
-    private class StretchesViewer extends JPanel {
-        private static final int MARGIN = 24;
-
-        private StretchView horizontal;
-        private StretchView vertical;
-        private StretchView both;
-
-        private Dimension size;
-
-        private float horizontalPatchesSum;
-        private float verticalPatchesSum;
-
-        private boolean showPadding;
-
-        StretchesViewer() {
-            setOpaque(false);
-            setLayout(new GridBagLayout());
-            setBorder(BorderFactory.createEmptyBorder(MARGIN, MARGIN, MARGIN, MARGIN));
-
-            horizontal = new StretchView();
-            vertical = new StretchView();
-            both = new StretchView();
-
-            setScale(DEFAULT_SCALE);
-            
-            add(vertical, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
-                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
-            add(horizontal, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
-                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
-            add(both, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
-                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            Graphics2D g2 = (Graphics2D) g.create();
-            g2.setPaint(texture);
-            g2.fillRect(0, 0, getWidth(), getHeight());
-            g2.dispose();
-        }
-
-        void setScale(float scale) {
-            int patchWidth = image.getWidth() - 2;
-            int patchHeight = image.getHeight() - 2;
-
-            int scaledWidth = (int) (patchWidth * scale);
-            int scaledHeight = (int) (patchHeight * scale);
-
-            horizontal.scaledWidth = scaledWidth;
-            vertical.scaledHeight = scaledHeight;
-            both.scaledWidth = scaledWidth;
-            both.scaledHeight = scaledHeight;
-
-            size = new Dimension(scaledWidth, scaledHeight);
-
-            computePatches();
-        }
-
-        void computePatches() {
-            boolean measuredWidth = false;
-            boolean endRow = true;
-
-            int remainderHorizontal = 0;
-            int remainderVertical = 0;
-
-            if (fixed.size() > 0) {
-                int start = fixed.get(0).y;
-                for (Rectangle rect : fixed) {
-                    if (rect.y > start) {
-                        endRow = true;
-                        measuredWidth = true;
-                    }
-                    if (!measuredWidth) {
-                        remainderHorizontal += rect.width;
-                    }
-                    if (endRow) {
-                        remainderVertical += rect.height;
-                        endRow = false;
-                        start = rect.y;
-                    }
-                }
-            }
-
-            horizontal.remainderHorizontal = horizontal.scaledWidth - remainderHorizontal;
-            vertical.remainderHorizontal = vertical.scaledWidth - remainderHorizontal;
-            both.remainderHorizontal = both.scaledWidth - remainderHorizontal;
-
-            horizontal.remainderVertical = horizontal.scaledHeight - remainderVertical;
-            vertical.remainderVertical = vertical.scaledHeight - remainderVertical;
-            both.remainderVertical = both.scaledHeight - remainderVertical;
-
-            horizontalPatchesSum = 0;
-            if (horizontalPatches.size() > 0) {
-                int start = -1;
-                for (Rectangle rect : horizontalPatches) {
-                    if (rect.x > start) {
-                        horizontalPatchesSum += rect.width;
-                        start = rect.x;
-                    }
-                }
-            } else {
-                int start = -1;
-                for (Rectangle rect : patches) {
-                    if (rect.x > start) {
-                        horizontalPatchesSum += rect.width;
-                        start = rect.x;
-                    }
-                }
-            }
-
-            verticalPatchesSum = 0;
-            if (verticalPatches.size() > 0) {
-                int start = -1;
-                for (Rectangle rect : verticalPatches) {
-                    if (rect.y > start) {
-                        verticalPatchesSum += rect.height;
-                        start = rect.y;
-                    }
-                }
-            } else {
-                int start = -1;
-                for (Rectangle rect : patches) {
-                    if (rect.y > start) {
-                        verticalPatchesSum += rect.height;
-                        start = rect.y;
-                    }
-                }
-            }
-
-            setSize(size);
-            ImageEditorPanel.this.validate();
-            repaint();
-        }
-
-        void setPaddingVisible(boolean visible) {
-            showPadding = visible;
-            repaint();
-        }
-
-        private class StretchView extends JComponent {
-            private final Color PADDING_COLOR = new Color(0.37f, 0.37f, 1.0f, 0.5f);
-
-            int scaledWidth;
-            int scaledHeight;
-
-            int remainderHorizontal;
-            int remainderVertical;
-
-            StretchView() {
-                scaledWidth = image.getWidth();
-                scaledHeight = image.getHeight();
-            }
-
-            @Override
-            protected void paintComponent(Graphics g) {
-                int x = (getWidth() - scaledWidth) / 2;
-                int y = (getHeight() - scaledHeight) / 2;
-
-                Graphics2D g2 = (Graphics2D) g.create();
-                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                g.translate(x, y);
-
-                x = 0;
-                y = 0;
-
-                if (patches.size() == 0) {
-                    g.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
-                    g2.dispose();
-                    return;
-                }
-
-                int fixedIndex = 0;
-                int horizontalIndex = 0;
-                int verticalIndex = 0;
-                int patchIndex = 0;
-
-                boolean hStretch;
-                boolean vStretch;
-
-                float vWeightSum = 1.0f;
-                float vRemainder = remainderVertical;
-
-                vStretch = verticalStartWithPatch;
-                while (y < scaledHeight - 1) {
-                    hStretch = horizontalStartWithPatch;
-
-                    int height = 0;
-                    float vExtra = 0.0f;
-
-                    float hWeightSum = 1.0f;
-                    float hRemainder = remainderHorizontal;
-
-                    while (x < scaledWidth - 1) {
-                        Rectangle r;
-                        if (!vStretch) {
-                            if (hStretch) {
-                                r = horizontalPatches.get(horizontalIndex++);
-                                float extra = r.width / horizontalPatchesSum;
-                                int width = (int) (extra * hRemainder / hWeightSum);
-                                hWeightSum -= extra;
-                                hRemainder -= width;
-                                g.drawImage(image, x, y, x + width, y + r.height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += width;
-                            } else {
-                                r = fixed.get(fixedIndex++);
-                                g.drawImage(image, x, y, x + r.width, y + r.height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += r.width;
-                            }
-                            height = r.height;
-                        } else {
-                            if (hStretch) {
-                                r = patches.get(patchIndex++);
-                                vExtra = r.height / verticalPatchesSum;
-                                height = (int) (vExtra * vRemainder / vWeightSum);
-                                float extra = r.width / horizontalPatchesSum;
-                                int width = (int) (extra * hRemainder / hWeightSum);
-                                hWeightSum -= extra;
-                                hRemainder -= width;
-                                g.drawImage(image, x, y, x + width, y + height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += width;
-                            } else {
-                                r = verticalPatches.get(verticalIndex++);
-                                vExtra = r.height / verticalPatchesSum;
-                                height = (int) (vExtra * vRemainder / vWeightSum);
-                                g.drawImage(image, x, y, x + r.width, y + height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += r.width;
-                            }
-                            
-                        }
-                        hStretch = !hStretch;
-                    }
-                    x = 0;
-                    y += height;
-                    if (vStretch) {
-                        vWeightSum -= vExtra;
-                        vRemainder -= height;
-                    }
-                    vStretch = !vStretch;
-                }
-
-                if (showPadding) {
-                    g.setColor(PADDING_COLOR);
-                    g.fillRect(horizontalPadding.first, verticalPadding.first,
-                            scaledWidth - horizontalPadding.first - horizontalPadding.second,
-                            scaledHeight - verticalPadding.first - verticalPadding.second);
-                }
-
-                g2.dispose();
-            }
-
-            @Override
-            public Dimension getPreferredSize() {
-                return size;
-            }
-        }
-    }
-
-    private class ImageViewer extends JComponent {
-        private final Color CORRUPTED_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.7f);
-        private final Color LOCK_COLOR = new Color(0.0f, 0.0f, 0.0f, 0.7f);
-        private final Color STRIPES_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.5f);
-        private final Color BACK_COLOR = new Color(0xc0c0c0);
-        private final Color HELP_COLOR = new Color(0xffffe1);
-        private final Color PATCH_COLOR = new Color(1.0f, 0.37f, 0.99f, 0.5f);
-        private final Color PATCH_ONEWAY_COLOR = new Color(0.37f, 1.0f, 0.37f, 0.5f);
-
-        private static final float STRIPES_WIDTH = 4.0f;
-        private static final double STRIPES_SPACING = 6.0;
-        private static final int STRIPES_ANGLE = 45;
-
-        private int zoom;
-        private boolean showPatches;
-        private boolean showLock = true;
-
-        private Dimension size;
-
-        private boolean locked;
-
-        private int[] row;
-        private int[] column;
-
-        private int lastPositionX;
-        private int lastPositionY;
-        private int currentButton;
-        private boolean showCursor;
-
-        private JLabel helpLabel;
-        private boolean eraseMode;
-
-        private JButton checkButton;
-        private List<Rectangle> corruptedPatches;
-        private boolean showBadPatches;
-
-        private JPanel helpPanel;
-
-        ImageViewer() {
-            setLayout(new GridBagLayout());
-            helpPanel = new JPanel(new BorderLayout());
-            helpPanel.setBorder(new EmptyBorder(0, 6, 0, 6));
-            helpPanel.setBackground(HELP_COLOR);
-            helpLabel = new JLabel("Press Shift to erase pixels");
-            helpLabel.putClientProperty("JComponent.sizeVariant", "small");            
-            helpPanel.add(helpLabel, BorderLayout.WEST);
-            checkButton = new JButton("Show bad patches");
-            checkButton.putClientProperty("JComponent.sizeVariant", "small");
-            checkButton.putClientProperty("JButton.buttonType", "roundRect");
-            helpPanel.add(checkButton, BorderLayout.EAST);
-
-            add(helpPanel, new GridBagConstraints(0, 0, 1, 1,
-                    1.0f, 1.0f, GridBagConstraints.FIRST_LINE_START, GridBagConstraints.HORIZONTAL,
-                    new Insets(0, 0, 0, 0), 0, 0));
-
-            setOpaque(true);
-
-            setZoom(DEFAULT_ZOOM);
-            findPatches();
-
-            addMouseListener(new MouseAdapter() {
-                @Override
-                public void mousePressed(MouseEvent event) {
-                    // Store the button here instead of retrieving it again in MouseDragged
-                    // below, because on linux, calling MouseEvent.getButton() for the drag
-                    // event returns 0, which appears to be technically correct (no button
-                    // changed state).
-                    currentButton = event.isShiftDown() ? MouseEvent.BUTTON3 : event.getButton();
-                    paint(event.getX(), event.getY(), currentButton);
-                }
-            });
-            addMouseMotionListener(new MouseMotionAdapter() {
-                @Override
-                public void mouseDragged(MouseEvent event) {
-                    if (!checkLockedRegion(event.getX(), event.getY())) {
-                        // use the stored button, see note above
-                        paint(event.getX(), event.getY(),  currentButton);
-                    }
-                }
-
-                @Override
-                public void mouseMoved(MouseEvent event) {
-                    checkLockedRegion(event.getX(), event.getY());
-                }
-            });
-            Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
-                public void eventDispatched(AWTEvent event) {
-                    enableEraseMode((KeyEvent) event);                    
-                }
-            }, AWTEvent.KEY_EVENT_MASK);
-
-            checkButton.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent event) {
-                    if (!showBadPatches) {
-                        findBadPatches();
-                        checkButton.setText("Hide bad patches");
-                    } else {
-                        checkButton.setText("Show bad patches");
-                        corruptedPatches = null;
-                    }
-                    repaint();
-                    showBadPatches = !showBadPatches;
-                }
-            });
-        }
-
-        private void findBadPatches() {
-            corruptedPatches = new ArrayList<Rectangle>();
-
-            for (Rectangle patch : patches) {
-                if (corruptPatch(patch)) {
-                    corruptedPatches.add(patch);
-                }
-            }
-
-            for (Rectangle patch : horizontalPatches) {
-                if (corruptHorizontalPatch(patch)) {
-                    corruptedPatches.add(patch);
-                }
-            }
-
-            for (Rectangle patch : verticalPatches) {
-                if (corruptVerticalPatch(patch)) {
-                    corruptedPatches.add(patch);
-                }
-            }
-        }
-
-        private boolean corruptPatch(Rectangle patch) {
-            int[] pixels = GraphicsUtilities.getPixels(image, patch.x, patch.y,
-                    patch.width, patch.height, null);
-
-            if (pixels.length > 0) {
-                int reference = pixels[0];
-                for (int pixel : pixels) {
-                    if (pixel != reference) {
-                        return true;
-                    }
-                }
-            }
-
-            return false;
-        }
-
-        private boolean corruptHorizontalPatch(Rectangle patch) {
-            int[] reference = new int[patch.height];
-            int[] column = new int[patch.height];
-            reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
-                    1, patch.height, reference);
-
-            for (int i = 1; i < patch.width; i++) {
-                column = GraphicsUtilities.getPixels(image, patch.x + i, patch.y,
-                        1, patch.height, column);
-                if (!Arrays.equals(reference, column)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        private boolean corruptVerticalPatch(Rectangle patch) {
-            int[] reference = new int[patch.width];
-            int[] row = new int[patch.width];
-            reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
-                    patch.width, 1, reference);
-
-            for (int i = 1; i < patch.height; i++) {
-                row = GraphicsUtilities.getPixels(image, patch.x, patch.y + i, patch.width, 1, row);
-                if (!Arrays.equals(reference, row)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        private void enableEraseMode(KeyEvent event) {
-            boolean oldEraseMode = eraseMode;
-            eraseMode = event.isShiftDown();
-            if (eraseMode != oldEraseMode) {
-                if (eraseMode) {
-                    helpLabel.setText("Release Shift to draw pixels");
-                } else {
-                    helpLabel.setText("Press Shift to erase pixels");
-                }
-            }
-        }
-
-        private void paint(int x, int y, int button) {
-            int color;
-            switch (button) {
-                case MouseEvent.BUTTON1:
-                    color = 0xFF000000;
-                    break;
-                case MouseEvent.BUTTON3:
-                    color = 0;
-                    break;
-                default:
-                    return;
-            }
-
-            int left = (getWidth() - size.width) / 2;
-            int top = (helpPanel.getHeight() + getHeight() - size.height) / 2;
-
-            x = (x - left) / zoom;
-            y = (y - top) / zoom;
-
-            int width = image.getWidth();
-            int height = image.getHeight();
-            if (((x == 0 || x == width - 1) && (y > 0 && y < height - 1)) ||
-                    ((x > 0 && x < width - 1) && (y == 0 || y == height - 1))) {
-                image.setRGB(x, y, color);
-                findPatches();
-                stretchesViewer.computePatches();
-                if (showBadPatches) {
-                    findBadPatches();
-                }
-                repaint();
-            }
-        }
-
-        private boolean checkLockedRegion(int x, int y) {
-            int oldX = lastPositionX;
-            int oldY = lastPositionY;
-            lastPositionX = x;
-            lastPositionY = y;
-
-            int left = (getWidth() - size.width) / 2;
-            int top = (helpPanel.getHeight() + getHeight() - size.height) / 2;
-
-            x = (x - left) / zoom;
-            y = (y - top) / zoom;
-
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            xLabel.setText(Math.max(0, Math.min(x, width - 1)) + " px");
-            yLabel.setText(Math.max(0, Math.min(y, height - 1)) + " px");
-
-            boolean previousLock = locked;
-            locked = x > 0 && x < width - 1 && y > 0 && y < height - 1;
-
-            boolean previousCursor = showCursor;
-            showCursor = ((x == 0 || x == width - 1) && (y > 0 && y < height - 1)) ||
-                    ((x > 0 && x < width - 1) && (y == 0 || y == height - 1));
-
-            if (locked != previousLock) {
-                repaint();
-            } else if (showCursor || (showCursor != previousCursor)) {
-                Rectangle clip = new Rectangle(lastPositionX - 1 - zoom / 2,
-                        lastPositionY - 1 - zoom / 2, zoom + 2, zoom + 2);
-                clip = clip.union(new Rectangle(oldX - 1 - zoom / 2,
-                        oldY - 1 - zoom / 2, zoom + 2, zoom + 2));
-                repaint(clip);
-            }
-
-            return locked;
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            int x = (getWidth() - size.width) / 2;
-            int y = (helpPanel.getHeight() + getHeight() - size.height) / 2;
-
-            Graphics2D g2 = (Graphics2D) g.create();
-            g2.setColor(BACK_COLOR);
-            g2.fillRect(0, 0, getWidth(), getHeight());
-
-            g2.translate(x, y);
-            g2.setPaint(texture);
-            g2.fillRect(0, 0, size.width, size.height);
-            g2.scale(zoom, zoom);
-            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-                    RenderingHints.VALUE_ANTIALIAS_ON);
-            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                    RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
-            g2.drawImage(image, 0, 0, null);
-
-            if (showPatches) {
-                g2.setColor(PATCH_COLOR);
-                for (Rectangle patch : patches) {
-                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
-                }
-                g2.setColor(PATCH_ONEWAY_COLOR);
-                for (Rectangle patch : horizontalPatches) {
-                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
-                }
-                for (Rectangle patch : verticalPatches) {
-                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
-                }
-            }
-
-            if (corruptedPatches != null) {
-                g2.setColor(CORRUPTED_COLOR);
-                g2.setStroke(new BasicStroke(3.0f / zoom));
-                for (Rectangle patch : corruptedPatches) {
-                    g2.draw(new RoundRectangle2D.Float(patch.x - 2.0f / zoom, patch.y - 2.0f / zoom,
-                            patch.width + 2.0f / zoom, patch.height + 2.0f / zoom,
-                            6.0f / zoom, 6.0f / zoom));
-                }
-            }
-
-            if (showLock && locked) {
-                int width = image.getWidth();
-                int height = image.getHeight();
-
-                g2.setColor(LOCK_COLOR);
-                g2.fillRect(1, 1, width - 2, height - 2);
-
-                g2.setColor(STRIPES_COLOR);
-                g2.translate(1, 1);
-                paintStripes(g2, width - 2, height - 2);
-                g2.translate(-1, -1);
-            }
-
-            g2.dispose();
-
-            if (showCursor) {
-                Graphics cursor = g.create();
-                cursor.setXORMode(Color.WHITE);
-                cursor.setColor(Color.BLACK);
-                cursor.drawRect(lastPositionX - zoom / 2, lastPositionY - zoom / 2, zoom, zoom);
-                cursor.dispose();
-            }
-        }
-
-        private void paintStripes(Graphics2D g, int width, int height) {
-            //draws pinstripes at the angle specified in this class
-            //and at the given distance apart
-            Shape oldClip = g.getClip();
-            Area area = new Area(new Rectangle(0, 0, width, height));
-            if(oldClip != null) {
-                area = new Area(oldClip);
-            }
-            area.intersect(new Area(new Rectangle(0,0,width,height)));
-            g.setClip(area);
-
-            g.setStroke(new BasicStroke(STRIPES_WIDTH));
-
-            double hypLength = Math.sqrt((width * width) +
-                    (height * height));
-
-            double radians = Math.toRadians(STRIPES_ANGLE);
-            g.rotate(radians);
-
-            double spacing = STRIPES_SPACING;
-            spacing += STRIPES_WIDTH;
-            int numLines = (int)(hypLength / spacing);
-
-            for (int i=0; i<numLines; i++) {
-                double x = i * spacing;
-                Line2D line = new Line2D.Double(x, -hypLength, x, hypLength);
-                g.draw(line);
-            }
-            g.setClip(oldClip);
-        }
-
-        @Override
-        public Dimension getPreferredSize() {
-            return size;
-        }
-
-        void setZoom(int value) {
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            zoom = value;
-            size = new Dimension(width * zoom, height * zoom);
-
-            setSize(size);
-            ImageEditorPanel.this.validate();
-            repaint();
-        }
-
-        void setPatchesVisible(boolean visible) {
-            showPatches = visible;
-            findPatches();
-            repaint();
-        }
-
-        private void findPatches() {
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            row = GraphicsUtilities.getPixels(image, 0, 0, width, 1, row);
-            column = GraphicsUtilities.getPixels(image, 0, 0, 1, height, column);
-
-            boolean[] result = new boolean[1];
-            Pair<List<Pair<Integer>>> left = getPatches(column, result);
-            verticalStartWithPatch = result[0];
-
-            result = new boolean[1];
-            Pair<List<Pair<Integer>>> top = getPatches(row, result);
-            horizontalStartWithPatch = result[0];
-
-            fixed = getRectangles(left.first, top.first);
-            patches = getRectangles(left.second, top.second);
-
-            if (fixed.size() > 0) {
-                horizontalPatches = getRectangles(left.first, top.second);
-                verticalPatches = getRectangles(left.second, top.first);
-            } else {
-                if (top.first.size() > 0) {
-                    horizontalPatches = new ArrayList<Rectangle>(0);
-                    verticalPatches = getVerticalRectangles(top.first);
-                } else if (left.first.size() > 0) {
-                    horizontalPatches = getHorizontalRectangles(left.first);
-                    verticalPatches = new ArrayList<Rectangle>(0);
-                } else {
-                    horizontalPatches = verticalPatches = new ArrayList<Rectangle>(0);
-                }
-            }
-
-            row = GraphicsUtilities.getPixels(image, 0, height - 1, width, 1, row);
-            column = GraphicsUtilities.getPixels(image, width - 1, 0, 1, height, column);
-
-            top = getPatches(row, result);
-            horizontalPadding = getPadding(top.first);
-
-            left = getPatches(column, result);
-            verticalPadding = getPadding(left.first);
-        }
-
-        private List<Rectangle> getVerticalRectangles(List<Pair<Integer>> topPairs) {
-            List<Rectangle> rectangles = new ArrayList<Rectangle>();
-            for (Pair<Integer> top : topPairs) {
-                int x = top.first;
-                int width = top.second - top.first;
-
-                rectangles.add(new Rectangle(x, 1, width, image.getHeight() - 2));
-            }
-            return rectangles;
-        }
-
-        private List<Rectangle> getHorizontalRectangles(List<Pair<Integer>> leftPairs) {
-            List<Rectangle> rectangles = new ArrayList<Rectangle>();
-            for (Pair<Integer> left : leftPairs) {
-                int y = left.first;
-                int height = left.second - left.first;
-
-                rectangles.add(new Rectangle(1, y, image.getWidth() - 2, height));
-            }
-            return rectangles;
-        }
-
-        private Pair<Integer> getPadding(List<Pair<Integer>> pairs) {
-            if (pairs.size() == 0) {
-                return new Pair<Integer>(0, 0);
-            } else if (pairs.size() == 1) {
-                if (pairs.get(0).first == 1) {
-                    return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first, 0);
-                } else {
-                    return new Pair<Integer>(0, pairs.get(0).second - pairs.get(0).first);                    
-                }
-            } else {
-                int index = pairs.size() - 1;
-                return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first,
-                        pairs.get(index).second - pairs.get(index).first);
-            }
-        }
-
-        private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs,
-                List<Pair<Integer>> topPairs) {
-            List<Rectangle> rectangles = new ArrayList<Rectangle>();
-            for (Pair<Integer> left : leftPairs) {
-                int y = left.first;
-                int height = left.second - left.first;
-                for (Pair<Integer> top : topPairs) {
-                    int x = top.first;
-                    int width = top.second - top.first;
-
-                    rectangles.add(new Rectangle(x, y, width, height));
-                }
-            }
-            return rectangles;
-        }
-
-        private Pair<List<Pair<Integer>>> getPatches(int[] pixels, boolean[] startWithPatch) {
-            int lastIndex = 1;
-            int lastPixel = pixels[1];
-            boolean first = true;
-
-            List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>();
-            List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>();
-
-            for (int i = 1; i < pixels.length - 1; i++) {
-                int pixel = pixels[i];
-                if (pixel != lastPixel) {
-                    if (lastPixel == 0xFF000000) {
-                        if (first) startWithPatch[0] = true;
-                        patches.add(new Pair<Integer>(lastIndex, i));
-                    } else {
-                        fixed.add(new Pair<Integer>(lastIndex, i));
-                    }
-                    first = false;
-
-                    lastIndex = i;
-                    lastPixel = pixel;
-                }
-            }
-            if (lastPixel == 0xFF000000) {
-                if (first) startWithPatch[0] = true;
-                patches.add(new Pair<Integer>(lastIndex, pixels.length - 1));
-            } else {
-                fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1));
-            }
-
-            if (patches.size() == 0) {
-                patches.add(new Pair<Integer>(1, pixels.length - 1));
-                startWithPatch[0] = true;
-                fixed.clear();
-            }
-
-            return new Pair<List<Pair<Integer>>>(fixed, patches);
-        }
-
-        void setLockVisible(boolean visible) {
-            showLock = visible;
-            repaint();
-        }
-    }
-
-    static class Pair<E> {
-        E first;
-        E second;
-
-        Pair(E first, E second) {
-            this.first = first;
-            this.second = second;
-        }
-
-        @Override
-        public String toString() {
-            return "Pair[" + first + ", " + second + "]";
-        }
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/ImageTransferHandler.java b/tools/draw9patch/src/com/android/draw9patch/ui/ImageTransferHandler.java
deleted file mode 100644
index f14cd77..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/ImageTransferHandler.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.android.draw9patch.ui;
-
-import javax.swing.TransferHandler;
-import javax.swing.JComponent;
-import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.net.MalformedURLException;
-
-class ImageTransferHandler extends TransferHandler {
-    private final MainFrame mainFrame;
-
-    ImageTransferHandler(MainFrame mainFrame) {
-        this.mainFrame = mainFrame;
-    }
-
-    @Override
-    public boolean importData(JComponent component, Transferable transferable) {
-        try {
-            for (DataFlavor flavor : transferable.getTransferDataFlavors()) {
-                if (flavor.isFlavorJavaFileListType()) {
-                    Object data = transferable.getTransferData(DataFlavor.javaFileListFlavor);
-                    //noinspection unchecked
-                    final File file = ((List<File>) data).get(0);
-                    mainFrame.open(file).execute();
-                    return true;
-                } else if (flavor.isFlavorTextType()) {
-                    if (flavor.getRepresentationClass() == String.class) {
-                        String mime = flavor.getMimeType();
-                        DataFlavor flave = new DataFlavor(mime);
-                        Object data = transferable.getTransferData(flave);
-                        final String path = convertPath(data.toString());
-                        mainFrame.open(new File(path)).execute();
-                        return true;
-                    }
-                }
-            }
-        } catch (UnsupportedFlavorException e) {
-            // Ignore
-        } catch (MalformedURLException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        return false;
-    }
-
-    private static String convertPath(String path) {
-        if (path.startsWith("file://")) path = path.substring("file://".length());
-        if (path.indexOf('\n') != -1) path = path.substring(0, path.indexOf('\n'));
-        if (path.indexOf('\r') != -1) path = path.substring(0, path.indexOf('\r'));
-        return path;
-    }
-
-    @Override
-    public boolean canImport(JComponent component, DataFlavor[] dataFlavors) {
-        for (DataFlavor flavor : dataFlavors) {
-            if (flavor.isFlavorJavaFileListType() || flavor.isFlavorTextType()) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/MainFrame.java b/tools/draw9patch/src/com/android/draw9patch/ui/MainFrame.java
deleted file mode 100644
index d5b6409..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/MainFrame.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.android.draw9patch.ui;
-
-import com.android.draw9patch.ui.action.ExitAction;
-import com.android.draw9patch.ui.action.OpenAction;
-import com.android.draw9patch.ui.action.SaveAction;
-import com.android.draw9patch.graphics.GraphicsUtilities;
-
-import javax.swing.JFrame;
-import javax.swing.JMenuBar;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.ActionMap;
-import javax.swing.JFileChooser;
-import javax.imageio.ImageIO;
-import java.awt.HeadlessException;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.util.concurrent.ExecutionException;
-
-import org.jdesktop.swingworker.SwingWorker;
-
-public class MainFrame extends JFrame {
-    private ActionMap actionsMap;
-    private JMenuItem saveMenuItem;
-    private ImageEditorPanel imageEditor;
-
-    public MainFrame(String path) throws HeadlessException {
-        super("Draw 9-patch");
-
-        buildActions();
-        buildMenuBar();
-        buildContent();
-
-        if (path == null) {
-            showOpenFilePanel();
-        } else {
-            try {
-                File file = new File(path);
-                BufferedImage img = GraphicsUtilities.loadCompatibleImage(file.toURI().toURL());
-                showImageEditor(img, file.getAbsolutePath());
-            } catch (Exception ex) {
-                showOpenFilePanel();
-            }
-        }
-
-        // pack();
-        setSize(1024, 600);
-    }
-
-    private void buildActions() {
-        actionsMap = new ActionMap();
-        actionsMap.put(OpenAction.ACTION_NAME, new OpenAction(this));
-        actionsMap.put(SaveAction.ACTION_NAME, new SaveAction(this));
-        actionsMap.put(ExitAction.ACTION_NAME, new ExitAction(this));
-    }
-
-    private void buildMenuBar() {
-        JMenu fileMenu = new JMenu("File");
-        JMenuItem openMenuItem = new JMenuItem();
-        saveMenuItem = new JMenuItem();
-        JMenuItem exitMenuItem = new JMenuItem();
-
-        openMenuItem.setAction(actionsMap.get(OpenAction.ACTION_NAME));
-        fileMenu.add(openMenuItem);
-
-        saveMenuItem.setAction(actionsMap.get(SaveAction.ACTION_NAME));
-        saveMenuItem.setEnabled(false);
-        fileMenu.add(saveMenuItem);
-
-        exitMenuItem.setAction(actionsMap.get(ExitAction.ACTION_NAME));
-        fileMenu.add(exitMenuItem);
-
-        JMenuBar menuBar = new JMenuBar();
-        menuBar.add(fileMenu);
-        setJMenuBar(menuBar);
-    }
-
-    private void buildContent() {
-        setContentPane(new GradientPanel());
-    }
-
-    private void showOpenFilePanel() {
-        add(new OpenFilePanel(this));
-    }
-
-    public SwingWorker<?, ?> open(File file) {
-        if (file == null) {
-            JFileChooser chooser = new JFileChooser();
-            chooser.setFileFilter(new PngFileFilter());
-            int choice = chooser.showOpenDialog(this);
-            if (choice == JFileChooser.APPROVE_OPTION) {
-                return new OpenTask(chooser.getSelectedFile());
-            } else {
-                return null;
-            }
-        } else {
-            return new OpenTask(file);
-        }
-    }
-
-    void showImageEditor(BufferedImage image, String name) {
-        getContentPane().removeAll();
-        imageEditor = new ImageEditorPanel(this, image, name);
-        add(imageEditor);
-        saveMenuItem.setEnabled(true);
-        validate();
-        repaint();
-    }
-
-    public SwingWorker<?, ?> save() {
-        if (imageEditor == null) {
-            return null;
-        }
-
-        File file = imageEditor.chooseSaveFile();
-        return file != null ? new SaveTask(file) : null;
-    }
-
-    private class SaveTask extends SwingWorker<Boolean, Void> {
-        private final File file;
-
-        SaveTask(File file) {
-            this.file = file;
-        }
-
-        protected Boolean doInBackground() throws Exception {
-            try {
-                ImageIO.write(imageEditor.getImage(), "PNG", file);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            return true;
-        }
-    }
-
-    private class OpenTask extends SwingWorker<BufferedImage, Void> {
-        private final File file;
-
-        OpenTask(File file) {
-            this.file = file;
-        }
-
-        protected BufferedImage doInBackground() throws Exception {
-            return GraphicsUtilities.loadCompatibleImage(file.toURI().toURL());
-        }
-
-        @Override
-        protected void done() {
-            try {
-                showImageEditor(get(), file.getAbsolutePath());
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            } catch (ExecutionException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/OpenFilePanel.java b/tools/draw9patch/src/com/android/draw9patch/ui/OpenFilePanel.java
deleted file mode 100644
index a444332..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/OpenFilePanel.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.android.draw9patch.ui;
-
-import com.android.draw9patch.graphics.GraphicsUtilities;
-
-import javax.swing.JComponent;
-import java.awt.image.BufferedImage;
-import java.awt.Graphics;
-import java.io.IOException;
-import java.net.URL;/*
- * 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.
- */
-
-class OpenFilePanel extends JComponent {
-    private BufferedImage dropHere;
-
-    OpenFilePanel(MainFrame mainFrame) {
-        setOpaque(false);
-        loadSupportImage();
-        setTransferHandler(new ImageTransferHandler(mainFrame));
-    }
-
-    private void loadSupportImage() {
-        try {
-            URL resource = getClass().getResource("/images/drop.png");
-            dropHere = GraphicsUtilities.loadCompatibleImage(resource);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    protected void paintComponent(Graphics g) {
-        int x = (getWidth() - dropHere.getWidth()) / 2;
-        int y = (getHeight() - dropHere.getHeight()) / 2;
-
-        g.drawImage(dropHere, x, y, null);
-    }
-
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/PngFileFilter.java b/tools/draw9patch/src/com/android/draw9patch/ui/PngFileFilter.java
deleted file mode 100644
index 8f8885a..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/PngFileFilter.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.android.draw9patch.ui;
-
-import javax.swing.filechooser.FileFilter;
-import java.io.File;
-
-class PngFileFilter extends FileFilter {
-    @Override
-    public boolean accept(File f) {
-        return f.isDirectory() || f.getName().toLowerCase().endsWith(".png");
-    }
-
-    @Override
-    public String getDescription() {
-        return "PNG Image (*.png)";
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/BackgroundAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/BackgroundAction.java
deleted file mode 100644
index 85d9d4f..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/action/BackgroundAction.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.android.draw9patch.ui.action;
-
-import org.jdesktop.swingworker.SwingWorker;
-
-import javax.swing.AbstractAction;
-
-public abstract class BackgroundAction extends AbstractAction {
-    protected void executeBackgroundTask(SwingWorker<?, ?> worker) {
-        if (worker != null) {
-            worker.execute();
-        }
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/ExitAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/ExitAction.java
deleted file mode 100644
index b6f047d..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/action/ExitAction.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.android.draw9patch.ui.action;
-
-import javax.swing.AbstractAction;
-import javax.swing.KeyStroke;
-import javax.swing.JFrame;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class ExitAction extends AbstractAction {
-    public static final String ACTION_NAME = "exit";
-    private JFrame frame;
-
-    public ExitAction(JFrame frame) {
-        putValue(NAME, "Quit");
-        putValue(SHORT_DESCRIPTION, "Quit");
-        putValue(LONG_DESCRIPTION, "Quit");
-        putValue(MNEMONIC_KEY, KeyEvent.VK_Q);
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-        this.frame = frame;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        frame.dispose();
-        System.exit(0);
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/OpenAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/OpenAction.java
deleted file mode 100644
index 45ee5be..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/action/OpenAction.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.android.draw9patch.ui.action;
-
-import com.android.draw9patch.ui.MainFrame;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class OpenAction extends BackgroundAction {
-    public static final String ACTION_NAME = "open";
-    private MainFrame frame;
-
-    public OpenAction(MainFrame frame) {
-        this.frame = frame;
-        putValue(NAME, "Open 9-patch...");
-        putValue(SHORT_DESCRIPTION, "Open...");
-        putValue(LONG_DESCRIPTION, "Open 9-patch...");
-        putValue(MNEMONIC_KEY, KeyEvent.VK_O);
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(frame.open(null));
-    }
-}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/SaveAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/SaveAction.java
deleted file mode 100644
index 5c1dc52..0000000
--- a/tools/draw9patch/src/com/android/draw9patch/ui/action/SaveAction.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.android.draw9patch.ui.action;
-
-import com.android.draw9patch.ui.MainFrame;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class SaveAction extends BackgroundAction {
-    public static final String ACTION_NAME = "save";
-    private MainFrame frame;
-
-    public SaveAction(MainFrame frame) {
-        this.frame = frame;
-        putValue(NAME, "Save 9-patch...");
-        putValue(SHORT_DESCRIPTION, "Save...");
-        putValue(LONG_DESCRIPTION, "Save 9-patch...");
-        putValue(MNEMONIC_KEY, KeyEvent.VK_S);
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(frame.save());
-    }
-}
diff --git a/tools/draw9patch/src/resources/images/checker.png b/tools/draw9patch/src/resources/images/checker.png
deleted file mode 100644
index 78908f4..0000000
--- a/tools/draw9patch/src/resources/images/checker.png
+++ /dev/null
Binary files differ
diff --git a/tools/draw9patch/src/resources/images/drop.png b/tools/draw9patch/src/resources/images/drop.png
deleted file mode 100644
index 7a7436a..0000000
--- a/tools/draw9patch/src/resources/images/drop.png
+++ /dev/null
Binary files differ
diff --git a/tools/dumpeventlog/.classpath b/tools/dumpeventlog/.classpath
deleted file mode 100644
index b0326c8..0000000
--- a/tools/dumpeventlog/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/dumpeventlog/.project b/tools/dumpeventlog/.project
deleted file mode 100644
index c416f4f..0000000
--- a/tools/dumpeventlog/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>dumpeventlog</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/dumpeventlog/Android.mk b/tools/dumpeventlog/Android.mk
deleted file mode 100644
index 7bb870d..0000000
--- a/tools/dumpeventlog/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-DUMPEVENTLOG_LOCAL_DIR := $(call my-dir)
-include $(DUMPEVENTLOG_LOCAL_DIR)/etc/Android.mk
-include $(DUMPEVENTLOG_LOCAL_DIR)/src/Android.mk
diff --git a/tools/dumpeventlog/etc/Android.mk b/tools/dumpeventlog/etc/Android.mk
deleted file mode 100644
index 8094734..0000000
--- a/tools/dumpeventlog/etc/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := dumpeventlog
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/dumpeventlog/etc/dumpeventlog b/tools/dumpeventlog/etc/dumpeventlog
deleted file mode 100755
index 56f8c22..0000000
--- a/tools/dumpeventlog/etc/dumpeventlog
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/sh
-# Copyright 2005-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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=dumpeventlog.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
-    # add this in for debugging
-    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
-    shift 1
-else
-    java_debug=
-fi
-
-# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
-if [ `uname` = "Darwin" ]; then
-    os_opts="-XstartOnFirstThread"
-else
-    os_opts=
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
diff --git a/tools/dumpeventlog/etc/manifest.txt b/tools/dumpeventlog/etc/manifest.txt
deleted file mode 100644
index 0eea915..0000000
--- a/tools/dumpeventlog/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.dumpeventlog.DumpEventLog
diff --git a/tools/dumpeventlog/src/Android.mk b/tools/dumpeventlog/src/Android.mk
deleted file mode 100644
index bf99375..0000000
--- a/tools/dumpeventlog/src/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	ddmlib
-LOCAL_MODULE := dumpeventlog
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java b/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
deleted file mode 100644
index 695573c..0000000
--- a/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.android.dumpeventlog;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.ILogOutput;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.log.LogReceiver;
-import com.android.ddmlib.log.LogReceiver.ILogListener;
-import com.android.ddmlib.log.LogReceiver.LogEntry;
-
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * Connects to a device using ddmlib and dumps its event log as long as the device is connected.
- */
-public class DumpEventLog {
-
-    /**
-     * Custom {@link ILogListener} to receive and save the event log raw output.
-     */
-    private static class LogWriter implements ILogListener {
-        private FileOutputStream mOutputStream;
-        private LogReceiver mReceiver;
-
-        public LogWriter(String filePath) throws IOException {
-            mOutputStream = new FileOutputStream(filePath);
-        }
-
-        public void newData(byte[] data, int offset, int length) {
-            try {
-                mOutputStream.write(data, offset, length);
-            } catch (IOException e) {
-                if (mReceiver != null) {
-                    mReceiver.cancel();
-                }
-                System.out.println(e);
-            }
-        }
-
-        public void newEntry(LogEntry entry) {
-            // pass
-        }
-
-        public void setReceiver(LogReceiver receiver) {
-            mReceiver = receiver;
-        }
-
-        public void done() throws IOException {
-            mOutputStream.close();
-        }
-    }
-
-    public static void main(String[] args) {
-        if (args.length != 2) {
-            System.out.println("Usage: dumpeventlog <device s/n> <filepath>");
-            return;
-        }
-
-        // redirect the log output to /dev/null
-        Log.setLogOutput(new ILogOutput() {
-            public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
-                // pass
-            }
-
-            public void printLog(LogLevel logLevel, String tag, String message) {
-                // pass
-            }
-        });
-
-        // init the lib
-        AndroidDebugBridge.init(false /* debugger support */);
-
-        try {
-            AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
-
-            // we can't just ask for the device list right away, as the internal thread getting
-            // them from ADB may not be done getting the first list.
-            // Since we don't really want getDevices() to be blocking, we wait here manually.
-            int count = 0;
-            while (bridge.hasInitialDeviceList() == false) {
-                try {
-                    Thread.sleep(100);
-                    count++;
-                } catch (InterruptedException e) {
-                    // pass
-                }
-
-                // let's not wait > 10 sec.
-                if (count > 100) {
-                    System.err.println("Timeout getting device list!");
-                    return;
-                }
-            }
-
-            // now get the devices
-            IDevice[] devices = bridge.getDevices();
-
-            for (IDevice device : devices) {
-                if (device.getSerialNumber().equals(args[0])) {
-                    try {
-                        grabLogFrom(device, args[1]);
-                    } catch (FileNotFoundException e) {
-                        e.printStackTrace();
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                    return;
-                }
-            }
-
-            System.err.println("Could not find " + args[0]);
-        } finally {
-            AndroidDebugBridge.terminate();
-        }
-    }
-
-    private static void grabLogFrom(IDevice device, String filePath) throws IOException {
-        LogWriter writer = new LogWriter(filePath);
-        LogReceiver receiver = new LogReceiver(writer);
-        writer.setReceiver(receiver);
-
-        device.runEventLogService(receiver);
-
-        writer.done();
-    }
-}
diff --git a/tools/eclipse/README_WINDOWS.txt b/tools/eclipse/README_WINDOWS.txt
deleted file mode 100644
index 1480f5d..0000000
--- a/tools/eclipse/README_WINDOWS.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-[RM 20080623]
-
-1- To build the Eclipse plugin:
-Under Linux:
-$ cd your-device-directory
-$ tools/eclipse/scripts/build_server.sh destination-directory
-
-This will create an "android-eclipse.zip" in the selected destination directory.
-Then in Eclipse, you can use Help > Software Updates > Find and Install > Search for new Features > Next > New Archived Site > select the new android-eclipse.zip. Then with the new archive checked, click Finish/Next.
-
-
-2- To build a Windows SDK, you need two steps:
-a- First you need to create a Linux SDK:
-
-Under Linux:
-$ cd your-device-directory
-$ make sdk
-Note: if you get an error when building the javadoc, make sure you use a Java SDK 1.5
-Note: if you get an error when building layoutlib, make sure you use a Java SDK 1.5.0-b13.
-
-b- Once you have a Linux SDK, you can create a Windows SDK:
-
-You need a Windows machine with XP or Vista and Cygwin.
-- Installer at http://sources.redhat.com/cygwin/
-- Set Default Text File Type to DOS/text, not Unix/binary.
-- Select packages autoconf, gcc, g++, bison, python, zip, unzip, mingw-zlib
-- Suggested extra packages: emacs, wget, openssh, rsync
-
-Then under Cygwin:
-$ cd your-device-directory
-$ tools/buildbot/_make_windows_sdk.sh path-to-the-linux-sdk.zip destination-directory
-
diff --git a/tools/eclipse/buildConfig/allElements.xml b/tools/eclipse/buildConfig/allElements.xml
deleted file mode 100644
index 2c8229c..0000000
--- a/tools/eclipse/buildConfig/allElements.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<!-- ========================================================================= -->
-<!-- Feature build ant targets                                                 -->
-<!-- Template obtained from org.eclipse.pde.build/templates/headless-build     -->
-<!-- ========================================================================= -->
-<project name="allElements Delegator">
-    
-     <!-- ===================================================================== -->
-     <!-- Run a given ${target} on all elements being built                     -->
-     <!-- Replace element.id with the id of the top level element being built.    -->
-     <!-- If element.id does not exist in ${buildDirectory}/features/element.id   -->
-     <!-- or ${baseLocation}/features/element.id, then you must provide the       -->
-     <!-- location by setting the property "pluginPath"                           -->
-     <!-- Add on <ant> task for each top level element being built.             -->
-     <!-- ===================================================================== -->
-     <target name="allElementsDelegator">
-         
-         <ant antfile="${genericTargets}" target="${target}">
-             <property name="type" value="feature" />
-             <property name="id" value="com.android.ide.eclipse.ddms" />
-         </ant>
-
-         <ant antfile="${genericTargets}" target="${target}">
-             <property name="type" value="feature" />
-             <property name="id" value="com.android.ide.eclipse.adt" />
-         </ant>
-         
-        <antcall target="buildInternalFeatures"/>
-         
-     </target>
-    
-     <!-- ===================================================================== -->
-     <!-- Conditional target for building the internal features                 -->
-     <!-- Builds if property internalSite is set                                -->
-     <!-- ===================================================================== -->
-     <target name="buildInternalFeatures" if="internalSite">
-        <ant antfile="${genericTargets}" target="${target}">
-            <property name="type" value="feature" />
-            <property name="id" value="com.android.ide.eclipse.tests" />
-        </ant>
-     </target>    
-         
-     <!-- ===================================================================== -->
-     <!-- Targets to assemble the built elements for particular configurations  -->
-     <!-- These generally call the generated assemble scripts (named in         -->
-     <!-- ${assembleScriptName}) but may also add pre and post processing       -->
-     <!-- Add one target for each root element and each configuration           -->
-     <!-- Replace element.id with the id of the top level element being built   -->
-     <!-- ===================================================================== -->
-     <target name="assemble.com.android.ide.eclipse.adt">
-         <ant antfile="${assembleScriptName}" dir="${buildDirectory}"/>
-     </target>
-
-     <target name="assemble.com.android.ide.eclipse.ddms">
-         <ant antfile="${assembleScriptName}" dir="${buildDirectory}"/>
-     </target>
-    
-    <target name="assemble.com.android.ide.eclipse.tests">
-        <ant antfile="${assembleScriptName}" dir="${buildDirectory}"/>
-    </target>
-</project>
diff --git a/tools/eclipse/buildConfig/build.properties b/tools/eclipse/buildConfig/build.properties
deleted file mode 100644
index cd477d8..0000000
--- a/tools/eclipse/buildConfig/build.properties
+++ /dev/null
@@ -1,238 +0,0 @@
-###############################################################################
-# Copyright (c) 2003, 2006 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-
-
-# This file was generated per the instructions located in Eclipse Help>Plug-in Development
-# Environment >  Guide > Tasks > Building features and customized for building the
-# Android Eclipse plugins.
-
-#####################
-# Parameters describing how and where to execute the build.
-# Typical users need only update the following properties:
-#    baseLocation - where things you are building against are installed
-#    bootclasspath - The base jars to compile against (typicaly rt.jar)
-#    configs - the list of {os, ws, arch} configurations to build.  
-#
-# Of course any of the settings here can be overridden by spec'ing 
-# them on the command line (e.g., -DbaseLocation=d:/eclipse
-
-############# PRODUCT/PACKAGING CONTROL #############
-product=/plugin or feature id/path/to/.product
-runPackager=true
-
-#Set the name of the archive that will result from the product build.
-#archiveNamePrefix=
-
-# The prefix that will be used in the generated archive.
-# override default of "eclipse" to aid for external site generation 
-archivePrefix=android-eclipse
-
-# The location underwhich all of the build output will be collected.
-collectingFolder=${archivePrefix}
-
-# The list of {os, ws, arch} configurations to build.  This 
-# value is a '&' separated list of ',' separate triples.  For example, 
-#     configs=win32,win32,x86 & linux,motif,x86
-# By default the value is *,*,*
-configs = *, *, *
-#configs=win32, win32, x86 & \
-#	linux, gtk, ppc &\
-# linux, gtk, x86 & \
-#	linux, gtk, x86_64 & \
-#	linux, motif, x86 & \
-#	solaris, motif, sparc & \
-#	solaris, gtk, sparc & \
-#	aix, motif, ppc & \
-#	hpux, motif, PA_RISC & \
-#	macosx, carbon, ppc
-
-# By default PDE creates one archive (result) per entry listed in the configs property.
-# Setting this value to try will cause PDE to only create one output containing all 
-# artifacts for all the platforms listed in the configs property.
-#groupConfigurations=true
-
-#The format of the archive. By default a zip is created using antZip.
-#The list can only contain the configuration for which the desired format is different than zip.
-#archivesFormat=win32, win32, x86 - antZip& \
-#	linux, gtk, ppc - antZip &\
-#    linux, gtk, x86 - antZip& \
-#	linux, gtk, x86_64 - antZip& \
-# linux, motif, x86 - antZip& \
-#	solaris, motif, sparc - antZip& \
-#	solaris, gtk, sparc - antZip& \
-#	aix, motif, ppc - antZip& \
-#	hpux, motif, PA_RISC - antZip& \
-#	macosx, carbon, ppc - antZip
-	
-#Set to true if you want the output to be ready for an update jar (no site.xml generated)
-outputUpdateJars = true
-
-#Set to true for Jnlp generation
-#codebase should be a URL that will be used as the root of all relative URLs in the output.
-#generateJnlp=false
-#jnlp.codebase=<codebase url>
-#jnlp.j2se=<j2se version>
-#jnlp.locale=<a locale>
-#jnlp.generateOfflineAllowed=true or false generate <offlineAllowed/> attribute in the generated features
-#jnlp.configs=${configs}			#uncomment to filter the content of the generated jnlp files based on the configuration being built
-
-#Set to true if you want to sign jars
-#signJars=false
-#sign.alias=<alias>
-#sign.keystore=<keystore location>
-#sign.storepass=<keystore password>
-
-#Arguments to send to the zip executable
-zipargs=
-
-#Arguments to send to the tar executable
-tarargs=
-
-#Control the creation of a file containing the version included in each configuration - on by default 
-#generateVersionsLists=false
-
-############## BUILD NAMING CONTROL ################
-# The directory into which the build elements are fetched and where
-# the build takes place.
-buildDirectory=.
-
-# Type of build.  Used in naming the build output.  Typically this value is
-# one of I, N, M, S, ...
-buildType=build
-
-# ID of the build.  Used in naming the build output.
-# forceContextQualifer = build label
-buildId=${forceContextQualifier}
-
-# Label for the build.  Used in naming the build output
-buildLabel=${buildId}
-
-# Timestamp for the build.  Used in naming the build output
-timestamp=007
-
-#The value to be used for the qualifier of a plugin or feature when you want to override the value computed by pde.
-#The value will only be applied to plugin or features indicating build.properties, qualifier = context 
-#forceContextQualifier=<the value for the qualifier>
-
-#Enable / disable the generation of a suffix for the features that use .qualifier. 
-#The generated suffix is computed according to the content of the feature   
-#generateFeatureVersionSuffix=true
-
-############# BASE CONTROL #############
-# Settings for the base Eclipse components and Java class libraries 
-# against which you are building.
-# Base location for anything the build needs to compile against.  For example,
-# in most RCP app or a plug-in,  the baseLocation should be the location of a previously
-# installed Eclipse against which the application or plug-in code will be compiled and the RCP delta pack.
-
-baseLocation=${ECLIPSE_HOME}
-#Os/Ws/Arch/nl of the eclipse specified by baseLocation
-baseos=linux
-basews=gtk
-basearch=x86
-
-#this property indicates whether you want the set of plug-ins and features to be considered during the build to be limited to the ones reachable from the features / plugins being built
-filteredDependencyCheck=false
-
-#this property indicates whether the resolution should be done in development mode (i.e. ignore multiple bundles with singletons)
-resolution.devMode=false
-
-#pluginPath is a list of locations in which to find plugins and features.  This list is separated by the platform file separator (; or :)
-#a location is one of:  
-#- the location of the jar or folder that is the plugin or feature : /path/to/foo.jar or /path/to/foo
-#- a directory that contains a /plugins or /features subdirectory
-#- the location of a feature.xml, or for 2.1 style plugins, the plugin.xml or fragment.xml
-#pluginPath=
-
-skipBase=true
-eclipseURL=<url for eclipse download site>
-eclipseBuildId=<Id of Eclipse build to get>
-eclipseBaseURL=${eclipseURL}/eclipse-platform-${eclipseBuildId}-win32.zip
-
-
-############# MAP FILE CONTROL ################
-# This section defines CVS tags to use when fetching the map files from the repository.
-# If you want to fetch the map file from repository / location, change the getMapFiles target in the customTargets.xml
-
-skipMaps=true
-mapsRepo=:pserver:anonymous@example.com/path/to/repo
-mapsRoot=path/to/maps
-mapsCheckoutTag=HEAD
-
-#tagMaps=true
-mapsTagTag=v${buildId}
-
-
-############ REPOSITORY CONTROL ###############
-# This section defines properties parameterizing the repositories where plugins, fragments
-# bundles and features are being obtained from. 
-
-# The tags to use when fetching elements to build.
-# By default thebuilder will use whatever is in the maps.  
-# This value takes the form of a comma separated list of repository identifier (like used in the map files) and the 
-# overriding value
-# For example fetchTag=CVS=HEAD, SVN=v20050101
-# fetchTag=HEAD
-skipFetch=true
-
-
-############# JAVA COMPILER OPTIONS ##############
-# The location of the Java jars to compile against.  Typically the rt.jar for your JDK/JRE
-#bootclasspath=${java.home}/lib/rt.jar
-
-# specific JRE locations to compile against. These values are used to compile bundles specifying a 
-# Bundle-RequiredExecutionEnvironment. Uncomment and set values for environments that you support
-#CDC-1.0/Foundation-1.0= /path/to/rt.jar
-#CDC-1.1/Foundation-1.1=
-#OSGi/Minimum-1.0=
-#OSGi/Minimum-1.1=
-#JRE-1.1=
-#J2SE-1.2=
-#J2SE-1.3=
-#J2SE-1.4=
-#J2SE-1.5=
-#JavaSE-1.6=
-#PersonalJava-1.1=
-#PersonalJava-1.2=
-#CDC-1.0/PersonalBasis-1.0=
-#CDC-1.0/PersonalJava-1.0=
-#CDC-1.1/PersonalBasis-1.1=
-#CDC-1.1/PersonalJava-1.1=
-
-# Specify the output format of the compiler log when eclipse jdt is used
-logExtension=.log
-
-# Whether or not to include debug info in the output jars
-javacDebugInfo=false 
-
-# Whether or not to fail the build if there are compiler errors
-javacFailOnError=true
-
-# Enable or disable verbose mode of the compiler
-javacVerbose=true
-
-# Extra arguments for the compiler. These are specific to the java compiler being used.
-#compilerArg=
-
-# Default value for the version of the source code. This value is used when compiling plug-ins that do not set the Bundle-RequiredExecutionEnvironment or set javacSource in build.properties
-javacSource=1.5
-
-# Default value for the version of the byte code targeted. This value is used when compiling plug-ins that do not set the Bundle-RequiredExecutionEnvironment or set javacTarget in build.properties.
-javacTarget=1.5
-
-################### CUSTOM PROPERTIES #######################################
-# repository location for update site
-# comment out - this is passed in from command line 
-#updateSiteSource=${buildDirectory}/sites/external
-# where to place update site build
-updateSiteRoot=${user.home}/www/no_crawl/
-updateSiteFolder=${archivePrefix}
-updateSiteDestination=${updateSiteRoot}/${updateSiteFolder}
diff --git a/tools/eclipse/buildConfig/buildUpdateSite.xml b/tools/eclipse/buildConfig/buildUpdateSite.xml
deleted file mode 100644
index 1ab7c99..0000000
--- a/tools/eclipse/buildConfig/buildUpdateSite.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<project name="update site">
-    <!-- ========================================================================= -->
-    <!-- Extracts feature zip for update site                                      -->
-    <!-- expected properties:                                                      -->
-    <!--    id - feature id to extract                                             -->
-    <!--    buildDirectory - base directgory where build takes place               -->
-    <!--    buildLabel - build id label                                            -->
-    <!--    updateSiteRoot - where to extract feature zip                          -->
-    <!-- ========================================================================= -->
-    <target name="extractFeature">
-        <unzip src="${buildDirectory}/${buildLabel}/${id}-${buildLabel}.zip" dest="${updateSiteRoot}"/>        
-    </target>
-</project>
diff --git a/tools/eclipse/buildConfig/customTargets.xml b/tools/eclipse/buildConfig/customTargets.xml
deleted file mode 100644
index 5a46bfc..0000000
--- a/tools/eclipse/buildConfig/customTargets.xml
+++ /dev/null
@@ -1,195 +0,0 @@
-<!-- ========================================================================= -->
-<!-- Eclipse template file for PDE builds -->
-<!-- template originally obtained from org.eclipse.pde.build/templates/headless-build -->
-<!-- ========================================================================= -->
-<project name="Build specific targets and properties" default="noDefault">
-
-    <!-- ===================================================================== -->
-    <!-- Run a given ${target} on all elements being built -->
-    <!-- Add on <ant> task for each top level element being built. -->
-    <!-- ===================================================================== -->
-    <property name="allElementsFile" value="${builder}/allElements.xml"/>
-    <import file="${allElementsFile}" />
-    <target name="allElements">
-        <antcall target="allElementsDelegator" />
-    </target>
-    
-    <!-- ===================================================================== -->
-    <!-- ===================================================================== -->
-    <target name="getBaseComponents" depends="checkLocalBase" unless="skipBase">
-        <get src="${eclipseBaseURL}" dest="${buildDirectory}/../temp-base.zip" />
-        <unzip dest="${base}" overwrite="true" src="${buildDirectory}/../temp-base.zip" />
-    </target>
-
-    <target name="checkLocalBase">
-        <available file="${base}" property="skipBase" />
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Check out map files from correct repository -->
-    <!-- Replace values for mapsCheckoutTag as desired. -->
-    <!-- ===================================================================== -->
-    <target name="getMapFiles" depends="checkLocalMaps" unless="skipMaps">
-        <property name="mapsCheckoutTag" value="HEAD" />
-        <cvs cvsRoot="${mapsRepo}" package="${mapsRoot}" dest="${buildDirectory}/maps" tag="${mapsCheckoutTag}" />
-    </target>
-
-    <target name="checkLocalMaps">
-        <available property="skipMaps" file="${buildDirectory}/maps" />
-    </target>
-
-    <target name="tagMapFiles" if="tagMaps">
-        <cvs dest="${buildDirectory}/maps/${mapsRoot}" command="tag ${mapsTagTag}" />
-    </target>
-
-    <!-- ===================================================================== -->
-
-    <target name="clean" unless="noclean">
-        <antcall target="allElements">
-            <param name="target" value="cleanElement" />
-        </antcall>
-    </target>
-
-    <target name="gatherLogs">
-        <mkdir dir="${buildDirectory}/${buildLabel}/compilelogs" />
-        <antcall target="allElements">
-            <param name="target" value="gatherLogs" />
-        </antcall>
-        <unzip dest="${buildDirectory}/${buildLabel}/compilelogs" overwrite="true">
-            <fileset dir="${buildDirectory}/features">
-                <include name="**/*.log.zip" />
-            </fileset>
-        </unzip>
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do before setup -->
-    <!-- ===================================================================== -->
-    <target name="preSetup">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do after setup but before starting the build proper -->
-    <!-- ===================================================================== -->
-    <target name="postSetup">
-        <antcall target="getBaseComponents" />
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do before fetching the build elements -->
-    <!-- ===================================================================== -->
-    <target name="preFetch">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do after fetching the build elements -->
-    <!-- ===================================================================== -->
-    <target name="postFetch">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do before generating the build scripts. -->
-    <!-- ===================================================================== -->
-    <target name="preGenerate">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do after generating the build scripts. -->
-    <!-- ===================================================================== -->
-    <target name="postGenerate">
-        <antcall target="clean" />
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do before running the build.xmls for the elements being built. -->
-    <!-- ===================================================================== -->
-    <target name="preProcess">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do after running the build.xmls for the elements being built. -->
-    <!-- ===================================================================== -->
-    <target name="postProcess">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do before running assemble. -->
-    <!-- ===================================================================== -->
-    <target name="preAssemble">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do after  running assemble. -->
-    <!-- ===================================================================== -->
-    <target name="postAssemble">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do before running package. -->
-    <!-- ===================================================================== -->
-    <target name="prePackage">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do after  running package. -->
-    <!-- ===================================================================== -->
-    <target name="postPackage">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do after the build is done. -->
-    <!-- ===================================================================== -->
-    <target name="postBuild">
-        <antcall target="gatherLogs" />
-        <!-- Added this custom target ! -->
-        <antcall target="generateUpdateSite" />
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do to test the build results -->
-    <!-- ===================================================================== -->
-    <target name="test">
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Steps to do to publish the build results -->
-    <!-- ===================================================================== -->
-    <target name="publish">
-        
-    </target>
-
-    <!-- ===================================================================== -->
-    <!-- Default target                                                        -->
-    <!-- ===================================================================== -->
-    <target name="noDefault">
-        <echo message="You must specify a target when invoking this file" />
-    </target>
-    
-    <!-- ===================================================================== -->
-    <!-- Custom target:                                                        -->
-    <!-- Steps to do to generate the update site                               -->
-    <!-- ===================================================================== -->
-    <target name="generateUpdateSite">
-        <echo message="Copying update site source ${updateSiteSource} to destination"/>
-    	
-        <copy file="${updateSiteSource}/site.xml" overwrite="true" todir="${updateSiteDestination}"/>
-        <copy file="${updateSiteSource}/index.html" overwrite="true" todir="${updateSiteDestination}"/>
-        <copy file="${updateSiteSource}/web/site.css" overwrite="true" todir="${updateSiteDestination}/web"/>
-        <copy file="${updateSiteSource}/web/site.xsl" overwrite="true" todir="${updateSiteDestination}/web"/>
-        
-        <!-- replace qualifier version references with build label -->
-        <replace file="${updateSiteDestination}/site.xml" token="qualifier" value="${buildId}"/>
-        
-        <!-- now extract each features zip to update site -->
-        <antcall target="allElements">
-            <param name="genericTargets" value="${builder}/buildUpdateSite.xml"/>
-            <param name="target" value="extractFeature" />
-        </antcall>
-        
-        <chmod perm="755" type="both">
-            <fileset dir="${updateSiteDestination}">
-            </fileset>
-        </chmod>    
-    </target>
-
-</project>
diff --git a/tools/eclipse/changes.txt b/tools/eclipse/changes.txt
deleted file mode 100644
index 0c653c3..0000000
--- a/tools/eclipse/changes.txt
+++ /dev/null
@@ -1,232 +0,0 @@
-0.9.4:
-- New "Create project from sample" choice in the New Project Wizard.
-
-0.9.3:
-- New wizard to create Android JUnit Test Projects.
-- New AVD wizard.
-- SDK Updater
-- zipalign support
-
-0.9.1:
-- Added an AVD creation wizard to ADT. It is automatically displayed during a launch if no compatible AVDs are found.
-- Fixed issue with libs/ folder where files with no extension would prevent the build from finishing.
-- Improved error handling during the final steps of the build to mark the project if an unexpected error prevent the build from finishing.
-- Fixed issue when launching ADT on a clean install would trigger org.eclipse.swt.SWTError: Not implemented [multiple displays].
-
-
-0.9.0:
-- Projects now store generated Java files (R.java/Manifest.java and output from aidl) in a 'gen' source folder.
-- Support for the new Android SDK with support for multiple versions of the Android platform and for vendor supplied add-ons.
-    * New Project Wizard lets you choose which platform/add-on to target.
-    * Project properties (right click project in Package Explorer, then "Properties"), lets you edit project target.
-    * New Launch configuration option to choose debug deployment target.
-- Ability to export multiple apk from one project, using resource filters. See the 'android' property for Android projects.
-- Support for running JUnit tests on a device/emulator from a new "Android JUnit tests" launch configuration.
-
-0.8.1:
-
-- Alternate Layout wizard. In the layout editor, the "create" button is now enabled to easily create alternate versions of the current layout.
-- Fixed issue with custom themes/styles in the layout editor.
-- Export Wizard: To export an application for release, and sign it with a non debug key. Accessible from the export menu, from the Android Tools contextual menu, or from the overview page of the manifest editor.
-- New XML File Wizard: To easily create new XML resources file in the /res directory.
-- New checks on launch when attempting to debug on a device.
-- Basic support for drag'n'drop in Graphical layout editor. You can add new items by drag'n'drop from the palette. There is no support for moving/resizing yet.
-- Undo/redo support in all XML form editors and Graphical layout editor.
-
-0.8.0:
-
-- Fixed issue with using custom classes implementing Parcelable in aidl files. Right click the project and choose Android Tools > Create aidl preprocess file for Parcelable Classes.
-- Added Custom Themes to theme drop down in the layout editor.
-- Customizable debug signing keystore path in preferences
-- Customizable HOME package name.
-
-0.7.1:
-
-- Layout Editor.
-
-0.6.1:
-
-- Fixed install issue when project name contains spaces (requires new emulator image)
-- Fixed setup of the New class wizard in the manifest (when clicking on "name" for a class attribute) in the cases where the class and some of its parent packages were missing.
-- Properly kill the application that is about to be reinstalled.
-- Create missing android folder automatically when building application (caused a signing error)
-- Manifest editor: support for uses-library node
-- Fixed NPE in editors.xml.descriptors.XmlDescriptors.createPreference
-- Fixed assert in MultiEditorPart.setActivePage
-- Fixed "connect to debugger" button in DeviceView. Also fixed support for custom process names.
-
-0.6.0:
-
-- new launch option for activity. Can choose to launch default activity (finds an activity configured to show up in the home screen), or specific activity, or none.
-- normal java resources (non java files placed in package folders) are now properly packaged in the final package, and can be accessed through normal java API such as ClassLoader.getResourceAsStream()
-- launch configuration now has an option to wipe emulator data on launch. This always asks for confirmation.
-- launch configuration now has an option to disable the boot animation. This will let the emulator start faster on older computers.
-- Applications are now signed with a debug key (stored in debug.keystore in ~/.android).
-- Installation of application is now more robust and will notify of installation failure. Also installation is blocking, removing issues where ADT tried to launch the activity before the app was installed.
-- Tree-based resource editor + content assist in XML editor for layout, menu, preferences, values xml files. Work in progress...
-
-
-0.4.0 (adt 0.4.0, ddms 0.3.0, editors 0.2.0, common 0.1.0)
-
-- New AndroidManifest editor.
-- True multiple device support allowing debugging apps on several device at the same time
-- New launch modes for device selection: automatic will launch an emulator if no device are present, automatically target the device if only one exists, and prompt the user if 2+ are connected. Manual mode always prompt the user.
-- New classpath container remove the dependencies on the location of android.jar making it easier to share a project through dsvn, cvs, etc... You should fix your project (right click project, choose Android > Fix Project properties)
-- Fixed a case where pm would fail and would up end outputting the "usage" text, which would in turn confuse the plugin during parsing.
-- Fixed an issue with compiling aidl file when they import project local files.
-
-0.3.4 (adt 0.3.4, ddms 0.2.3, editors 0.1.0)
-
-Internal release only.
-- Enabled device support.
-
-0.3.3 (adt 0.3.3, ddms 0.2.3, editors 0.1.0)
-
-- Support for referenced projects.
-- During launch, display if a package conflict occurs when the new application is pushed onto the device.
-- You can now change the font of the logcat view. Also indentation is now properly displayed.
-- Plugin generated files are now properly marked as derived. This will make Team plugins ignore them.
-
-0.3.2
-
-- XML Highlighting for AndroidManifest.xml (requires WebTools WST plugin)
-- Custom java editor for R.java/Manifest.java to make those files non editable. This is to replace the current locking mechanism which causes issues on Mac OS.
-- Fixed some issue in the "Restart adb" feature in the device view of ddms.
-- Better handling of aidl files and the java files generated from them.
-- Plugin now retries to launch the app on the emulator if it fails due to timing issues.
-- Skin dropdown in the Emulator/Target tabs is now build from the content of the skin directory, to support developer made skins.
-- Emulator control panel. This is a UI on top of the emulator console. it allows you to change the state of the network and gsm connection, and to initiate incoming voice call.
-
-0.3.1
-
-- Fixed issue on winXP/Eclipse 3.2 where errors in the New Project Wizard would not display.
-- Added missing intent definition in the AndroidManifest.xml file created by the New Project Wizard.
-- Fixed possible NPE in the debug action from the Process View
-- Support for Eclipse 3.4
-
-0.2.6 / 0.3.0
-
-- New Project Wizard now makes it easy to open Android sample code
-- Plugin will output a warning if the build id of the device/emulator does not match the sdk build id.
-- Java/Debug/ddms perspective now contains direct menus to open some of the ddms views, and to create a new android project. This will require you to reset your perspectives.
-- Error during builds now put an error marker on the project instead of displaying an (annoying) dialog box.
-- Custom builders now remember their build state when restarting eclipse.
-- Properly parse some aapt warnings and don't abort the build when they happen.
-- Abort launch and prompt the user if the project contains errors.
-- New silent/normal/verbose build output.
-
-0.2.5
-
-- Check compiler compliance level before compilation and abort if different from 1.5
-- Fix Project Properties will fix the project compiler compliance if needed.
-- Fixed an issue with multiple source folders.
-- Added support for new Manifest.java class (it is automatically generated with R.java if the content of the AndroidManifest.xml requires it)
-- Fixed an issue that could result in not packaging code changes.
-- Automatic fix of the Launch Configurations when the java package in the manifest is changed. Also improved Launch Config dialog and error alert for erroneous activity names in the Launch Configuration.
-- Support for external jars that are not under the project root directory.
-- New projects have a default layout.
-- Misc fixes for Windows support.
-
-0.2.4
-
-- fixed large resource corruption issue.
-
-0.2.3
-
-- fixed issue related to the integration of dx.
-- fixed issue related to the package generation that was modified for windows support. 
-
-0.2.2
-
-- Changing the SDK location in the Preferences does not require to restart Eclipse anymore.
-- New SDK-Project sync mode in Android preference pane. Default value set to true. If true, all android projects are automatically sync'ed to the SDK defined in the preferences.
-- Cases where no emulator is running but a dialog still says "An emulator is running..." should be less frequent.
-- Projects do not reference the standard desktop JRE anymore, as android.zip contains the core java library. This will solve the case where using a core class non present on the platform would not generate a compilation error.
-- Changing the package defined in the manifest now deletes the R.java class from its previous location. This will require 1 build after upgrading the plugin, before it works.
-- Project selection in the Launch Config Dialog now only shows Android projects.
-- Launching a debug/run session now checks that the project uses the SDK set in the preferences (This is for the non automatic sync mode).
-- Removed obsolete wallpaper mode in the New Project Creation Wizard.
-- dx (dalvik code conversion tool) now embedded instead of calling the external version.
-- improvements in the parsing of the aapt errors.
-- some fixes for windows support.
-
-0.2.1
-
-- fixed bug in logcat search where invalid regexp would cause a crash
-- minor improvements to the build/launch process.
-
-0.2.0
-
-- Logcat view.
-- File Explorer view.
-- Custom options for emulator. In the Launch configuration dialog you can specify custom command line emulator options. See "emulator -help" for available options.
-- Android Tools > Export Application Package is now implemented.
-- Misc incremental builder fixes.
-- Including static .jar files as library in your project will automatically include them in the final APK. Warning: only the .class content is included.
-
-0.1.10
-
-- res and assets folders now fully refresh before the build, ensuring R.java and packaged resources are always up to date. This can be disabled in the preferences under "Android" if this becomes slow due to too many files.
-
-0.1.9
-
-- New Action in the "Processes" view to debug an application that is already running. The source project for this application MUST be opened in the current workspace.
-- Building the project now force refreshes the res folder. This should help rebuilding the resources when only binary files were changed from outside eclipse.
-- Clean/full builds now compile all aidl files found in the build path (previously only incremental builds would compile them). Also, misc improvements to the incremental builders.
-- Starting a run/debug session now asks to save the files and forces a new build to ensure that the latest package is pushed on the device.
-- Plugin should be less aggressive when waiting for the emulator to be ready. This should translate in fewer failed launches.
-
-0.1.8
-
-- Fixed Debugger issue introduced in 0.1.6
-- Added Log level preferences for DDMS. Look under Android > DDMS > Advanced. Default error level is Error.
-
-0.1.7
-
-- Fixed issue where java warnings wouldn't trigger a new package. Now only errors stop the packaging like it should be.
-- Added more error output in the console during launch.
-
-0.1.6
-
-- New "Android" Console. It receives the error output from external tools such and aidl, dx, and aapt (only when they can't be parsed). Any error force the console to be displayed.
-- The Activity Manager on the device/emulator now outputs some messages in the "Android" console when asked to start an activity. This should help you figure out what is wrong if the application doesn't start.
-- Fixed a case where the .apk file would be updated with broken code. Now if there are java compile error, the .apk is not touched.
-- Added support for manifest with non fully qualified activity java name, yet not starting with a dot.
-- Fixed creation of manifest files (through New Project wizard) to use proper namespace for attributes.
-- Better error reporting for namespace issue in the manifest.
-- "Reset Adb" action from the device view. Use this is the plugin tells you  an emulator is running when there are none.
-- New "ddms" Console which receives the standard output of ddms.
-
-0.1.5
-
-- Support for new activity declaration inside AndroidManifest.xml
-- fixed issue that prevented bin/ to be removed from the buildpath when converting project.
-
-0.1.4
-
-- Changes in the Manifest, now properly trigger a new package of the resources.
-
-0.1.3
-
-- Fixed the "fix project properties" action to remove old framework libraries, just not add new ones.
-
-0.1.2
-
-- aidl builder. The Android Resources PreBuilder now also converts aidl files into java files.
-- New Project wizard now allows to make Wallpaper activities instead of gadgets (which are obsolete.)
-- Launch shortcuts. Right click in the package explorer allow you to launch the application in debug or run mode directly without creating launch configurations.
-- New project wizard and Project conversion now sets up the java doc path for android.zip
-- Package builder now supports custom application assets placed in assets/ (which is now created automatically by the New Project Wizard).
-- New action: Android Tools > Fix Project Properties, in the package explorer contextual menu. This allows you to fix the framework path (and its javadoc path) in case you change the sdk location.
-
-0.1.1
-
-- Fixed project convertor to add the framework library if missing.
-
-0.1.0
-
-- New project wizard.
-- Python script-generated project convertor.
-- Incremental builders.
-- XML validation for resource files.
-- Android Launch Configuration.
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/.project b/tools/eclipse/features/com.android.ide.eclipse.adt/.project
deleted file mode 100644
index beca599..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.adt/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>adt-feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/build.properties b/tools/eclipse/features/com.android.ide.eclipse.adt/build.properties
deleted file mode 100644
index 64f93a9..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.adt/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-bin.includes = feature.xml
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
deleted file mode 100644
index e4cc9f2..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
+++ /dev/null
@@ -1,153 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="com.android.ide.eclipse.adt"
-      label="Android Development Tools"
-      version="0.9.4.qualifier"
-      provider-name="The Android Open Source Project"
-      plugin="com.android.ide.eclipse.adt">
-
-   <description>
-      Android Developer Tools.
-   </description>
-
-   <copyright>
-      Copyright (C) 2007 The Android Open Source Project
-   </copyright>
-
-   <license url="http://www.eclipse.org/org/documents/epl-v10.php">
-      Note:  kxml2-2.3.0.jar is under the BSD license rather than the EPL.  You can find a copy of the BSD License at http://www.opensource.org/licenses/bsd-license.php
-
-      Eclipse Public License - v 1.0
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT&apos;S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-&quot;Contribution&quot; means:
-
-a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
-
-b) in the case of each subsequent Contributor:
-
-i) changes to the Program, and
-
-ii) additions to the Program;
-
-where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution &apos;originates&apos; from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor&apos;s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
-
-&quot;Contributor&quot; means any person or entity that distributes the Program.
-
-&quot;Licensed Patents&quot; mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
-
-&quot;Program&quot; means the Contributions distributed in accordance with this Agreement.
-
-&quot;Recipient&quot; means anyone who receives the Program under this Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
-a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
-
-b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
-
-c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient&apos;s responsibility to acquire that license before distributing the Program.
-
-d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
-
-a) it complies with the terms and conditions of this Agreement; and
-
-b) its license agreement:
-
-i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
-
-ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
-
-iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
-
-iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
-
-When the Program is made available in source code form:
-
-a) it must be made available under this Agreement; and
-
-b) a copy of this Agreement must be included with each copy of the Program.
-
-Contributors may not remove or alter any copyright notices contained within the Program.
-
-Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (&quot;Commercial Contributor&quot;) hereby agrees to defend and indemnify every other Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor&apos;s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient&apos;s patent(s), then such Recipient&apos;s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
-
-All Recipient&apos;s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient&apos;s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient&apos;s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
-   </license>
-
-   <url>
-      <update label="Android Update Site" url="https://dl-ssl.google.com/android/eclipse/"/>
-   </url>
-
-   <requires>
-      <import plugin="com.android.ide.eclipse.ddms"/>
-      <import plugin="org.eclipse.core.runtime"/>
-      <import plugin="org.eclipse.core.resources"/>
-      <import plugin="org.eclipse.debug.core"/>
-      <import plugin="org.eclipse.debug.ui"/>
-      <import plugin="org.eclipse.jdt"/>
-      <import plugin="org.eclipse.ant.core"/>
-      <import plugin="org.eclipse.jdt.core"/>
-      <import plugin="org.eclipse.jdt.ui"/>
-      <import plugin="org.eclipse.jdt.launching"/>
-      <import plugin="org.eclipse.jface.text"/>
-      <import plugin="org.eclipse.ui.editors"/>
-      <import plugin="org.eclipse.ui.workbench.texteditor"/>
-      <import plugin="org.eclipse.ui.console"/>
-      <import plugin="org.eclipse.core.filesystem"/>
-      <import plugin="org.eclipse.ui"/>
-      <import plugin="org.eclipse.ui.ide"/>
-      <import plugin="org.eclipse.ui.forms"/>
-      <import plugin="org.eclipse.gef"/>
-      <import plugin="org.eclipse.ui.browser"/>
-      <import plugin="org.eclipse.ui.views"/>
-      <import plugin="org.eclipse.wst.sse.core"/>
-      <import plugin="org.eclipse.wst.sse.ui"/>
-      <import plugin="org.eclipse.wst.xml.core"/>
-      <import plugin="org.eclipse.wst.xml.ui"/>
-      <import plugin="org.eclipse.jdt.junit"/>
-      <import plugin="org.eclipse.jdt.junit.runtime"/>
-      <import plugin="org.eclipse.ltk.core.refactoring"/>
-      <import plugin="org.eclipse.ltk.ui.refactoring"/>
-      <import plugin="org.eclipse.core.expressions"/>
-   </requires>
-
-   <plugin
-         id="com.android.ide.eclipse.adt"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-</feature>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/.project b/tools/eclipse/features/com.android.ide.eclipse.ddms/.project
deleted file mode 100644
index f80ff60..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.ddms/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ddms-feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/build.properties b/tools/eclipse/features/com.android.ide.eclipse.ddms/build.properties
deleted file mode 100644
index 64f93a9..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.ddms/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-bin.includes = feature.xml
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
deleted file mode 100644
index 9b782ac..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
+++ /dev/null
@@ -1,245 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="com.android.ide.eclipse.ddms"
-      label="Android DDMS"
-      version="0.9.4.qualifier"
-      provider-name="The Android Open Source Project">
-
-   <description>
-      Android Dalvik Debug Monitor Service
-   </description>
-
-   <copyright>
-      Copyright (C) 2007 The Android Open Source Project
-   </copyright>
-
-   <license url="http://www.apache.org/licenses/LICENSE-2.0">
-      Note:  jcommon-1.0.12.jar is under the BSD license rather than the APL.  You can find a copy of the BSD License at http://www.opensource.org/licenses/bsd-license.php
-
-   jfreechart-1.0.9.jar and jfreechart-1.0.9-swt.jar are under the LGPL rather than the APL.  You can find a copy of the LGPL at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.  You can get the source code for these two components at http://android.git.kernel.org/pub/jfreechart-1.0.9.zip
-
-
-      Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      &quot;License&quot; shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      &quot;Licensor&quot; shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      &quot;Legal Entity&quot; shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      &quot;control&quot; means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      &quot;You&quot; (or &quot;Your&quot;) shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      &quot;Source&quot; form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      &quot;Object&quot; form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      &quot;Work&quot; shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      &quot;Derivative Works&quot; shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      &quot;Contribution&quot; shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, &quot;submitted&quot;
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as &quot;Not a Contribution.&quot;
-
-      &quot;Contributor&quot; shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a &quot;NOTICE&quot; text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an &quot;AS IS&quot; BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets &quot;[]&quot;
-      replaced with your own identifying information. (Don&apos;t include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same &quot;printed page&quot; as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
-   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 &quot;AS IS&quot; 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.
-   </license>
-
-   <url>
-      <update label="Android Update Site" url="https://dl-ssl.google.com/android/eclipse/"/>
-   </url>
-
-   <requires>
-      <import plugin="org.eclipse.ui"/>
-      <import plugin="org.eclipse.core.runtime"/>
-      <import plugin="org.eclipse.ui.console"/>
-      <import plugin="org.eclipse.core.resources"/>
-      <import plugin="org.eclipse.ui.ide"/>
-      <import plugin="org.eclipse.core.filesystem"/>
-   </requires>
-
-   <plugin
-         id="com.android.ide.eclipse.ddms"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-</feature>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/.project b/tools/eclipse/features/com.android.ide.eclipse.tests/.project
deleted file mode 100644
index 6a16276..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.tests/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>adt-tests-feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/build.properties b/tools/eclipse/features/com.android.ide.eclipse.tests/build.properties
deleted file mode 100644
index 64f93a9..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.tests/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-bin.includes = feature.xml
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
deleted file mode 100644
index 679da31..0000000
--- a/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="com.android.ide.eclipse.tests"
-      label="ADT Tests"
-      version="0.9.4.qualifier"
-      provider-name="The Android Open Source Project">
-
-   <copyright>
-      Copyright (C) 2007 The Android Open Source Project
-   </copyright>
-
-   <requires>
-      <import plugin="org.eclipse.ui"/>
-      <import plugin="org.eclipse.core.runtime"/>
-      <import plugin="org.eclipse.core.resources"/>
-      <import plugin="com.android.ide.eclipse.adt"/>
-      <import plugin="org.junit"/>
-      <import plugin="org.eclipse.jdt.core"/>
-      <import plugin="org.eclipse.jdt.launching"/>
-      <import plugin="org.eclipse.ui.views"/>
-   </requires>
-
-   <plugin
-         id="com.android.ide.eclipse.tests"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-</feature>
diff --git a/tools/eclipse/plugins/.gitignore b/tools/eclipse/plugins/.gitignore
deleted file mode 100644
index 72cc8c5..0000000
--- a/tools/eclipse/plugins/.gitignore
+++ /dev/null
@@ -1,59 +0,0 @@
-com.android.ide.eclipse.adt/bin
-com.android.ide.eclipse.ddms/bin
-com.android.ide.eclipse.tests/bin
-
-com.android.ide.eclipse.adt/androidprefs.jar
-com.android.ide.eclipse.adt/jarutils.jar
-com.android.ide.eclipse.adt/kxml2-2.3.0.jar
-com.android.ide.eclipse.adt/layoutlib_api.jar
-com.android.ide.eclipse.adt/layoutlib_utils.jar
-com.android.ide.eclipse.adt/ninepatch.jar
-com.android.ide.eclipse.adt/sdklib.jar
-com.android.ide.eclipse.adt/sdkstats.jar
-com.android.ide.eclipse.adt/sdkuilib.jar
-com.android.ide.eclipse.adt/commons-compress-1.0.jar
-com.android.ide.eclipse.ddms/icons/add.png
-com.android.ide.eclipse.ddms/icons/backward.png
-com.android.ide.eclipse.ddms/icons/clear.png
-com.android.ide.eclipse.ddms/icons/d.png
-com.android.ide.eclipse.ddms/icons/debug-attach.png
-com.android.ide.eclipse.ddms/icons/debug-error.png
-com.android.ide.eclipse.ddms/icons/debug-wait.png
-com.android.ide.eclipse.ddms/icons/delete.png
-com.android.ide.eclipse.ddms/icons/device.png
-com.android.ide.eclipse.ddms/icons/down.png
-com.android.ide.eclipse.ddms/icons/e.png
-com.android.ide.eclipse.ddms/icons/edit.png
-com.android.ide.eclipse.ddms/icons/empty.png
-com.android.ide.eclipse.ddms/icons/emulator.png
-com.android.ide.eclipse.ddms/icons/forward.png
-com.android.ide.eclipse.ddms/icons/gc.png
-com.android.ide.eclipse.ddms/icons/halt.png
-com.android.ide.eclipse.ddms/icons/heap.png
-com.android.ide.eclipse.ddms/icons/hprof.png
-com.android.ide.eclipse.ddms/icons/i.png
-com.android.ide.eclipse.ddms/icons/importBug.png
-com.android.ide.eclipse.ddms/icons/load.png
-com.android.ide.eclipse.ddms/icons/pause.png
-com.android.ide.eclipse.ddms/icons/play.png
-com.android.ide.eclipse.ddms/icons/pull.png
-com.android.ide.eclipse.ddms/icons/push.png
-com.android.ide.eclipse.ddms/icons/save.png
-com.android.ide.eclipse.ddms/icons/thread.png
-com.android.ide.eclipse.ddms/icons/tracing_start.png
-com.android.ide.eclipse.ddms/icons/tracing_stop.png
-com.android.ide.eclipse.ddms/icons/up.png
-com.android.ide.eclipse.ddms/icons/v.png
-com.android.ide.eclipse.ddms/icons/w.png
-com.android.ide.eclipse.ddms/icons/warning.png
-com.android.ide.eclipse.ddms/libs/jcommon-1.0.12.jar
-com.android.ide.eclipse.ddms/libs/jfreechart-1.0.9-swt.jar
-com.android.ide.eclipse.ddms/libs/jfreechart-1.0.9.jar
-com.android.ide.eclipse.ddms/src/com/android/ddmlib
-com.android.ide.eclipse.ddms/src/com/android/ddmuilib
-com.android.ide.eclipse.tests/kxml2-2.3.0.jar
-com.android.ide.eclipse.tests/unittests/com/android/ddmlib
-com.android.ide.eclipse.tests/unittests/com/android/sdklib
-com.android.ide.eclipse.tests/unittests/com/android/sdkuilib
-com.android.ide.eclipse.tests/unittests/com/android/layoutlib
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
deleted file mode 100644
index 5684195..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="Makefile|resources/" kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="lib" path="jarutils.jar" sourcepath="/JarUtils"/>
-	<classpathentry kind="lib" path="androidprefs.jar" sourcepath="/AndroidPrefs"/>
-	<classpathentry kind="lib" path="sdkstats.jar" sourcepath="/SdkStatsService"/>
-	<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
-	<classpathentry kind="lib" path="layoutlib_api.jar"/>
-	<classpathentry kind="lib" path="layoutlib_utils.jar"/>
-	<classpathentry kind="lib" path="ninepatch.jar"/>
-	<classpathentry kind="lib" path="sdklib.jar" sourcepath="/SdkLib"/>
-	<classpathentry kind="lib" path="sdkuilib.jar" sourcepath="/SdkUiLib"/>
-	<classpathentry kind="lib" path="commons-compress-1.0.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.gitignore b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.gitignore
deleted file mode 100644
index d392f0e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.jar
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project
deleted file mode 100644
index c7b1ad4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>adt</name>
-	<comment></comment>
-	<projects>
-		<project>SdkLib</project>
-		<project>SdkUiLib</project>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
deleted file mode 100644
index 0c78390..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,110 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Android Development Toolkit
-Bundle-SymbolicName: com.android.ide.eclipse.adt;singleton:=true
-Bundle-Version: 0.9.4.qualifier
-Bundle-ClassPath: .,
- jarutils.jar,
- androidprefs.jar,
- sdkstats.jar,
- kxml2-2.3.0.jar,
- layoutlib_api.jar,
- ninepatch.jar,
- layoutlib_utils.jar,
- sdklib.jar,
- sdkuilib.jar,
- commons-compress-1.0.jar
-Bundle-Activator: com.android.ide.eclipse.adt.AdtPlugin
-Bundle-Vendor: The Android Open Source Project
-Require-Bundle: com.android.ide.eclipse.ddms,
- org.eclipse.core.runtime,
- org.eclipse.core.resources,
- org.eclipse.debug.core,
- org.eclipse.debug.ui,
- org.eclipse.jdt,
- org.eclipse.ant.core,
- org.eclipse.jdt.core,
- org.eclipse.jdt.ui,
- org.eclipse.jdt.launching,
- org.eclipse.jface.text,
- org.eclipse.ui.editors,
- org.eclipse.ui.workbench.texteditor,
- org.eclipse.ui.console,
- org.eclipse.core.filesystem,
- org.eclipse.ui,
- org.eclipse.ui.ide,
- org.eclipse.ui.forms,
- org.eclipse.gef,
- org.eclipse.ui.browser,
- org.eclipse.ui.views,
- org.eclipse.wst.sse.core,
- org.eclipse.wst.sse.ui,
- org.eclipse.wst.xml.core,
- org.eclipse.wst.xml.ui,
- org.eclipse.jdt.junit,
- org.eclipse.jdt.junit.runtime,
- org.eclipse.ltk.core.refactoring,
- org.eclipse.ltk.ui.refactoring,
- org.eclipse.core.expressions
-Eclipse-LazyStart: true
-Export-Package: com.android.ide.eclipse.adt;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.actions;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.build;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.layout;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.layout.configuration,
- com.android.ide.eclipse.adt.internal.editors.layout.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.layout.parts;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.layout.uimodel;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.manifest;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.manifest.model;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.manifest.pages;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.menu;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.menu.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.resources;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.resources.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.resources.uimodel;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.ui;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.ui.tree;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.uimodel;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.xml;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.editors.xml.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.launch;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.launch.junit;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.launch.junit.runtime;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.preferences;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.project;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.properties;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.refactorings.extractstring;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.resources;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.resources.configurations;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.resources.manager;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.resources.manager.files;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.sdk;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.ui;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.wizards.actions;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.wizards.export;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.wizards.newproject;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.wizards.newxmlfile;x-friends:="com.android.ide.eclipse.tests",
- com.android.jarutils;x-friends:="com.android.ide.eclipse.tests",
- com.android.layoutlib.api;x-friends:="com.android.ide.eclipse.tests",
- com.android.layoutlib.utils;x-friends:="com.android.ide.eclipse.tests",
- com.android.ninepatch;x-friends:="com.android.ide.eclipse.tests",
- com.android.prefs;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdklib;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdklib.internal.avd;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdklib.internal.project;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdklib.internal.repository;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdklib.repository;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdklib.xml;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdkstats;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdkuilib.internal.repository;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdkuilib.internal.repository.icons;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdkuilib.internal.tasks;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdkuilib.internal.widgets;x-friends:="com.android.ide.eclipse.tests",
- com.android.sdkuilib.repository;x-friends:="com.android.ide.eclipse.tests"
-
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/MODULE_LICENSE_EPL b/tools/eclipse/plugins/com.android.ide.eclipse.adt/MODULE_LICENSE_EPL
deleted file mode 100644
index e69de29..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/MODULE_LICENSE_EPL
+++ /dev/null
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/NOTICE b/tools/eclipse/plugins/com.android.ide.eclipse.adt/NOTICE
deleted file mode 100644
index 49c101d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/NOTICE
+++ /dev/null
@@ -1,224 +0,0 @@
-*Eclipse Public License - v 1.0*
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
-PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
-THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-*1. DEFINITIONS*
-
-"Contribution" means:
-
-a) in the case of the initial Contributor, the initial code and
-documentation distributed under this Agreement, and
-b) in the case of each subsequent Contributor:
-
-i) changes to the Program, and
-
-ii) additions to the Program;
-
-where such changes and/or additions to the Program originate from and
-are distributed by that particular Contributor. A Contribution
-'originates' from a Contributor if it was added to the Program by such
-Contributor itself or anyone acting on such Contributor's behalf.
-Contributions do not include additions to the Program which: (i) are
-separate modules of software distributed in conjunction with the Program
-under their own license agreement, and (ii) are not derivative works of
-the Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents " mean patent claims licensable by a Contributor which
-are necessarily infringed by the use or sale of its Contribution alone
-or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this
-Agreement.
-
-"Recipient" means anyone who receives the Program under this Agreement,
-including all Contributors.
-
-*2. GRANT OF RIGHTS*
-
-a) Subject to the terms of this Agreement, each Contributor hereby
-grants Recipient a non-exclusive, worldwide, royalty-free copyright
-license to reproduce, prepare derivative works of, publicly display,
-publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and
-object code form.
-
-b) Subject to the terms of this Agreement, each Contributor hereby
-grants Recipient a non-exclusive, worldwide, royalty-free patent license
-under Licensed Patents to make, use, sell, offer to sell, import and
-otherwise transfer the Contribution of such Contributor, if any, in
-source code and object code form. This patent license shall apply to the
-combination of the Contribution and the Program if, at the time the
-Contribution is added by the Contributor, such addition of the
-Contribution causes such combination to be covered by the Licensed
-Patents. The patent license shall not apply to any other combinations
-which include the Contribution. No hardware per se is licensed hereunder.
-
-c) Recipient understands that although each Contributor grants the
-licenses to its Contributions set forth herein, no assurances are
-provided by any Contributor that the Program does not infringe the
-patent or other intellectual property rights of any other entity. Each
-Contributor disclaims any liability to Recipient for claims brought by
-any other entity based on infringement of intellectual property rights
-or otherwise. As a condition to exercising the rights and licenses
-granted hereunder, each Recipient hereby assumes sole responsibility to
-secure any other intellectual property rights needed, if any. For
-example, if a third party patent license is required to allow Recipient
-to distribute the Program, it is Recipient's responsibility to acquire
-that license before distributing the Program.
-
-d) Each Contributor represents that to its knowledge it has sufficient
-copyright rights in its Contribution, if any, to grant the copyright
-license set forth in this Agreement.
-
-*3. REQUIREMENTS*
-
-A Contributor may choose to distribute the Program in object code form
-under its own license agreement, provided that:
-
-a) it complies with the terms and conditions of this Agreement; and
-
-b) its license agreement:
-
-i) effectively disclaims on behalf of all Contributors all warranties
-and conditions, express and implied, including warranties or conditions
-of title and non-infringement, and implied warranties or conditions of
-merchantability and fitness for a particular purpose;
-
-ii) effectively excludes on behalf of all Contributors all liability for
-damages, including direct, indirect, special, incidental and
-consequential damages, such as lost profits;
-
-iii) states that any provisions which differ from this Agreement are
-offered by that Contributor alone and not by any other party; and
-
-iv) states that source code for the Program is available from such
-Contributor, and informs licensees how to obtain it in a reasonable
-manner on or through a medium customarily used for software exchange.
-
-When the Program is made available in source code form:
-
-a) it must be made available under this Agreement; and
-
-b) a copy of this Agreement must be included with each copy of the Program.
-
-Contributors may not remove or alter any copyright notices contained
-within the Program.
-
-Each Contributor must identify itself as the originator of its
-Contribution, if any, in a manner that reasonably allows subsequent
-Recipients to identify the originator of the Contribution.
-
-*4. COMMERCIAL DISTRIBUTION*
-
-Commercial distributors of software may accept certain responsibilities
-with respect to end users, business partners and the like. While this
-license is intended to facilitate the commercial use of the Program, the
-Contributor who includes the Program in a commercial product offering
-should do so in a manner which does not create potential liability for
-other Contributors. Therefore, if a Contributor includes the Program in
-a commercial product offering, such Contributor ("Commercial
-Contributor") hereby agrees to defend and indemnify every other
-Contributor ("Indemnified Contributor") against any losses, damages and
-costs (collectively "Losses") arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified
-Contributor to the extent caused by the acts or omissions of such
-Commercial Contributor in connection with its distribution of the
-Program in a commercial product offering. The obligations in this
-section do not apply to any claims or Losses relating to any actual or
-alleged intellectual property infringement. In order to qualify, an
-Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial
-Contributor to control, and cooperate with the Commercial Contributor
-in, the defense and any related settlement negotiations. The Indemnified
-Contributor may participate in any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial
-product offering, Product X. That Contributor is then a Commercial
-Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance
-claims and warranties are such Commercial Contributor's responsibility
-alone. Under this section, the Commercial Contributor would have to
-defend claims against the other Contributors related to those
-performance claims and warranties, and if a court requires any other
-Contributor to pay any damages as a result, the Commercial Contributor
-must pay those damages.
-
-*5. NO WARRANTY*
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
-ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
-EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES
-OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
-A PARTICULAR PURPOSE. Each Recipient is solely responsible for
-determining the appropriateness of using and distributing the Program
-and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program
-errors, compliance with applicable laws, damage to or loss of data,
-programs or equipment, and unavailability or interruption of operations.
-
-*6. DISCLAIMER OF LIABILITY*
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
-ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
-WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
-DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-*7. GENERAL*
-
-If any provision of this Agreement is invalid or unenforceable under
-applicable law, it shall not affect the validity or enforceability of
-the remainder of the terms of this Agreement, and without further action
-by the parties hereto, such provision shall be reformed to the minimum
-extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against any entity (including
-a cross-claim or counterclaim in a lawsuit) alleging that the Program
-itself (excluding combinations of the Program with other software or
-hardware) infringes such Recipient's patent(s), then such Recipient's
-rights granted under Section 2(b) shall terminate as of the date such
-litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it fails
-to comply with any of the material terms or conditions of this Agreement
-and does not cure such failure in a reasonable period of time after
-becoming aware of such noncompliance. If all Recipient's rights under
-this Agreement terminate, Recipient agrees to cease use and distribution
-of the Program as soon as reasonably practicable. However, Recipient's
-obligations under this Agreement and any licenses granted by Recipient
-relating to the Program shall continue and survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement,
-but in order to avoid inconsistency the Agreement is copyrighted and may
-only be modified in the following manner. The Agreement Steward reserves
-the right to publish new versions (including revisions) of this
-Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the
-initial Agreement Steward. The Eclipse Foundation may assign the
-responsibility to serve as the Agreement Steward to a suitable separate
-entity. Each new version of the Agreement will be given a distinguishing
-version number. The Program (including Contributions) may always be
-distributed subject to the version of the Agreement under which it was
-received. In addition, after a new version of the Agreement is
-published, Contributor may elect to distribute the Program (including
-its Contributions) under the new version. Except as expressly stated in
-Sections 2(a) and 2(b) above, Recipient receives no rights or licenses
-to the intellectual property of any Contributor under this Agreement,
-whether expressly, by implication, estoppel or otherwise. All rights in
-the Program not expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the
-intellectual property laws of the United States of America. No party to
-this Agreement will bring a legal action under this Agreement more than
-one year after the cause of action arose. Each party waives its rights
-to a jury trial in any resulting litigation.
-
- 
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/about.ini b/tools/eclipse/plugins/com.android.ide.eclipse.adt/about.ini
deleted file mode 100644
index fddaef0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/about.ini
+++ /dev/null
@@ -1 +0,0 @@
-featureImage=icons/android_32X32.jpg
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/build.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/build.properties
deleted file mode 100644
index af6383b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/build.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-bin.includes = plugin.xml,\
-               META-INF/,\
-               icons/,\
-               .,\
-               templates/,\
-               about.ini,\
-               jarutils.jar,\
-               androidprefs.jar,\
-               sdkstats.jar,\
-               kxml2-2.3.0.jar,\
-               layoutlib_api.jar,\
-               layoutlib_utils.jar,\
-               ninepatch.jar,\
-               sdklib.jar,\
-               sdkuilib.jar,\
-               commons-compress-1.0.jar
-source.. = src/
-output.. = bin/
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/add.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/add.png
deleted file mode 100644
index eefc2ca..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/add.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android.png
deleted file mode 100644
index 3779d4d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_32X32.jpg b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_32X32.jpg
deleted file mode 100644
index 823670b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_32X32.jpg
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_large.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_large.png
deleted file mode 100644
index 64e3601..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_large.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_project.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_project.png
deleted file mode 100644
index 5334568..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_project.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/androidjunit.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/androidjunit.png
deleted file mode 100644
index 25826dc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/androidjunit.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/avd_manager.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/avd_manager.png
deleted file mode 100755
index 7dbbbb6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/avd_manager.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/az_sort.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/az_sort.png
deleted file mode 100644
index 5d92f76..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/az_sort.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/clipping.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/clipping.png
deleted file mode 100644
index 6f2a35f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/clipping.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/delete.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/delete.png
deleted file mode 100644
index db5fab8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/delete.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dimension.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dimension.png
deleted file mode 100644
index 10057c8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dimension.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/down.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/down.png
deleted file mode 100644
index 36cd223..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/down.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dpi.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dpi.png
deleted file mode 100644
index fae5e96..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dpi.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/error.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/error.png
deleted file mode 100644
index 1eecf2c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/error.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/keyboard.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/keyboard.png
deleted file mode 100644
index 7911a85..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/keyboard.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/language.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/language.png
deleted file mode 100644
index a727dd5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/language.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mainLaunchTab.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mainLaunchTab.png
deleted file mode 100644
index 2540fbb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mainLaunchTab.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/match.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/match.png
deleted file mode 100644
index 7e939c2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/match.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mcc.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mcc.png
deleted file mode 100644
index 4dc95d7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mcc.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mnc.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mnc.png
deleted file mode 100644
index aefffe4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mnc.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/navpad.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/navpad.png
deleted file mode 100644
index c2bb79a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/navpad.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png
deleted file mode 100644
index 0f0e883..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png
deleted file mode 100644
index 8273185..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/orientation.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/orientation.png
deleted file mode 100644
index 423c3cd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/orientation.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/region.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/region.png
deleted file mode 100644
index 9608cd6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/region.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/text_input.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/text_input.png
deleted file mode 100644
index b4ddc87..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/text_input.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/touch.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/touch.png
deleted file mode 100644
index 6536576..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/touch.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/up.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/up.png
deleted file mode 100644
index 35b9a46..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/up.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/warning.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/warning.png
deleted file mode 100644
index ca3b6ed..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/warning.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
deleted file mode 100644
index 285f667..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
+++ /dev/null
@@ -1,693 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.2"?>
-<plugin>
-   <extension
-         id="com.android.ide.eclipse.common.xmlProblem"
-         name="Android XML Format Problem"
-         point="org.eclipse.core.resources.markers">
-      <super type="org.eclipse.core.resources.problemmarker"/>
-      <super type="org.eclipse.core.resources.textmarker"/>
-      <persistent value="true"/>
-   </extension>
-   <extension
-         id="com.android.ide.eclipse.common.aaptProblem"
-         name="Android AAPT Problem"
-         point="org.eclipse.core.resources.markers">
-      <super type="org.eclipse.core.resources.problemmarker"/>
-      <super type="org.eclipse.core.resources.textmarker"/>
-      <persistent value="true"/>
-   </extension>
-   <extension
-         id="com.android.ide.eclipse.common.aapt2Problem"
-         name="Android AAPT Problem"
-         point="org.eclipse.core.resources.markers">
-      <super type="org.eclipse.core.resources.problemmarker"/>
-      <super type="org.eclipse.core.resources.textmarker"/>
-      <persistent value="true"/>
-   </extension>
-   <extension
-         id="com.android.ide.eclipse.common.aidlProblem"
-         name="Android AIDL Problem"
-         point="org.eclipse.core.resources.markers">
-      <super type="org.eclipse.core.resources.problemmarker"/>
-      <super type="org.eclipse.core.resources.textmarker"/>
-      <persistent value="true"/>
-   </extension>
-   <extension
-        id="com.android.ide.eclipse.common.androidProblem"
-        name="Android XML Content Problem"
-        point="org.eclipse.core.resources.markers">
-      <super type="org.eclipse.core.resources.problemmarker"/>
-      <super type="org.eclipse.core.resources.textmarker"/>
-      <persistent value="true"/>
-   </extension>
-   <extension
-         id="ResourceManagerBuilder"
-         name="Android Resource Manager"
-         point="org.eclipse.core.resources.builders">
-      <builder
-            hasNature="true">
-         <run class="com.android.ide.eclipse.adt.internal.build.ResourceManagerBuilder"/>
-      </builder>
-   </extension>
-   <extension
-         id="PreCompilerBuilder"
-         name="Android Pre Compiler"
-         point="org.eclipse.core.resources.builders">
-      <builder
-            hasNature="true">
-         <run class="com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder"/>
-      </builder>
-   </extension>
-   <extension
-         id="ApkBuilder"
-         name="Android Package Builder"
-         point="org.eclipse.core.resources.builders">
-      <builder
-            hasNature="true">
-         <run class="com.android.ide.eclipse.adt.internal.build.ApkBuilder"/>
-      </builder>
-   </extension>
-   <extension
-         id="AndroidNature"
-         name="AndroidNature"
-         point="org.eclipse.core.resources.natures">
-      <runtime>
-         <run class="com.android.ide.eclipse.adt.internal.project.AndroidNature"/>
-      </runtime>
-      <builder id="com.android.ide.eclipse.adt.ResourceManagerBuilder"/>
-      <builder id="com.android.ide.eclipse.adt.PreCompilerBuilder"/>
-      <builder id="com.android.ide.eclipse.adt.ApkBuilder"/>
-   </extension>
-   <extension
-         point="org.eclipse.ui.newWizards">
-      <category
-            id="com.android.ide.eclipse.wizards.category"
-            name="Android"/>
-      <wizard
-            canFinishEarly="false"
-            category="com.android.ide.eclipse.wizards.category"
-            class="com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard"
-            finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
-            hasPages="true"
-            icon="icons/new_adt_project.png"
-            id="com.android.ide.eclipse.adt.project.NewProjectWizard"
-            name="Android Project"
-            preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
-            project="true"/>
-      <wizard
-            canFinishEarly="false"
-            category="com.android.ide.eclipse.wizards.category"
-            class="com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectWizard"
-            finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
-            hasPages="true"
-            icon="icons/androidjunit.png"
-            id="com.android.ide.eclipse.adt.project.NewTestProjectWizard"
-            name="Android Test Project"
-            preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
-            project="true">
-      </wizard>
-      <wizard
-            canFinishEarly="false"
-            category="com.android.ide.eclipse.wizards.category"
-            class="com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard"
-            finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
-            hasPages="true"
-            icon="icons/new_xml.png"
-            id="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard"
-            name="Android XML File"
-            preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
-            project="false">
-      </wizard>
-   </extension>
-   <extension
-         point="org.eclipse.debug.core.launchConfigurationTypes">
-      <launchConfigurationType
-            delegate="com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate"
-            delegateDescription="The Android Application Launcher supports running and debugging remote Android applications on devices or emulators."
-            delegateName="Android Launcher"
-            id="com.android.ide.eclipse.adt.debug.LaunchConfigType"
-            modes="debug, run"
-            name="Android Application"
-            public="true"
-            sourceLocatorId="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"
-            sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer">
-      </launchConfigurationType>
-   </extension>
-   <extension
-         point="org.eclipse.debug.ui.launchConfigurationTypeImages">
-      <launchConfigurationTypeImage
-            configTypeID="com.android.ide.eclipse.adt.debug.LaunchConfigType"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.adt.debug.LaunchConfigTypeImage"/>
-   </extension>
-   <extension
-         point="org.eclipse.debug.ui.launchConfigurationTabGroups">
-      <launchConfigurationTabGroup
-            class="com.android.ide.eclipse.adt.internal.launch.LaunchConfigTabGroup"
-            description="Android Application"
-            id="com.android.ide.eclipse.adt.debug.LaunchConfigTabGroup"
-            type="com.android.ide.eclipse.adt.debug.LaunchConfigType"/>
-   </extension>
-   <extension
-         point="org.eclipse.debug.ui.launchShortcuts">
-      <shortcut
-            category="com.android.ide.eclipse.adt.launch.LaunchConfigType"
-            class="com.android.ide.eclipse.adt.internal.launch.LaunchShortcut"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut"
-            label="Android Application"
-            modes="debug, run">
-        <contextualLaunch>
-           <enablement>
-             <with variable="selection">
-               <count value="1"/>
-               <iterate>
-                  <and>
-                     <test property="org.eclipse.jdt.launching.isContainer"/>
-                     <test property="org.eclipse.jdt.launching.hasProjectNature" args="com.android.ide.eclipse.adt.AndroidNature"/>
-                  </and>
-               </iterate>
-               </with>
-           </enablement>
-         </contextualLaunch>
-         <perspective id="org.eclipse.jdt.ui.JavaPerspective"/>
-         <perspective id="org.eclipse.debug.ui.DebugPerspective"/>
-         <description
-               description="Runs an Android Application"
-               mode="run">
-         </description>
-         <description
-               description="Debugs an Android Application"
-               mode="debug">
-         </description>
-      </shortcut>
-   </extension>
-   <extension
-         point="org.eclipse.ui.popupMenus">
-      <objectContribution
-            id="com.android.ide.eclipse.adt.contribution1"
-            nameFilter="*"
-            objectClass="org.eclipse.core.resources.IProject"
-            adaptable="true">
-         <menu
-               id="com.android.ide.eclipse.adt.AndroidTools"
-               label="Android Tools"
-               path="additions">
-            <separator name="group1"/>
-         </menu>
-         <visibility>
-            <not>
-            <or>
-            <objectState
-                name="projectNature"
-                value="com.android.ide.eclipse.adt.AndroidNature"/>
-            <objectState
-                name="open"
-                value="false"/>
-            </or>
-            </not>
-         </visibility>
-         <action
-               class="com.android.ide.eclipse.adt.internal.actions.ConvertToAndroidAction"
-               enablesFor="1"
-               id="com.android.ide.eclipse.adt.ConvertToAndroidAction"
-               label="Convert To Android Project"
-               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1"/>
-      </objectContribution>
-      <objectContribution
-            id="com.android.ide.eclipse.adt.contribution2"
-            nameFilter="*"
-            objectClass="org.eclipse.core.resources.IProject"
-            adaptable="true">
-         <menu
-               id="com.android.ide.eclipse.adt.AndroidTools"
-               label="Android Tools"
-               path="additions">
-            <separator name="group1"/>
-            <separator name="group2"/>
-         </menu>
-         <filter
-               name="projectNature"
-               value="com.android.ide.eclipse.adt.AndroidNature">
-         </filter>
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.NewXmlFileAction"
-               enablesFor="1"
-               icon="icons/new_xml.png"
-               id="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
-               label="New Resource File..."
-               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1"
-               tooltip="Opens a wizard to help create a new Android XML Resource file">
-         </action>
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.NewTestProjectAction"
-               enablesFor="1"
-               icon="icons/androidjunit.png"
-               id="com.android.ide.eclipse.adt.wizards.actions.NewTestProjectAction"
-               label="New Test Project..."
-               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1"
-               tooltip="Opens a wizard to help create a new Android Test Project">
-         </action>
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.ExportAction"
-               enablesFor="1"
-               id="com.android.ide.eclipse.adt.project.ExportAction"
-               label="Export Unsigned Application Package..."
-               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group2"/>
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.ExportWizardAction"
-               enablesFor="1"
-               id="com.android.ide.eclipse.adt.project.ExportWizardAction"
-               label="Export Signed Application Package..."
-               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group2"/>
-         <action
-               class="com.android.ide.eclipse.adt.internal.actions.FixProjectAction"
-               enablesFor="1"
-               id="com.android.ide.eclipse.adt.project.FixProjectAction"
-               label="Fix Project Properties"
-               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group3"/>
-      </objectContribution>
-
-   </extension>
-   <extension
-         point="org.eclipse.ui.preferencePages">
-      <page
-            class="com.android.ide.eclipse.adt.internal.preferences.AndroidPreferencePage"
-            id="com.android.ide.eclipse.preferences.main"
-            name="Android"/>
-      <page
-            category="com.android.ide.eclipse.preferences.main"
-            class="com.android.ide.eclipse.adt.internal.preferences.BuildPreferencePage"
-            id="com.android.ide.eclipse.adt.preferences.BuildPreferencePage"
-            name="Build"/>
-      <page
-            category="com.android.ide.eclipse.preferences.main"
-            class="com.android.ide.eclipse.adt.internal.preferences.LaunchPreferencePage"
-            id="com.android.ide.eclipse.adt.preferences.LaunchPreferencePage"
-            name="Launch"/>
-      <page
-            category="com.android.ide.eclipse.preferences.main"
-            class="com.android.ide.eclipse.adt.internal.preferences.UsagePreferencePage"
-            id="com.android.ide.eclipse.common.preferences.UsagePreferencePage"
-            name="Usage Stats">
-      </page>
-   </extension>
-   <extension
-         point="org.eclipse.core.runtime.preferences">
-      <initializer class="com.android.ide.eclipse.adt.internal.preferences.PreferenceInitializer"/>
-   </extension>
-   <extension
-         id="com.android.ide.eclipse.adt.adtProblem"
-         name="Android ADT Problem"
-         point="org.eclipse.core.resources.markers">
-      <super type="org.eclipse.core.resources.problemmarker"/>
-      <persistent value="true"/>
-   </extension>
-   <extension
-         id="com.android.ide.eclipse.adt.targetProblem"
-         name="Android Target Problem"
-         point="org.eclipse.core.resources.markers">
-      <super type="org.eclipse.core.resources.problemmarker"/>
-      <persistent value="false"/>
-   </extension>
-   <extension
-         point="org.eclipse.ui.perspectiveExtensions">
-      <perspectiveExtension targetID="org.eclipse.jdt.ui.JavaPerspective">
-         <newWizardShortcut id="com.android.ide.eclipse.adt.project.NewProjectWizard" />
-         <newWizardShortcut
-               id="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard">
-         </newWizardShortcut>
-      </perspectiveExtension>
-      <perspectiveExtension targetID="org.eclipse.debug.ui.DebugPerspective">
-         <viewShortcut id="com.android.ide.eclipse.ddms.views.LogCatView"/>
-         <viewShortcut id="com.android.ide.eclipse.ddms.views.DeviceView"/>
-      </perspectiveExtension>
-   </extension>
-   <extension
-         point="org.eclipse.ui.ide.projectNatureImages">
-      <image
-            icon="icons/android_project.png"
-            id="com.android.ide.eclipse.adt.AndroidNature.image"
-            natureId="com.android.ide.eclipse.adt.AndroidNature">
-      </image>
-   </extension>
-   <extension
-         point="org.eclipse.jdt.core.classpathContainerInitializer">
-      <classpathContainerInitializer
-            class="com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer"
-            id="com.android.ide.eclipse.adt.project.AndroidClasspathContainerInitializer">
-      </classpathContainerInitializer>
-      <classpathContainerInitializer
-            class="com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer"
-            id="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK">
-      </classpathContainerInitializer>
-   </extension>
-   <extension
-         point="org.eclipse.ui.exportWizards">
-      <category
-            id="com.android.ide.eclipse.wizards.category"
-            name="Android">
-      </category>
-      <wizard
-            category="com.android.ide.eclipse.wizards.category"
-            class="com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.adt.project.ExportWizard"
-            name="Export Android Application">
-      </wizard>
-   </extension>
-   <extension
-         point="org.eclipse.ui.commands">
-      <command
-            name="Debug Android Application"
-            description="Debug Android Application"
-            categoryId="org.eclipse.debug.ui.category.run"
-            id="com.android.ide.eclipse.adt.launch.LaunchShortcut.debug">
-      </command>
-      <command
-            name="Run Android Application"
-            description="Run Android Application"
-            categoryId="org.eclipse.debug.ui.category.run"
-            id="com.android.ide.eclipse.adt.launch.LaunchShortcut.run">
-      </command>
-      <keyBinding
-            keySequence="M3+M2+A D"
-            contextId="org.eclipse.ui.globalScope"
-            commandId="com.android.ide.eclipse.adt.launch.LaunchShortcut.debug"
-            keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </keyBinding>
-      <keyBinding
-            keySequence="M3+M2+A R"
-            contextId="org.eclipse.ui.globalScope"
-            commandId="com.android.ide.eclipse.adt.launch.LaunchShortcut.run"
-            keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </keyBinding>
-   </extension>
-   <extension
-         point="org.eclipse.ui.decorators">
-      <decorator
-            adaptable="true"
-            class="com.android.ide.eclipse.adt.internal.project.FolderDecorator"
-            id="com.android.ide.eclipse.adt.project.FolderDecorator"
-            label="Android Decorator"
-            lightweight="true"
-            location="TOP_RIGHT"
-            objectClass="org.eclipse.core.resources.IFolder"
-            state="true">
-      </decorator>
-   </extension>
-   <extension
-         point="org.eclipse.ui.editors">
-      <editor
-            class="com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor"
-            default="true"
-            filenames="AndroidManifest.xml"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.editors.manifest.ManifestEditor"
-            name="Android Manifest Editor">
-      </editor>
-      <editor
-            class="com.android.ide.eclipse.adt.internal.editors.resources.ResourcesEditor"
-            default="false"
-            extensions="xml"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.editors.resources.ResourcesEditor"
-            name="Android Resource Editor">
-      </editor>
-      <editor
-            class="com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor"
-            default="false"
-            extensions="xml"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.editors.layout.LayoutEditor"
-            matchingStrategy="com.android.ide.eclipse.adt.internal.editors.layout.MatchingStrategy"
-            name="Android Layout Editor">
-      </editor>
-      <editor
-            class="com.android.ide.eclipse.adt.internal.editors.menu.MenuEditor"
-            default="false"
-            extensions="xml"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.editors.menu.MenuEditor"
-            name="Android Menu Editor">
-      </editor>
-      <editor
-            class="com.android.ide.eclipse.adt.internal.editors.xml.XmlEditor"
-            default="false"
-            extensions="xml"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.editors.xml.XmlEditor"
-            name="Android Xml Resources Editor">
-      </editor>
-   </extension>
-   <extension
-         point="org.eclipse.ui.views">
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.adt.internal.ui.ResourceExplorerView"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.editors.resources.explorer.ResourceExplorerView"
-            name="Resource Explorer">
-      </view>
-   </extension>
-   <extension
-         point="org.eclipse.wst.sse.ui.editorConfiguration">
-      <sourceViewerConfiguration
-            class="com.android.ide.eclipse.adt.internal.editors.manifest.ManifestSourceViewerConfig"
-            target="com.android.ide.eclipse.editors.manifest.ManifestEditor">
-      </sourceViewerConfiguration>
-      <sourceViewerConfiguration
-            class="com.android.ide.eclipse.adt.internal.editors.resources.ResourcesSourceViewerConfig"
-            target="com.android.ide.eclipse.editors.resources.ResourcesEditor">
-      </sourceViewerConfiguration>
-      <sourceViewerConfiguration
-            class="com.android.ide.eclipse.adt.internal.editors.layout.LayoutSourceViewerConfig"
-            target="com.android.ide.eclipse.editors.layout.LayoutEditor">
-      </sourceViewerConfiguration>
-      <sourceViewerConfiguration
-            class="com.android.ide.eclipse.adt.internal.editors.menu.MenuSourceViewerConfig"
-            target="com.android.ide.eclipse.editors.menu.MenuEditor">
-      </sourceViewerConfiguration>
-      <sourceViewerConfiguration
-            class="com.android.ide.eclipse.adt.internal.editors.xml.XmlSourceViewerConfig"
-            target="com.android.ide.eclipse.editors.xml.XmlEditor">
-      </sourceViewerConfiguration>
-   </extension>
-   <extension
-         point="org.eclipse.ui.propertyPages">
-      <page
-            adaptable="true"
-            class="com.android.ide.eclipse.adt.internal.properties.AndroidPropertyPage"
-            id="com.android.ide.eclipse.adt.project.properties.AndroidPropertyPage"
-            name="Android"
-            nameFilter="*"
-            objectClass="org.eclipse.core.resources.IProject">
-         <enabledWhen>
-               <test property="org.eclipse.jdt.launching.hasProjectNature"
-                     args="com.android.ide.eclipse.adt.AndroidNature"/>
-         </enabledWhen>
-      </page>
-   </extension>
-   <extension
-         point="org.eclipse.ui.actionSets">
-      <actionSet
-            description="Android Wizards"
-            id="adt.actionSet.wizards"
-            label="Android Wizards"
-            visible="true">
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.NewXmlFileAction"
-               icon="icons/new_xml.png"
-               id="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
-               label="New Android XML File"
-               style="push"
-               toolbarPath="android_project"
-               tooltip="Opens a wizard to help create a new Android XML file">
-         </action>
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.NewTestProjectAction"
-               icon="icons/androidjunit.png"
-               id="com.android.ide.eclipse.adt.wizards.actions.NewTestProjectAction"
-               label="New Android Test Project"
-               style="push"
-               toolbarPath="android_project"
-               tooltip="Opens a wizard to help create a new Android Test Project">
-         </action>
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.NewProjectAction"
-               icon="icons/new_adt_project.png"
-               id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
-               label="New Android Project"
-               style="push"
-               toolbarPath="android_project"
-               tooltip="Opens a wizard to help create a new Android project">
-         </action>
-      </actionSet>
-      <actionSet
-            description="Refactorings for Android"
-            id="adt.actionSet.refactorings"
-            label="Android Refactorings"
-            visible="true">
-
-         <!-- This duplicates the Refactoring Menu definition from the jdt.ui plugin.xml,
-              which allows us to insert our contribution even if the JDT is not loaded.
-              We overload the definition with our new group.-->
-         <menu
-               label="Refactor"
-               path="edit"
-               id="org.eclipse.jdt.ui.refactoring.menu">
-            <separator name="undoRedoGroup"/>
-            <separator name="reorgGroup"/>
-            <separator name="androidGroup"/>
-            <separator name="codingGroup"/>
-            <separator name="reorgGroup2"/>
-            <separator name="typeGroup"/>
-            <separator name="typeGroup2"/>
-            <separator name="codingGroup2"/>
-            <separator name="typeGroup3"/>
-            <separator name="scriptGroup"/>
-         </menu>
-
-         <menu
-               label="Android"
-               path="org.eclipse.jdt.ui.refactoring.menu/androidGroup"
-               id="com.android.ide.eclipse.adt.refactoring.menu">
-              <separator name="android"/>
-         </menu>
-         <action
-               class="com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringAction"
-               definitionId="com.android.ide.eclipse.adt.refactoring.extract.string"
-               id="com.android.ide.eclipse.adt.actions.ExtractString"
-               label="Extract Android String..."
-               menubarPath="org.eclipse.jdt.ui.refactoring.menu/com.android.ide.eclipse.adt.refactoring.menu/android"
-               style="push"
-               tooltip="Extracts a string into Android resource string">
-         </action>
-         <menu
-               id="org.eclipse.jdt.ui.refactoring.menu"
-               label="Refactor">
-         </menu>
-      </actionSet>
-      <actionSet
-            description="Android AVD and SDK Manager"
-            id="adt.actionSet.avdManager"
-            label="Android SDK and AVD Manager"
-            visible="true">
-         <action
-               class="com.android.ide.eclipse.adt.internal.wizards.actions.AvdManagerAction"
-               icon="icons/avd_manager.png"
-               id="com.android.ide.eclipse.adt.ui.avdmanager"
-               label="Android SDK and AVD Manager"
-               menubarPath="Window/additions"
-               style="push"
-               toolbarPath="android_project"
-               tooltip="Opens the Android SDK and AVD Manager">
-         </action>
-      </actionSet>
-   </extension>
-   <extension
-         point="org.eclipse.debug.core.launchDelegates">
-       <launchDelegate
-             delegate="com.android.ide.eclipse.adt.internal.launch.JUnitLaunchConfigDelegate"
-             delegateDescription="Removes the Android JAR from the Bootstrap Classpath"
-             id="com.android.ide.eclipse.adt.launch.JUnitLaunchConfigDelegate.launchAndroidJunit"
-             modes="run,debug"
-             name="Android JUnit Test"
-             type="org.eclipse.jdt.junit.launchconfig">
-       </launchDelegate>
-   </extension>
-   <extension
-         point="org.eclipse.debug.core.launchConfigurationTypes">
-      <launchConfigurationType
-            delegate="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitLaunchConfigDelegate"
-            id="com.android.ide.eclipse.adt.junit.launchConfigurationType"
-            modes="run,debug"
-            name="Android JUnit Test"
-            public="true"
-            sourceLocatorId="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"
-            sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer">
-      </launchConfigurationType>
-   </extension>
-   <extension
-         point="org.eclipse.debug.ui.launchConfigurationTypeImages">
-      <launchConfigurationTypeImage
-            configTypeID="com.android.ide.eclipse.adt.junit.launchConfigurationType"
-            icon="icons/androidjunit.png"
-            id="com.android.ide.eclipse.adt.junit.launchConfigurationTypeImage">
-      </launchConfigurationTypeImage>
-   </extension>
-   <extension
-         point="org.eclipse.debug.ui.launchConfigurationTabGroups">
-      <launchConfigurationTabGroup
-            class="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitTabGroup"
-            description="Android JUnit Test"
-            id="com.android.ide.eclipse.adt.junit.AndroidJUnitLaunchConfigTabGroup"
-            type="com.android.ide.eclipse.adt.junit.launchConfigurationType"/>
-   </extension>
-   <extension
-         point="org.eclipse.debug.ui.launchShortcuts">
-      <shortcut
-            class="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitLaunchShortcut"
-            icon="icons/androidjunit.png"
-            id="com.android.ide.eclipse.adt.junit.launchShortcut"
-            label="Android JUnit Test"
-            modes="run,debug">
-          <contextualLaunch>
-            <enablement>
-               <with variable="selection">
-                  <count value="1"/>
-                  <iterate>
-                      <adapt type="org.eclipse.jdt.core.IJavaElement">
-                        <test property="org.eclipse.jdt.core.isInJavaProjectWithNature" value="com.android.ide.eclipse.adt.AndroidNature"/>
-                        <test property="org.eclipse.jdt.core.hasTypeOnClasspath" value="junit.framework.Test"/>
-                        <test property="com.android.ide.eclipse.adt.canLaunchAsJUnit"/>
-                     </adapt>
-                  </iterate>
-               </with>
-            </enablement>
-         </contextualLaunch>
-         <configurationType
-             id="com.android.ide.eclipse.adt.junit.launchConfigurationType">
-         </configurationType>
-      </shortcut>
-   </extension>
-   <extension
-         point="org.eclipse.ui.commands">
-      <category
-            description="Refactorings for Android Projects"
-            id="com.android.ide.eclipse.adt.refactoring.category"
-            name="Android Refactorings">
-      </category>
-      <command
-            categoryId="com.android.ide.eclipse.adt.refactoring.category"
-            description="Extract Strings into Android String Resources"
-            id="com.android.ide.eclipse.adt.refactoring.extract.string"
-            name="Extract Android String">
-      </command>
-      <keyBinding
-            commandId="com.android.ide.eclipse.adt.refactoring.extract.string"
-            contextId="org.eclipse.ui.globalScope"
-            keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration"
-            keySequence="M3+M2+A S">
-      </keyBinding>
-   </extension>
-   <extension
-         point="org.eclipse.ltk.core.refactoring.refactoringContributions">
-      <contribution
-            class="com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringContribution"
-            id="com.android.ide.eclipse.adt.refactoring.extract.string">
-      </contribution>
-   </extension>
-    <extension
-         point="org.eclipse.core.expressions.propertyTesters">
-      <propertyTester
-            properties="isTest,canLaunchAsJUnit"
-            namespace="com.android.ide.eclipse.adt"
-            type="org.eclipse.core.runtime.IAdaptable"
-            class="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitPropertyTester"
-            id="com.android.ide.eclipse.adt.AndroidJUnitPropertyTester">
-      </propertyTester>
-   </extension>
-</plugin>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
deleted file mode 100644
index d3175ce..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt;
-
-import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
-
-
-/**
- * Constant definition class.<br>
- * <br>
- * Most constants have a prefix defining the content.
- * <ul>
- * <li><code>WS_</code> Workspace path constant. Those are absolute paths,
- * from the project root.</li>
- * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
- * <li><code>FN_</code> File name constant.</li>
- * <li><code>FD_</code> Folder name constant.</li>
- * <li><code>MARKER_</code> Resource Marker Ids constant.</li>
- * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
- * <li><code>DOT_</code> File extension constant. This start with a dot.</li>
- * <li><code>RE_</code> Regexp constant.</li>
- * <li><code>BUILD_</code> Build verbosity level constant. To use with
- * <code>AdtPlugin.printBuildToConsole()</code></li>
- * </ul>
- */
-public class AdtConstants {
-    /** Generic marker for ADT errors. */
-    public final static String MARKER_ADT = AdtPlugin.PLUGIN_ID + ".adtProblem"; //$NON-NLS-1$
-
-    /** Marker for Android Target errors.
-     * This is not cleared on each like other markers. Instead, it's cleared
-     * when an {@link AndroidClasspathContainerInitializer} has succeeded in creating an
-     * AndroidClasspathContainer */
-    public final static String MARKER_TARGET = AdtPlugin.PLUGIN_ID + ".targetProblem"; //$NON-NLS-1$
-
-    /** Build verbosity "Always". Those messages are always displayed. */
-    public final static int BUILD_ALWAYS = 0;
-
-    /** Build verbosity level "Normal" */
-    public final static int BUILD_NORMAL = 1;
-
-    /** Build verbosity level "Verbose". Those messages are only displayed in verbose mode */
-    public final static int BUILD_VERBOSE = 2;
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
deleted file mode 100644
index 5d8b6c2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
+++ /dev/null
@@ -1,1448 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt;
-
-import com.android.ddmuilib.StackTracePanel;
-import com.android.ddmuilib.StackTracePanel.ISourceRevealer;
-import com.android.ddmuilib.console.DdmConsole;
-import com.android.ddmuilib.console.IDdmConsole;
-import com.android.ide.eclipse.adt.internal.VersionCheck;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
-import com.android.ide.eclipse.adt.internal.editors.menu.MenuEditor;
-import com.android.ide.eclipse.adt.internal.editors.resources.ResourcesEditor;
-import com.android.ide.eclipse.adt.internal.editors.xml.XmlEditor;
-import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchController;
-import com.android.ide.eclipse.adt.internal.preferences.BuildPreferencePage;
-import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ExportHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ExportHelper.IExportCallback;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
-import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.internal.ui.EclipseUiHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.ImageLoader;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdkstats.SdkStatsService;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Preferences;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
-import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IEditorDescriptor;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.console.ConsolePlugin;
-import org.eclipse.ui.console.IConsole;
-import org.eclipse.ui.console.IConsoleConstants;
-import org.eclipse.ui.console.MessageConsole;
-import org.eclipse.ui.console.MessageConsoleStream;
-import org.eclipse.ui.ide.IDE;
-import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.List;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public class AdtPlugin extends AbstractUIPlugin {
-    /** The plug-in ID */
-    public static final String PLUGIN_ID = "com.android.ide.eclipse.adt"; //$NON-NLS-1$
-
-    public final static String PREFS_SDK_DIR = PLUGIN_ID + ".sdk"; //$NON-NLS-1$
-
-    public final static String PREFS_RES_AUTO_REFRESH = PLUGIN_ID + ".resAutoRefresh"; //$NON-NLS-1$
-
-    public final static String PREFS_BUILD_VERBOSITY = PLUGIN_ID + ".buildVerbosity"; //$NON-NLS-1$
-
-    public final static String PREFS_DEFAULT_DEBUG_KEYSTORE = PLUGIN_ID + ".defaultDebugKeyStore"; //$NON-NLS-1$
-
-    public final static String PREFS_CUSTOM_DEBUG_KEYSTORE = PLUGIN_ID + ".customDebugKeyStore"; //$NON-NLS-1$
-
-    public final static String PREFS_HOME_PACKAGE = PLUGIN_ID + ".homePackage"; //$NON-NLS-1$
-
-    public final static String PREFS_EMU_OPTIONS = PLUGIN_ID + ".emuOptions"; //$NON-NLS-1$
-
-    /** singleton instance */
-    private static AdtPlugin sPlugin;
-
-    private static Image sAndroidLogo;
-    private static ImageDescriptor sAndroidLogoDesc;
-
-    /** default store, provided by eclipse */
-    private IPreferenceStore mStore;
-
-    /** cached location for the sdk folder */
-    private String mOsSdkLocation;
-
-    /** The global android console */
-    private MessageConsole mAndroidConsole;
-
-    /** Stream to write in the android console */
-    private MessageConsoleStream mAndroidConsoleStream;
-
-    /** Stream to write error messages to the android console */
-    private MessageConsoleStream mAndroidConsoleErrorStream;
-
-    /** Image loader object */
-    private ImageLoader mLoader;
-
-    /** Verbosity of the build */
-    private int mBuildVerbosity = AdtConstants.BUILD_NORMAL;
-
-    /** Color used in the error console */
-    private Color mRed;
-
-    /** Load status of the SDK. Any access MUST be in a synchronized(mPostLoadProjects) block */
-    private LoadStatus mSdkIsLoaded = LoadStatus.LOADING;
-    /** Project to update once the SDK is loaded.
-     * Any access MUST be in a synchronized(mPostLoadProjectsToResolve) block */
-    private final ArrayList<IJavaProject> mPostLoadProjectsToResolve =
-            new ArrayList<IJavaProject>();
-    /** Project to check validity of cache vs actual once the SDK is loaded.
-     * Any access MUST be in a synchronized(mPostLoadProjectsToResolve) block */
-    private final ArrayList<IJavaProject> mPostLoadProjectsToCheck = new ArrayList<IJavaProject>();
-
-    private ResourceMonitor mResourceMonitor;
-    private ArrayList<ITargetChangeListener> mTargetChangeListeners =
-            new ArrayList<ITargetChangeListener>();
-
-    protected boolean mSdkIsLoading;
-
-    /**
-     * Custom PrintStream for Dx output. This class overrides the method
-     * <code>println()</code> and adds the standard output tag with the
-     * date and the project name in front of every messages.
-     */
-    private static final class AndroidPrintStream extends PrintStream {
-        private IProject mProject;
-        private String mPrefix;
-
-        /**
-         * Default constructor with project and output stream.
-         * The project is used to get the project name for the output tag.
-         *
-         * @param project The Project
-         * @param prefix A prefix to be printed before the actual message. Can be null
-         * @param stream The Stream
-         */
-        public AndroidPrintStream(IProject project, String prefix, OutputStream stream) {
-            super(stream);
-            mProject = project;
-        }
-
-        @Override
-        public void println(String message) {
-            // write the date/project tag first.
-            String tag = getMessageTag(mProject != null ? mProject.getName() : null);
-
-            print(tag);
-            if (mPrefix != null) {
-                print(mPrefix);
-            }
-
-            // then write the regular message
-            super.println(message);
-        }
-    }
-
-    /**
-     * An error handler for checkSdkLocationAndId() that will handle the generated error
-     * or warning message. Each method must return a boolean that will in turn be returned by
-     * checkSdkLocationAndId.
-     */
-    public static abstract class CheckSdkErrorHandler {
-        /** Handle an error message during sdk location check. Returns whatever
-         * checkSdkLocationAndId() should returns.
-         */
-        public abstract boolean handleError(String message);
-
-        /** Handle a warning message during sdk location check. Returns whatever
-         * checkSdkLocationAndId() should returns.
-         */
-        public abstract boolean handleWarning(String message);
-    }
-
-    /**
-     * The constructor
-     */
-    public AdtPlugin() {
-        sPlugin = this;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-     */
-    @SuppressWarnings("deprecation")
-    @Override
-    public void start(BundleContext context) throws Exception {
-        super.start(context);
-
-        Display display = getDisplay();
-
-        // set the default android console.
-        mAndroidConsole = new MessageConsole("Android", null); //$NON-NLS-1$
-        ConsolePlugin.getDefault().getConsoleManager().addConsoles(
-                new IConsole[] { mAndroidConsole });
-
-        // get the stream to write in the android console.
-        mAndroidConsoleStream = mAndroidConsole.newMessageStream();
-        mAndroidConsoleErrorStream = mAndroidConsole.newMessageStream();
-        mRed = new Color(display, 0xFF, 0x00, 0x00);
-
-        // because this can be run, in some cases, by a non ui thread, and beccause
-        // changing the console properties update the ui, we need to make this change
-        // in the ui thread.
-        display.asyncExec(new Runnable() {
-            public void run() {
-                mAndroidConsoleErrorStream.setColor(mRed);
-            }
-        });
-
-        // set up the ddms console to use this objects
-        DdmConsole.setConsole(new IDdmConsole() {
-            public void printErrorToConsole(String message) {
-                AdtPlugin.printErrorToConsole((String)null, message);
-            }
-            public void printErrorToConsole(String[] messages) {
-                AdtPlugin.printErrorToConsole((String)null, (Object[])messages);
-            }
-            public void printToConsole(String message) {
-                AdtPlugin.printToConsole((String)null, message);
-            }
-            public void printToConsole(String[] messages) {
-                AdtPlugin.printToConsole((String)null, (Object[])messages);
-            }
-        });
-
-        // get the eclipse store
-        mStore = getPreferenceStore();
-
-        // set the listener for the preference change
-        Preferences prefs = getPluginPreferences();
-        prefs.addPropertyChangeListener(new IPropertyChangeListener() {
-            public void propertyChange(PropertyChangeEvent event) {
-                // get the name of the property that changed.
-                String property = event.getProperty();
-
-                // if the SDK changed, we update the cached version
-                if (PREFS_SDK_DIR.equals(property)) {
-
-                    // get the new one from the preferences
-                    mOsSdkLocation = (String)event.getNewValue();
-
-                    // make sure it ends with a separator
-                    if (mOsSdkLocation.endsWith(File.separator) == false) {
-                        mOsSdkLocation = mOsSdkLocation + File.separator;
-                    }
-
-                    // finally restart adb, in case it's a different version
-                    DdmsPlugin.setAdb(getOsAbsoluteAdb(), true /* startAdb */);
-
-                    // get the SDK location and build id.
-                    if (checkSdkLocationAndId()) {
-                        // if sdk if valid, reparse it
-
-                        reparseSdk();
-                    }
-                } else if (PREFS_BUILD_VERBOSITY.equals(property)) {
-                    mBuildVerbosity = BuildPreferencePage.getBuildLevel(
-                            mStore.getString(PREFS_BUILD_VERBOSITY));
-                }
-            }
-        });
-
-        mOsSdkLocation = mStore.getString(PREFS_SDK_DIR);
-
-        // make sure it ends with a separator. Normally this is done when the preference
-        // is set. But to make sure older version still work, we fix it here as well.
-        if (mOsSdkLocation.length() > 0 && mOsSdkLocation.endsWith(File.separator) == false) {
-            mOsSdkLocation = mOsSdkLocation + File.separator;
-        }
-
-        // check the location of SDK
-        final boolean isSdkLocationValid = checkSdkLocationAndId();
-
-        mBuildVerbosity = BuildPreferencePage.getBuildLevel(
-                mStore.getString(PREFS_BUILD_VERBOSITY));
-
-        // create the loader that's able to load the images
-        mLoader = new ImageLoader(this);
-
-        // start the DdmsPlugin by setting the adb location, only if it is set already.
-        if (mOsSdkLocation.length() > 0) {
-            DdmsPlugin.setAdb(getOsAbsoluteAdb(), true);
-        }
-
-        // and give it the debug launcher for android projects
-        DdmsPlugin.setRunningAppDebugLauncher(new DdmsPlugin.IDebugLauncher() {
-            public boolean debug(String appName, int port) {
-                // search for an android project matching the process name
-                IProject project = ProjectHelper.findAndroidProjectByAppName(appName);
-                if (project != null) {
-                    AndroidLaunchController.debugRunningApp(project, port);
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-        });
-
-        StackTracePanel.setSourceRevealer(new ISourceRevealer() {
-            public void reveal(String applicationName, String className, int line) {
-                IProject project = ProjectHelper.findAndroidProjectByAppName(applicationName);
-                if (project != null) {
-                    BaseProjectHelper.revealSource(project, className, line);
-                }
-            }
-        });
-
-        // setup export callback for editors
-        ExportHelper.setCallback(new IExportCallback() {
-            public void startExportWizard(IProject project) {
-                StructuredSelection selection = new StructuredSelection(project);
-
-                ExportWizard wizard = new ExportWizard();
-                wizard.init(PlatformUI.getWorkbench(), selection);
-                WizardDialog dialog = new WizardDialog(getDisplay().getActiveShell(),
-                        wizard);
-                dialog.open();
-            }
-        });
-
-        // initialize editors
-        startEditors();
-
-        // Ping the usage server and parse the SDK content.
-        // This is deferred in separate jobs to avoid blocking the bundle start.
-        // We also serialize them to avoid too many parallel jobs when Eclipse starts.
-        Job pingJob = createPingUsageServerJob();
-        pingJob.addJobChangeListener(new JobChangeAdapter() {
-           @Override
-            public void done(IJobChangeEvent event) {
-                super.done(event);
-
-                // Once the ping job is finished, start the SDK parser
-                if (isSdkLocationValid) {
-                    // parse the SDK resources.
-                    parseSdkContent();
-                }
-            }
-        });
-        // build jobs are run after other interactive jobs
-        pingJob.setPriority(Job.BUILD);
-        // Wait 2 seconds before starting the ping job. This leaves some time to the
-        // other bundles to initialize.
-        pingJob.schedule(2000 /*milliseconds*/);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-     */
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        super.stop(context);
-
-        stopEditors();
-
-        mRed.dispose();
-        synchronized (AdtPlugin.class) {
-            sPlugin = null;
-        }
-    }
-
-    /** Return the image loader for the plugin */
-    public static synchronized ImageLoader getImageLoader() {
-        if (sPlugin != null) {
-            return sPlugin.mLoader;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the shared instance
-     *
-     * @return the shared instance
-     */
-    public static synchronized AdtPlugin getDefault() {
-        return sPlugin;
-    }
-
-    public static Display getDisplay() {
-        IWorkbench bench = null;
-        synchronized (AdtPlugin.class) {
-            bench = sPlugin.getWorkbench();
-        }
-
-        if (bench != null) {
-            return bench.getDisplay();
-        }
-        return null;
-    }
-
-    /** Returns the adb path relative to the sdk folder */
-    public static String getOsRelativeAdb() {
-        return SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_ADB;
-    }
-
-    /** Returns the zipalign path relative to the sdk folder */
-    public static String getOsRelativeZipAlign() {
-        return SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_ZIPALIGN;
-    }
-
-    /** Returns the emulator path relative to the sdk folder */
-    public static String getOsRelativeEmulator() {
-        return SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_EMULATOR;
-    }
-
-    /** Returns the absolute adb path */
-    public static String getOsAbsoluteAdb() {
-        return getOsSdkFolder() + getOsRelativeAdb();
-    }
-
-    /** Returns the absolute zipalign path */
-    public static String getOsAbsoluteZipAlign() {
-        return getOsSdkFolder() + getOsRelativeZipAlign();
-    }
-
-    /** Returns the absolute traceview path */
-    public static String getOsAbsoluteTraceview() {
-        return getOsSdkFolder() + SdkConstants.OS_SDK_TOOLS_FOLDER +
-                AndroidConstants.FN_TRACEVIEW;
-    }
-
-    /** Returns the absolute emulator path */
-    public static String getOsAbsoluteEmulator() {
-        return getOsSdkFolder() + getOsRelativeEmulator();
-    }
-
-    /**
-     * Returns a Url file path to the javaDoc folder.
-     */
-    public static String getUrlDoc() {
-        return ProjectHelper.getJavaDocPath(
-                getOsSdkFolder() + AndroidConstants.WS_JAVADOC_FOLDER_LEAF);
-    }
-
-    /**
-     * Returns the SDK folder.
-     * Guaranteed to be terminated by a platform-specific path separator.
-     */
-    public static synchronized String getOsSdkFolder() {
-        if (sPlugin == null) {
-            return null;
-        }
-
-        if (sPlugin.mOsSdkLocation == null) {
-            sPlugin.mOsSdkLocation = sPlugin.mStore.getString(PREFS_SDK_DIR);
-        }
-        return sPlugin.mOsSdkLocation;
-    }
-
-    public static String getOsSdkToolsFolder() {
-        return getOsSdkFolder() + SdkConstants.OS_SDK_TOOLS_FOLDER;
-    }
-
-    public static synchronized boolean getAutoResRefresh() {
-        if (sPlugin == null) {
-            return false;
-        }
-        return sPlugin.mStore.getBoolean(PREFS_RES_AUTO_REFRESH);
-    }
-
-    public static synchronized int getBuildVerbosity() {
-        if (sPlugin != null) {
-            return sPlugin.mBuildVerbosity;
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns an image descriptor for the image file at the given
-     * plug-in relative path
-     *
-     * @param path the path
-     * @return the image descriptor
-     */
-    public static ImageDescriptor getImageDescriptor(String path) {
-        return imageDescriptorFromPlugin(PLUGIN_ID, path);
-    }
-
-    /**
-     * Reads and returns the content of a text file embedded in the plugin jar
-     * file.
-     * @param filepath the file path to the text file
-     * @return null if the file could not be read
-     */
-    public static String readEmbeddedTextFile(String filepath) {
-        Bundle bundle = null;
-        synchronized (AdtPlugin.class) {
-            if (sPlugin != null) {
-                bundle = sPlugin.getBundle();
-            } else {
-                return null;
-            }
-        }
-
-        // attempt to get a file to one of the template.
-        try {
-            URL url = bundle.getEntry(AndroidConstants.WS_SEP + filepath);
-            if (url != null) {
-                BufferedReader reader = new BufferedReader(
-                        new InputStreamReader(url.openStream()));
-
-                String line;
-                StringBuilder total = new StringBuilder(reader.readLine());
-                while ((line = reader.readLine()) != null) {
-                    total.append('\n');
-                    total.append(line);
-                }
-
-                return total.toString();
-            }
-        } catch (MalformedURLException e) {
-            // we'll just return null.
-        } catch (IOException e) {
-            // we'll just return null.
-        }
-
-        return null;
-    }
-
-    /**
-     * Reads and returns the content of a binary file embedded in the plugin jar
-     * file.
-     * @param filepath the file path to the text file
-     * @return null if the file could not be read
-     */
-    public static byte[] readEmbeddedFile(String filepath) {
-        Bundle bundle = null;
-        synchronized (AdtPlugin.class) {
-            if (sPlugin != null) {
-                bundle = sPlugin.getBundle();
-            } else {
-                return null;
-            }
-        }
-
-        // attempt to get a file to one of the template.
-        try {
-            URL url = bundle.getEntry(AndroidConstants.WS_SEP + filepath);
-            if (url != null) {
-                // create a buffered reader to facilitate reading.
-                BufferedInputStream stream = new BufferedInputStream(
-                        url.openStream());
-
-                // get the size to read.
-                int avail = stream.available();
-
-                // create the buffer and reads it.
-                byte[] buffer = new byte[avail];
-                stream.read(buffer);
-
-                // and return.
-                return buffer;
-            }
-        } catch (MalformedURLException e) {
-            // we'll just return null.
-        } catch (IOException e) {
-            // we'll just return null;.
-        }
-
-        return null;
-    }
-
-    /**
-     * Displays an error dialog box. This dialog box is ran asynchronously in the ui thread,
-     * therefore this method can be called from any thread.
-     * @param title The title of the dialog box
-     * @param message The error message
-     */
-    public final static void displayError(final String title, final String message) {
-        // get the current Display
-        final Display display = getDisplay();
-
-        // dialog box only run in ui thread..
-        display.asyncExec(new Runnable() {
-            public void run() {
-                Shell shell = display.getActiveShell();
-                MessageDialog.openError(shell, title, message);
-            }
-        });
-    }
-
-    /**
-     * Displays a warning dialog box. This dialog box is ran asynchronously in the ui thread,
-     * therefore this method can be called from any thread.
-     * @param title The title of the dialog box
-     * @param message The warning message
-     */
-    public final static void displayWarning(final String title, final String message) {
-        // get the current Display
-        final Display display = getDisplay();
-
-        // dialog box only run in ui thread..
-        display.asyncExec(new Runnable() {
-            public void run() {
-                Shell shell = display.getActiveShell();
-                MessageDialog.openWarning(shell, title, message);
-            }
-        });
-    }
-
-    /**
-     * Display a yes/no question dialog box. This dialog is opened synchronously in the ui thread,
-     * therefore this message can be called from any thread.
-     * @param title The title of the dialog box
-     * @param message The error message
-     * @return true if OK was clicked.
-     */
-    public final static boolean displayPrompt(final String title, final String message) {
-        // get the current Display and Shell
-        final Display display = getDisplay();
-
-        // we need to ask the user what he wants to do.
-        final boolean[] result = new boolean[1];
-        display.syncExec(new Runnable() {
-            public void run() {
-                Shell shell = display.getActiveShell();
-                result[0] = MessageDialog.openQuestion(shell, title, message);
-            }
-        });
-        return result[0];
-    }
-
-    /**
-     * Logs a message to the default Eclipse log.
-     *
-     * @param severity The severity code. Valid values are: {@link IStatus#OK},
-     * {@link IStatus#ERROR}, {@link IStatus#INFO}, {@link IStatus#WARNING} or
-     * {@link IStatus#CANCEL}.
-     * @param format The format string, like for {@link String#format(String, Object...)}.
-     * @param args The arguments for the format string, like for
-     * {@link String#format(String, Object...)}.
-     */
-    public static void log(int severity, String format, Object ... args) {
-        String message = String.format(format, args);
-        Status status = new Status(severity, PLUGIN_ID, message);
-        getDefault().getLog().log(status);
-    }
-
-    /**
-     * Logs an exception to the default Eclipse log.
-     * <p/>
-     * The status severity is always set to ERROR.
-     *
-     * @param exception the exception to log.
-     * @param format The format string, like for {@link String#format(String, Object...)}.
-     * @param args The arguments for the format string, like for
-     * {@link String#format(String, Object...)}.
-     */
-    public static void log(Throwable exception, String format, Object ... args) {
-        String message = String.format(format, args);
-        Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
-        getDefault().getLog().log(status);
-    }
-
-    /**
-     * This is a mix between log(Throwable) and printErrorToConsole.
-     * <p/>
-     * This logs the exception with an ERROR severity and the given printf-like format message.
-     * The same message is then printed on the Android error console with the associated tag.
-     *
-     * @param exception the exception to log.
-     * @param format The format string, like for {@link String#format(String, Object...)}.
-     * @param args The arguments for the format string, like for
-     * {@link String#format(String, Object...)}.
-     */
-    public static synchronized void logAndPrintError(Throwable exception, String tag,
-            String format, Object ... args) {
-        if (sPlugin != null) {
-            String message = String.format(format, args);
-            Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
-            getDefault().getLog().log(status);
-            printToStream(sPlugin.mAndroidConsoleErrorStream, tag, message);
-            showAndroidConsole();
-        }
-    }
-
-    /**
-     * Prints one or more error message to the android console.
-     * @param tag A tag to be associated with the message. Can be null.
-     * @param objects the objects to print through their <code>toString</code> method.
-     */
-    public static synchronized void printErrorToConsole(String tag, Object... objects) {
-        if (sPlugin != null) {
-            printToStream(sPlugin.mAndroidConsoleErrorStream, tag, objects);
-
-            showAndroidConsole();
-        }
-    }
-
-    /**
-     * Prints one or more error message to the android console.
-     * @param objects the objects to print through their <code>toString</code> method.
-     */
-    public static void printErrorToConsole(Object... objects) {
-        printErrorToConsole((String)null, objects);
-    }
-
-    /**
-     * Prints one or more error message to the android console.
-     * @param project The project to which the message is associated. Can be null.
-     * @param objects the objects to print through their <code>toString</code> method.
-     */
-    public static void printErrorToConsole(IProject project, Object... objects) {
-        String tag = project != null ? project.getName() : null;
-        printErrorToConsole(tag, objects);
-    }
-
-    /**
-     * Prints one or more build messages to the android console, filtered by Build output verbosity.
-     * @param level Verbosity level of the message.
-     * @param project The project to which the message is associated. Can be null.
-     * @param objects the objects to print through their <code>toString</code> method.
-     * @see AdtConstants#BUILD_ALWAYS
-     * @see AdtConstants#BUILD_NORMAL
-     * @see AdtConstants#BUILD_VERBOSE
-     */
-    public static synchronized void printBuildToConsole(int level, IProject project,
-            Object... objects) {
-        if (sPlugin != null) {
-            if (level <= sPlugin.mBuildVerbosity) {
-                String tag = project != null ? project.getName() : null;
-                printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
-            }
-        }
-    }
-
-    /**
-     * Prints one or more message to the android console.
-     * @param tag The tag to be associated with the message. Can be null.
-     * @param objects the objects to print through their <code>toString</code> method.
-     */
-    public static synchronized void printToConsole(String tag, Object... objects) {
-        if (sPlugin != null) {
-            printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
-        }
-    }
-
-    /**
-     * Prints one or more message to the android console.
-     * @param project The project to which the message is associated. Can be null.
-     * @param objects the objects to print through their <code>toString</code> method.
-     */
-    public static void printToConsole(IProject project, Object... objects) {
-        String tag = project != null ? project.getName() : null;
-        printToConsole(tag, objects);
-    }
-
-    /** Force the display of the android console */
-    public static void showAndroidConsole() {
-        // first make sure the console is in the workbench
-        EclipseUiHelper.showView(IConsoleConstants.ID_CONSOLE_VIEW, true);
-
-        // now make sure it's not docked.
-        ConsolePlugin.getDefault().getConsoleManager().showConsoleView(
-                AdtPlugin.getDefault().getAndroidConsole());
-    }
-
-    /**
-     * Returns an standard PrintStream object for a specific project.<br>
-     * This PrintStream will add a date/project at the beginning of every
-     * <code>println()</code> output.
-     *
-     * @param project The project object
-     * @param prefix The prefix to be added to the message. Can be null.
-     * @return a new PrintStream
-     */
-    public static synchronized PrintStream getOutPrintStream(IProject project, String prefix) {
-        if (sPlugin != null) {
-            return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleStream);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns an error PrintStream object for a specific project.<br>
-     * This PrintStream will add a date/project at the beginning of every
-     * <code>println()</code> output.
-     *
-     * @param project The project object
-     * @param prefix The prefix to be added to the message. Can be null.
-     * @return a new PrintStream
-     */
-    public static synchronized PrintStream getErrPrintStream(IProject project, String prefix) {
-        if (sPlugin != null) {
-            return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleErrorStream);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns whether the Sdk has been loaded.
-     */
-    public final LoadStatus getSdkLoadStatus() {
-        synchronized (getSdkLockObject()) {
-            return mSdkIsLoaded;
-        }
-    }
-
-    /**
-     * Returns the lock object for SDK loading. If you wish to do things while the SDK is loading,
-     * you must synchronize on this object.
-     */
-    public final Object getSdkLockObject() {
-        return mPostLoadProjectsToResolve;
-    }
-
-    /**
-     * Sets the given {@link IJavaProject} to have its target resolved again once the SDK finishes
-     * to load.
-     */
-    public final void setProjectToResolve(IJavaProject javaProject) {
-        synchronized (getSdkLockObject()) {
-            mPostLoadProjectsToResolve.add(javaProject);
-        }
-    }
-
-    /**
-     * Sets the given {@link IJavaProject} to have its target checked for consistency
-     * once the SDK finishes to load. This is used if the target is resolved using cached
-     * information while the SDK is loading.
-     */
-    public final void setProjectToCheck(IJavaProject javaProject) {
-        // only lock on
-        synchronized (getSdkLockObject()) {
-            mPostLoadProjectsToCheck.add(javaProject);
-        }
-    }
-
-    /**
-     * Checks the location of the SDK is valid and if it is, grab the SDK API version
-     * from the SDK.
-     * @return false if the location is not correct.
-     */
-    private boolean checkSdkLocationAndId() {
-        if (mOsSdkLocation == null || mOsSdkLocation.length() == 0) {
-            displayError(Messages.Dialog_Title_SDK_Location, Messages.SDK_Not_Setup);
-            return false;
-        }
-
-        return checkSdkLocationAndId(mOsSdkLocation, new CheckSdkErrorHandler() {
-            @Override
-            public boolean handleError(String message) {
-                AdtPlugin.displayError(Messages.Dialog_Title_SDK_Location,
-                        String.format(Messages.Error_Check_Prefs, message));
-                return false;
-            }
-
-            @Override
-            public boolean handleWarning(String message) {
-                AdtPlugin.displayWarning(Messages.Dialog_Title_SDK_Location, message);
-                return true;
-            }
-        });
-    }
-
-    /**
-     * Internal helper to perform the actual sdk location and id check.
-     *
-     * @param osSdkLocation The sdk directory, an OS path.
-     * @param errorHandler An checkSdkErrorHandler that can display a warning or an error.
-     * @return False if there was an error or the result from the errorHandler invocation.
-     */
-    public boolean checkSdkLocationAndId(String osSdkLocation, CheckSdkErrorHandler errorHandler) {
-        if (osSdkLocation.endsWith(File.separator) == false) {
-            osSdkLocation = osSdkLocation + File.separator;
-        }
-
-        File osSdkFolder = new File(osSdkLocation);
-        if (osSdkFolder.isDirectory() == false) {
-            return errorHandler.handleError(
-                    String.format(Messages.Could_Not_Find_Folder, osSdkLocation));
-        }
-
-        String osTools = osSdkLocation + SdkConstants.OS_SDK_TOOLS_FOLDER;
-        File toolsFolder = new File(osTools);
-        if (toolsFolder.isDirectory() == false) {
-            return errorHandler.handleError(
-                    String.format(Messages.Could_Not_Find_Folder_In_SDK,
-                            SdkConstants.FD_TOOLS, osSdkLocation));
-        }
-
-        // check the path to various tools we use
-        String[] filesToCheck = new String[] {
-                osSdkLocation + getOsRelativeAdb(),
-                osSdkLocation + getOsRelativeEmulator()
-        };
-        for (String file : filesToCheck) {
-            if (checkFile(file) == false) {
-                return errorHandler.handleError(String.format(Messages.Could_Not_Find, file));
-            }
-        }
-
-        // check the SDK build id/version and the plugin version.
-        return VersionCheck.checkVersion(osSdkLocation, errorHandler);
-    }
-
-    /**
-     * Checks if a path reference a valid existing file.
-     * @param osPath the os path to check.
-     * @return true if the file exists and is, in fact, a file.
-     */
-    private boolean checkFile(String osPath) {
-        File file = new File(osPath);
-        if (file.isFile() == false) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Creates a job than can ping the usage server.
-     */
-    private Job createPingUsageServerJob() {
-        // In order to not block the plugin loading, so we spawn another thread.
-        Job job = new Job("Android SDK Ping") {  // Job name, visible in progress view
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                try {
-                    pingUsageServer(); //$NON-NLS-1$
-
-                    return Status.OK_STATUS;
-                } catch (Throwable t) {
-                    log(t, "pingUsageServer failed");       //$NON-NLS-1$
-                    return new Status(IStatus.ERROR, PLUGIN_ID,
-                            "pingUsageServer failed", t);    //$NON-NLS-1$
-                }
-            }
-        };
-        return job;
-    }
-
-    /**
-     * Parses the SDK resources.
-     */
-    private void parseSdkContent() {
-        // Perform the update in a thread (here an Eclipse runtime job)
-        // since this should never block the caller (especially the start method)
-        Job job = new Job(Messages.AdtPlugin_Android_SDK_Content_Loader) {
-            @SuppressWarnings("unchecked")
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                try {
-
-                    if (mSdkIsLoading) {
-                        return new Status(IStatus.WARNING, PLUGIN_ID,
-                                "An Android SDK is already being loaded. Please try again later.");
-                    }
-
-                    mSdkIsLoading = true;
-
-                    SubMonitor progress = SubMonitor.convert(monitor,
-                            "Initialize SDK Manager", 100);
-
-                    Sdk sdk = Sdk.loadSdk(mOsSdkLocation);
-
-                    if (sdk != null) {
-
-                        progress.setTaskName(Messages.AdtPlugin_Parsing_Resources);
-
-                        final IAndroidTarget[] targets = sdk.getTargets();
-                        final int n = targets.length;
-                        if (n > 0) {
-                            // load the rest of the targets.
-                            // TODO: make this on-demand.
-                            int w = 60 / n;
-                            for (IAndroidTarget target : targets) {
-                                SubMonitor p2 = progress.newChild(w);
-                                IStatus status = new AndroidTargetParser(target).run(p2);
-                                if (status.getCode() != IStatus.OK) {
-                                    synchronized (getSdkLockObject()) {
-                                        mSdkIsLoaded = LoadStatus.FAILED;
-                                        mPostLoadProjectsToResolve.clear();
-                                    }
-                                    return status;
-                                }
-                            }
-                        }
-
-                        ArrayList<IJavaProject> list = new ArrayList<IJavaProject>();
-                        synchronized (getSdkLockObject()) {
-                            mSdkIsLoaded = LoadStatus.LOADED;
-
-                            progress.setTaskName("Check Projects");
-
-                            for (IJavaProject javaProject : mPostLoadProjectsToResolve) {
-                                if (javaProject.getProject().isOpen()) {
-                                    list.add(javaProject);
-                                }
-                            }
-
-                            // done with this list.
-                            mPostLoadProjectsToResolve.clear();
-                        }
-
-                        // check the projects that need checking.
-                        // The method modifies the list (it removes the project that
-                        // do not need to be resolved again).
-                        AndroidClasspathContainerInitializer.checkProjectsCache(
-                                mPostLoadProjectsToCheck);
-
-                        list.addAll(mPostLoadProjectsToCheck);
-
-                        // update the project that needs recompiling.
-                        if (list.size() > 0) {
-                            IJavaProject[] array = list.toArray(
-                                    new IJavaProject[list.size()]);
-                            AndroidClasspathContainerInitializer.updateProjects(array);
-                        }
-
-                        progress.worked(10);
-                    }
-
-                    // Notify resource changed listeners
-                    progress.setTaskName("Refresh UI");
-                    progress.setWorkRemaining(mTargetChangeListeners.size());
-
-                    // Clone the list before iterating, to avoid Concurrent Modification
-                    // exceptions
-                    final List<ITargetChangeListener> listeners =
-                            (List<ITargetChangeListener>)mTargetChangeListeners.clone();
-                    final SubMonitor progress2 = progress;
-                    AdtPlugin.getDisplay().syncExec(new Runnable() {
-                        public void run() {
-                            for (ITargetChangeListener listener : listeners) {
-                                try {
-                                    listener.onTargetsLoaded();
-                                } catch (Exception e) {
-                                    AdtPlugin.log(e, "Failed to update a TargetChangeListener.");  //$NON-NLS-1$
-                                } finally {
-                                    progress2.worked(1);
-                                }
-                            }
-                        }
-                    });
-                } catch (Throwable t) {
-                    log(t, "Unknown exception in parseSdkContent.");    //$NON-NLS-1$
-                    return new Status(IStatus.ERROR, PLUGIN_ID,
-                            "parseSdkContent failed", t);               //$NON-NLS-1$
-
-                } finally {
-                    mSdkIsLoading = false;
-                    if (monitor != null) {
-                        monitor.done();
-                    }
-                }
-
-                return Status.OK_STATUS;
-            }
-        };
-        job.setPriority(Job.BUILD); // build jobs are run after other interactive jobs
-        job.schedule();
-    }
-
-    /** Returns the global android console */
-    public MessageConsole getAndroidConsole() {
-        return mAndroidConsole;
-    }
-
-    // ----- Methods for Editors -------
-
-    public void startEditors() {
-        sAndroidLogoDesc = imageDescriptorFromPlugin(AdtPlugin.PLUGIN_ID,
-                "/icons/android.png"); //$NON-NLS-1$
-        sAndroidLogo = sAndroidLogoDesc.createImage();
-
-        // Add a resource listener to handle compiled resources.
-        IWorkspace ws = ResourcesPlugin.getWorkspace();
-        mResourceMonitor = ResourceMonitor.startMonitoring(ws);
-
-        if (mResourceMonitor != null) {
-            try {
-                setupDefaultEditor(mResourceMonitor);
-                ResourceManager.setup(mResourceMonitor);
-            } catch (Throwable t) {
-                log(t, "ResourceManager.setup failed"); //$NON-NLS-1$
-            }
-        }
-    }
-
-    /**
-     * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
-     * method saves this plug-in's preference and dialog stores and shuts down
-     * its image registry (if they are in use). Subclasses may extend this
-     * method, but must send super <b>last</b>. A try-finally statement should
-     * be used where necessary to ensure that <code>super.shutdown()</code> is
-     * always done.
-     *
-     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-     */
-    public void stopEditors() {
-        sAndroidLogo.dispose();
-
-        IconFactory.getInstance().Dispose();
-
-        // Remove the resource listener that handles compiled resources.
-        IWorkspace ws = ResourcesPlugin.getWorkspace();
-        ResourceMonitor.stopMonitoring(ws);
-
-        mRed.dispose();
-    }
-
-    /**
-     * Returns an Image for the small Android logo.
-     *
-     * Callers should not dispose it.
-     */
-    public static Image getAndroidLogo() {
-        return sAndroidLogo;
-    }
-
-    /**
-     * Returns an {@link ImageDescriptor} for the small Android logo.
-     *
-     * Callers should not dispose it.
-     */
-    public static ImageDescriptor getAndroidLogoDesc() {
-        return sAndroidLogoDesc;
-    }
-
-    /**
-     * Returns the ResourceMonitor object.
-     */
-    public ResourceMonitor getResourceMonitor() {
-        return mResourceMonitor;
-    }
-
-    /**
-     * Sets up the editor to register default editors for resource files when needed.
-     *
-     * This is called by the {@link AdtPlugin} during initialization.
-     *
-     * @param monitor The main Resource Monitor object.
-     */
-    public void setupDefaultEditor(ResourceMonitor monitor) {
-        monitor.addFileListener(new IFileListener() {
-
-            private static final String UNKNOWN_EDITOR = "unknown-editor"; //$NON-NLS-1$
-
-            /* (non-Javadoc)
-             * Sent when a file changed.
-             * @param file The file that changed.
-             * @param markerDeltas The marker deltas for the file.
-             * @param kind The change kind. This is equivalent to
-             * {@link IResourceDelta#accept(IResourceDeltaVisitor)}
-             *
-             * @see IFileListener#fileChanged
-             */
-            public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
-                if (AndroidConstants.EXT_XML.equals(file.getFileExtension())) {
-                    // The resources files must have a file path similar to
-                    //    project/res/.../*.xml
-                    // There is no support for sub folders, so the segment count must be 4
-                    if (file.getFullPath().segmentCount() == 4) {
-                        // check if we are inside the res folder.
-                        String segment = file.getFullPath().segment(1);
-                        if (segment.equalsIgnoreCase(SdkConstants.FD_RESOURCES)) {
-                            // we are inside a res/ folder, get the actual ResourceFolder
-                            ProjectResources resources = ResourceManager.getInstance().
-                                getProjectResources(file.getProject());
-
-                            // This happens when importing old Android projects in Eclipse
-                            // that lack the container (probably because resources fail to build
-                            // properly.)
-                            if (resources == null) {
-                                log(IStatus.INFO,
-                                        "getProjectResources failed for path %1$s in project %2$s", //$NON-NLS-1$
-                                        file.getFullPath().toOSString(),
-                                        file.getProject().getName());
-                                return;
-                            }
-
-                            ResourceFolder resFolder = resources.getResourceFolder(
-                                (IFolder)file.getParent());
-
-                            if (resFolder != null) {
-                                if (kind == IResourceDelta.ADDED) {
-                                    resourceAdded(file, resFolder.getType());
-                                } else if (kind == IResourceDelta.CHANGED) {
-                                    resourceChanged(file, resFolder.getType());
-                                }
-                            } else {
-                                // if the res folder is null, this means the name is invalid,
-                                // in this case we remove whatever android editors that was set
-                                // as the default editor.
-                                IEditorDescriptor desc = IDE.getDefaultEditor(file);
-                                String editorId = desc.getId();
-                                if (editorId.startsWith(AndroidConstants.EDITORS_NAMESPACE)) {
-                                    // reset the default editor.
-                                    IDE.setDefaultEditor(file, null);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            private void resourceAdded(IFile file, ResourceFolderType type) {
-                // set the default editor based on the type.
-                if (type == ResourceFolderType.LAYOUT) {
-                    IDE.setDefaultEditor(file, LayoutEditor.ID);
-                } else if (type == ResourceFolderType.DRAWABLE
-                        || type == ResourceFolderType.VALUES) {
-                    IDE.setDefaultEditor(file, ResourcesEditor.ID);
-                } else if (type == ResourceFolderType.MENU) {
-                    IDE.setDefaultEditor(file, MenuEditor.ID);
-                } else if (type == ResourceFolderType.XML) {
-                    if (XmlEditor.canHandleFile(file)) {
-                        IDE.setDefaultEditor(file, XmlEditor.ID);
-                    } else {
-                        // set a property to determine later if the XML can be handled
-                        QualifiedName qname = new QualifiedName(
-                                AdtPlugin.PLUGIN_ID,
-                                UNKNOWN_EDITOR);
-                        try {
-                            file.setPersistentProperty(qname, "1"); //$NON-NLS-1$
-                        } catch (CoreException e) {
-                            // pass
-                        }
-                    }
-                }
-            }
-
-            private void resourceChanged(IFile file, ResourceFolderType type) {
-                if (type == ResourceFolderType.XML) {
-                    IEditorDescriptor ed = IDE.getDefaultEditor(file);
-                    if (ed == null || ed.getId() != XmlEditor.ID) {
-                        QualifiedName qname = new QualifiedName(
-                                AdtPlugin.PLUGIN_ID,
-                                UNKNOWN_EDITOR);
-                        String prop = null;
-                        try {
-                            prop = file.getPersistentProperty(qname);
-                        } catch (CoreException e) {
-                            // pass
-                        }
-                        if (prop != null && XmlEditor.canHandleFile(file)) {
-                            try {
-                                // remove the property & set editor
-                                file.setPersistentProperty(qname, null);
-                                IWorkbenchPage page = PlatformUI.getWorkbench().
-                                                        getActiveWorkbenchWindow().getActivePage();
-
-                                IEditorPart oldEditor = page.findEditor(new FileEditorInput(file));
-                                if (oldEditor != null &&
-                                        AdtPlugin.displayPrompt("Android XML Editor",
-                                            String.format("The file you just saved as been recognized as a file that could be better handled using the Android XML Editor. Do you want to edit '%1$s' using the Android XML editor instead?",
-                                                    file.getFullPath()))) {
-                                    IDE.setDefaultEditor(file, XmlEditor.ID);
-                                    IEditorPart newEditor = page.openEditor(
-                                            new FileEditorInput(file),
-                                            XmlEditor.ID,
-                                            true, /* activate */
-                                            IWorkbenchPage.MATCH_NONE);
-
-                                    if (newEditor != null) {
-                                        page.closeEditor(oldEditor, true /* save */);
-                                    }
-                                }
-                            } catch (CoreException e) {
-                                // setPersistentProperty or page.openEditor may have failed
-                            }
-                        }
-                    }
-                }
-            }
-
-        }, IResourceDelta.ADDED | IResourceDelta.CHANGED);
-    }
-
-    /**
-     * Adds a new {@link ITargetChangeListener} to be notified when a new SDK is loaded, or when
-     * a project has its target changed.
-     */
-    public void addTargetListener(ITargetChangeListener listener) {
-        mTargetChangeListeners.add(listener);
-    }
-
-    /**
-     * Removes an existing {@link ITargetChangeListener}.
-     * @see #addTargetListener(ITargetChangeListener)
-     */
-    public void removeTargetListener(ITargetChangeListener listener) {
-        mTargetChangeListeners.remove(listener);
-    }
-
-    /**
-     * Updates all the {@link ITargetChangeListener} that a target has changed for a given project.
-     * <p/>Only editors related to that project should reload.
-     */
-    @SuppressWarnings("unchecked")
-    public void updateTargetListener(final IProject project) {
-        final List<ITargetChangeListener> listeners =
-            (List<ITargetChangeListener>)mTargetChangeListeners.clone();
-
-        AdtPlugin.getDisplay().asyncExec(new Runnable() {
-            public void run() {
-                for (ITargetChangeListener listener : listeners) {
-                    try {
-                        listener.onProjectTargetChange(project);
-                    } catch (Exception e) {
-                        AdtPlugin.log(e, "Failed to update a TargetChangeListener.");  //$NON-NLS-1$
-                    }
-                }
-            }
-        });
-    }
-
-    public static synchronized OutputStream getErrorStream() {
-        return sPlugin.mAndroidConsoleErrorStream;
-    }
-
-    /**
-     * Pings the usage start server.
-     */
-    private void pingUsageServer() {
-        // get the version of the plugin
-        String versionString = (String) getBundle().getHeaders().get(
-                Constants.BUNDLE_VERSION);
-        Version version = new Version(versionString);
-
-        versionString = String.format("%1$d.%2$d.%3$d", version.getMajor(), //$NON-NLS-1$
-                version.getMinor(), version.getMicro());
-
-        SdkStatsService.ping("adt", versionString, getDisplay()); //$NON-NLS-1$
-    }
-
-    /**
-     * Reparses the content of the SDK and updates opened projects.
-     */
-    public void reparseSdk() {
-        // add all the opened Android projects to the list of projects to be updated
-        // after the SDK is reloaded
-        synchronized (getSdkLockObject()) {
-            // get the project to refresh.
-            IJavaProject[] androidProjects = BaseProjectHelper.getAndroidProjects();
-            mPostLoadProjectsToResolve.addAll(Arrays.asList(androidProjects));
-        }
-
-        // parse the SDK resources at the new location
-        parseSdkContent();
-    }
-
-    /**
-     * Prints messages, associated with a project to the specified stream
-     * @param stream The stream to write to
-     * @param tag The tag associated to the message. Can be null
-     * @param objects The objects to print through their toString() method (or directly for
-     * {@link String} objects.
-     */
-    public static synchronized void printToStream(MessageConsoleStream stream, String tag,
-            Object... objects) {
-        String dateTag = getMessageTag(tag);
-
-        for (Object obj : objects) {
-            stream.print(dateTag);
-            if (obj instanceof String) {
-                stream.println((String)obj);
-            } else {
-                stream.println(obj.toString());
-            }
-        }
-    }
-
-    /**
-     * Creates a string containing the current date/time, and the tag
-     * @param tag The tag associated to the message. Can be null
-     * @return The dateTag
-     */
-    public static String getMessageTag(String tag) {
-        Calendar c = Calendar.getInstance();
-
-        if (tag == null) {
-            return String.format(Messages.Console_Date_Tag, c);
-        }
-
-        return String.format(Messages.Console_Data_Project_Tag, c, tag);
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java
deleted file mode 100644
index a09ee3c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt;
-
-import com.android.sdklib.SdkConstants;
-
-import java.io.File;
-import java.util.regex.Pattern;
-
-/**
- * Constant definition class.<br>
- * <br>
- * Most constants have a prefix defining the content.
- * <ul>
- * <li><code>WS_</code> Workspace path constant. Those are absolute paths,
- * from the project root.</li>
- * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
- * <li><code>FN_</code> File name constant.</li>
- * <li><code>FD_</code> Folder name constant.</li>
- * <li><code>MARKER_</code> Resource Marker Ids constant.</li>
- * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
- * <li><code>DOT_</code> File extension constant. This start with a dot.</li>
- * <li><code>RE_</code> Regexp constant.</li>
- * <li><code>NS_</code> Namespace constant.</li>
- * <li><code>CLASS_</code> Fully qualified class name.</li>
- * </ul>
- *
- */
-public class AndroidConstants {
-    /**
-     * The old Editors Plugin ID. It is still used in some places for compatibility.
-     * Please do not use for new features.
-     */
-    public static final String EDITORS_NAMESPACE = "com.android.ide.eclipse.editors"; // $NON-NLS-1$
-
-    /** Nature of android projects */
-    public final static String NATURE = "com.android.ide.eclipse.adt.AndroidNature"; //$NON-NLS-1$
-
-    /** Separator for workspace path, i.e. "/". */
-    public final static String WS_SEP = "/"; //$NON-NLS-1$
-    /** Separator character for workspace path, i.e. '/'. */
-    public final static char WS_SEP_CHAR = '/';
-
-    /** Extension of the Application package Files, i.e. "apk". */
-    public final static String EXT_ANDROID_PACKAGE = "apk"; //$NON-NLS-1$
-    /** Extension of java files, i.e. "java" */
-    public final static String EXT_JAVA = "java"; //$NON-NLS-1$
-    /** Extension of compiled java files, i.e. "class" */
-    public final static String EXT_CLASS = "class"; //$NON-NLS-1$
-    /** Extension of xml files, i.e. "xml" */
-    public final static String EXT_XML = "xml"; //$NON-NLS-1$
-    /** Extension of jar files, i.e. "jar" */
-    public final static String EXT_JAR = "jar"; //$NON-NLS-1$
-    /** Extension of aidl files, i.e. "aidl" */
-    public final static String EXT_AIDL = "aidl"; //$NON-NLS-1$
-    /** Extension of native libraries, i.e. "so" */
-    public final static String EXT_NATIVE_LIB = "so"; //$NON-NLS-1$
-
-    private final static String DOT = "."; //$NON-NLS-1$
-
-    /** Dot-Extension of the Application package Files, i.e. ".apk". */
-    public final static String DOT_ANDROID_PACKAGE = DOT + EXT_ANDROID_PACKAGE;
-    /** Dot-Extension of java files, i.e. ".java" */
-    public final static String DOT_JAVA = DOT + EXT_JAVA;
-    /** Dot-Extension of compiled java files, i.e. ".class" */
-    public final static String DOT_CLASS = DOT + EXT_CLASS;
-    /** Dot-Extension of xml files, i.e. ".xml" */
-    public final static String DOT_XML = DOT + EXT_XML;
-    /** Dot-Extension of jar files, i.e. ".jar" */
-    public final static String DOT_JAR = DOT + EXT_JAR;
-    /** Dot-Extension of aidl files, i.e. ".aidl" */
-    public final static String DOT_AIDL = DOT + EXT_AIDL;
-
-    /** Name of the manifest file, i.e. "AndroidManifest.xml". */
-    public static final String FN_ANDROID_MANIFEST = "AndroidManifest.xml"; //$NON-NLS-1$
-
-    /** Name of the android sources directory */
-    public static final String FD_ANDROID_SOURCES = "sources"; //$NON-NLS-1$
-
-    /** Resource java class  filename, i.e. "R.java" */
-    public final static String FN_RESOURCE_CLASS = "R.java"; //$NON-NLS-1$
-    /** Resource class file  filename, i.e. "R.class" */
-    public final static String FN_COMPILED_RESOURCE_CLASS = "R.class"; //$NON-NLS-1$
-    /** Manifest java class filename, i.e. "Manifest.java" */
-    public final static String FN_MANIFEST_CLASS = "Manifest.java"; //$NON-NLS-1$
-    /** Dex conversion output filname, i.e. "classes.dex" */
-    public final static String FN_CLASSES_DEX = "classes.dex"; //$NON-NLS-1$
-    /** Temporary packaged resources file name, i.e. "resources.ap_" */
-    public final static String FN_RESOURCES_AP_ = "resources.ap_"; //$NON-NLS-1$
-    /** Temporary packaged resources file name for a specific set of configuration */
-    public final static String FN_RESOURCES_S_AP_ = "resources-%s.ap_"; //$NON-NLS-1$
-    public final static Pattern PATTERN_RESOURCES_S_AP_ =
-        Pattern.compile("resources-.*\\.ap_", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-
-    public final static String FN_TRACEVIEW =
-        (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
-            "traceview.exe" : "traceview"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /** Absolute path of the workspace root, i.e. "/" */
-    public final static String WS_ROOT = WS_SEP;
-
-    /** Absolute path of the resource folder, eg "/res".<br> This is a workspace path. */
-    public final static String WS_RESOURCES = WS_SEP + SdkConstants.FD_RESOURCES;
-
-    /** Absolute path of the resource folder, eg "/assets".<br> This is a workspace path. */
-    public final static String WS_ASSETS = WS_SEP + SdkConstants.FD_ASSETS;
-
-    /** Leaf of the javaDoc folder. Does not start with a separator. */
-    public final static String WS_JAVADOC_FOLDER_LEAF = SdkConstants.FD_DOCS + "/" + //$NON-NLS-1$
-            SdkConstants.FD_DOCS_REFERENCE;
-
-    /** Path of the samples directory relative to the sdk folder.
-     *  This is an OS path, ending with a separator.
-     *  FIXME: remove once the NPW is fixed. */
-    public final static String OS_SDK_SAMPLES_FOLDER = SdkConstants.FD_SAMPLES + File.separator;
-
-    public final static String RE_DOT = "\\."; //$NON-NLS-1$
-    /** Regexp for java extension, i.e. "\.java$" */
-    public final static String RE_JAVA_EXT = "\\.java$"; //$NON-NLS-1$
-    /** Regexp for aidl extension, i.e. "\.aidl$" */
-    public final static String RE_AIDL_EXT = "\\.aidl$"; //$NON-NLS-1$
-
-    /** Namespace pattern for the custom resource XML, i.e. "http://schemas.android.com/apk/res/%s" */
-    public final static String NS_CUSTOM_RESOURCES = "http://schemas.android.com/apk/res/%1$s"; //$NON-NLS-1$
-
-    /** The old common plug-in ID. Please do not use for new features. */
-    public static final String COMMON_PLUGIN_ID = "com.android.ide.eclipse.common"; //$NON-NLS-1$
-
-    /** aapt marker error when running the compile command */
-    public final static String MARKER_AAPT_COMPILE = COMMON_PLUGIN_ID + ".aaptProblem"; //$NON-NLS-1$
-
-    /** aapt marker error when running the package command */
-    public final static String MARKER_AAPT_PACKAGE = COMMON_PLUGIN_ID + ".aapt2Problem"; //$NON-NLS-1$
-
-    /** XML marker error. */
-    public final static String MARKER_XML = COMMON_PLUGIN_ID + ".xmlProblem"; //$NON-NLS-1$
-
-    /** aidl marker error. */
-    public final static String MARKER_AIDL = COMMON_PLUGIN_ID + ".aidlProblem"; //$NON-NLS-1$
-
-    /** android marker error */
-    public final static String MARKER_ANDROID = COMMON_PLUGIN_ID + ".androidProblem"; //$NON-NLS-1$
-
-    /** Name for the "type" marker attribute */
-    public final static String MARKER_ATTR_TYPE = "android.type"; //$NON-NLS-1$
-    /** Name for the "class" marker attribute */
-    public final static String MARKER_ATTR_CLASS = "android.class"; //$NON-NLS-1$
-    /** activity value for marker attribute "type" */
-    public final static String MARKER_ATTR_TYPE_ACTIVITY = "activity"; //$NON-NLS-1$
-    /** service value for marker attribute "type" */
-    public final static String MARKER_ATTR_TYPE_SERVICE = "service"; //$NON-NLS-1$
-    /** receiver value for marker attribute "type" */
-    public final static String MARKER_ATTR_TYPE_RECEIVER = "receiver"; //$NON-NLS-1$
-    /** provider value for marker attribute "type" */
-    public final static String MARKER_ATTR_TYPE_PROVIDER = "provider"; //$NON-NLS-1$
-
-    public final static String CLASS_ACTIVITY = "android.app.Activity"; //$NON-NLS-1$
-    public final static String CLASS_SERVICE = "android.app.Service"; //$NON-NLS-1$
-    public final static String CLASS_BROADCASTRECEIVER = "android.content.BroadcastReceiver"; //$NON-NLS-1$
-    public final static String CLASS_CONTENTPROVIDER = "android.content.ContentProvider"; //$NON-NLS-1$
-    public final static String CLASS_INSTRUMENTATION = "android.app.Instrumentation"; //$NON-NLS-1$
-    public final static String CLASS_INSTRUMENTATION_RUNNER =
-        "android.test.InstrumentationTestRunner"; //$NON-NLS-1$
-    public final static String CLASS_BUNDLE = "android.os.Bundle"; //$NON-NLS-1$
-    public final static String CLASS_R = "android.R"; //$NON-NLS-1$
-    public final static String CLASS_MANIFEST_PERMISSION = "android.Manifest$permission"; //$NON-NLS-1$
-    public final static String CLASS_INTENT = "android.content.Intent"; //$NON-NLS-1$
-    public final static String CLASS_CONTEXT = "android.content.Context"; //$NON-NLS-1$
-    public final static String CLASS_VIEW = "android.view.View"; //$NON-NLS-1$
-    public final static String CLASS_VIEWGROUP = "android.view.ViewGroup"; //$NON-NLS-1$
-    public final static String CLASS_NAME_LAYOUTPARAMS = "LayoutParams"; //$NON-NLS-1$
-    public final static String CLASS_VIEWGROUP_LAYOUTPARAMS =
-        CLASS_VIEWGROUP + "$" + CLASS_NAME_LAYOUTPARAMS; //$NON-NLS-1$
-    public final static String CLASS_NAME_FRAMELAYOUT = "FrameLayout"; //$NON-NLS-1$
-    public final static String CLASS_FRAMELAYOUT =
-        "android.widget." + CLASS_NAME_FRAMELAYOUT; //$NON-NLS-1$
-    public final static String CLASS_PREFERENCE = "android.preference.Preference"; //$NON-NLS-1$
-    public final static String CLASS_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; //$NON-NLS-1$
-    public final static String CLASS_PREFERENCES =
-        "android.preference." + CLASS_NAME_PREFERENCE_SCREEN; //$NON-NLS-1$
-    public final static String CLASS_PREFERENCEGROUP = "android.preference.PreferenceGroup"; //$NON-NLS-1$
-    public final static String CLASS_PARCELABLE = "android.os.Parcelable"; //$NON-NLS-1$
-
-    public final static String CLASS_BRIDGE = "com.android.layoutlib.bridge.Bridge"; //$NON-NLS-1$
-
-    /**
-     * Prefered compiler level, i.e. "1.5".
-     */
-    public final static String COMPILER_COMPLIANCE_PREFERRED = "1.5"; //$NON-NLS-1$
-    /**
-     * List of valid compiler level, i.e. "1.5" and "1.6"
-     */
-    public final static String[] COMPILER_COMPLIANCE = {
-        "1.5", //$NON-NLS-1$
-        "1.6", //$NON-NLS-1$
-    };
-
-    /** The base URL where to find the Android class & manifest documentation */
-    public static final String CODESITE_BASE_URL = "http://code.google.com/android";  //$NON-NLS-1$
-
-    public static final String LIBRARY_TEST_RUNNER = "android.test.runner"; // $NON-NLS-1$
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/Messages.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/Messages.java
deleted file mode 100644
index 33046dc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/Messages.java
+++ /dev/null
@@ -1,52 +0,0 @@
-
-package com.android.ide.eclipse.adt;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-    private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.messages"; //$NON-NLS-1$
-
-    public static String AdtPlugin_Android_SDK_Content_Loader;
-
-    public static String AdtPlugin_Android_SDK_Resource_Parser;
-
-    public static String AdtPlugin_Failed_To_Parse_s;
-
-    public static String AdtPlugin_Failed_To_Start_s;
-
-    public static String AdtPlugin_Parsing_Resources;
-
-    public static String Console_Data_Project_Tag;
-
-    public static String Console_Date_Tag;
-
-    public static String Could_Not_Find;
-
-    public static String Could_Not_Find_Folder;
-
-    public static String Could_Not_Find_Folder_In_SDK;
-
-    public static String Dialog_Title_SDK_Location;
-
-    public static String Error_Check_Prefs;
-
-    public static String SDK_Not_Setup;
-
-    public static String VersionCheck_Plugin_Too_Old;
-
-    public static String VersionCheck_Plugin_Version_Failed;
-
-    public static String VersionCheck_SDK_Build_Too_Low;
-
-    public static String VersionCheck_SDK_Milestone_Too_Low;
-
-    public static String VersionCheck_Unable_To_Parse_Version_s;
-
-    static {
-        // initialize resource bundle
-        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
-    }
-
-    private Messages() {
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/VersionCheck.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/VersionCheck.java
deleted file mode 100644
index 6199ef9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/VersionCheck.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.Messages;
-import com.android.ide.eclipse.adt.AdtPlugin.CheckSdkErrorHandler;
-import com.android.sdklib.SdkConstants;
-
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Class handling the version check for the plugin vs. the SDK.<br>
- * The plugin must be able to support all version of the SDK.
- *
- * <p/>An SDK can require a new version of the plugin.
- * <p/>The SDK contains a file with the minimum version for the plugin. This file is inside the
- * <code>tools/lib</code> directory, and is called <code>plugin.prop</code>.<br>
- * Inside that text file, there is a line in the format "plugin.version=#.#.#". This is checked
- * against the current plugin version.<br>
- *
- */
-public final class VersionCheck {
-    /**
-     * Pattern to get the minimum plugin version supported by the SDK. This is read from
-     * the file <code>$SDK/tools/lib/plugin.prop</code>.
-     */
-    private final static Pattern sPluginVersionPattern = Pattern.compile(
-            "^plugin.version=(\\d+)\\.(\\d+)\\.(\\d+).*$"); //$NON-NLS-1$
-
-    /**
-     * Checks the plugin and the SDK have compatible versions.
-     * @param osSdkPath The path to the SDK
-     * @return true if compatible.
-     */
-    public static boolean checkVersion(String osSdkPath, CheckSdkErrorHandler errorHandler) {
-        AdtPlugin plugin = AdtPlugin.getDefault();
-        String osLibs = osSdkPath + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER;
-
-        // get the plugin property file, and grab the minimum plugin version required
-        // to work with the sdk
-        int minMajorVersion = -1;
-        int minMinorVersion = -1;
-        int minMicroVersion = -1;
-        try {
-            FileReader reader = new FileReader(osLibs + SdkConstants.FN_PLUGIN_PROP);
-            BufferedReader bReader = new BufferedReader(reader);
-            String line;
-            while ((line = bReader.readLine()) != null) {
-                Matcher m = sPluginVersionPattern.matcher(line);
-                if (m.matches()) {
-                    minMajorVersion = Integer.parseInt(m.group(1));
-                    minMinorVersion = Integer.parseInt(m.group(2));
-                    minMicroVersion = Integer.parseInt(m.group(3));
-                    break;
-                }
-            }
-        } catch (FileNotFoundException e) {
-            // the build id will be null, and this is handled by the builders.
-        } catch (IOException e) {
-            // the build id will be null, and this is handled by the builders.
-        }
-
-        // Failed to get the min plugin version number?
-        if (minMajorVersion == -1 || minMinorVersion == -1 || minMicroVersion ==-1) {
-            return errorHandler.handleWarning(Messages.VersionCheck_Plugin_Version_Failed);
-        }
-
-        // test the plugin number
-        String versionString = (String) plugin.getBundle().getHeaders().get(
-                Constants.BUNDLE_VERSION);
-        Version version = new Version(versionString);
-
-        boolean valid = true;
-        if (version.getMajor() < minMajorVersion) {
-            valid = false;
-        } else if (version.getMajor() == minMajorVersion) {
-            if (version.getMinor() < minMinorVersion) {
-                valid = false;
-            } else if (version.getMinor() == minMinorVersion) {
-                if (version.getMicro() < minMicroVersion) {
-                    valid = false;
-                }
-            }
-        }
-
-        if (valid == false) {
-            return errorHandler.handleWarning(
-                    String.format(Messages.VersionCheck_Plugin_Too_Old,
-                            minMajorVersion, minMinorVersion, minMicroVersion, versionString));
-        }
-
-        return true; // no error!
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/ConvertToAndroidAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/ConvertToAndroidAction.java
deleted file mode 100644
index cfbc93d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/ConvertToAndroidAction.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.actions;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-
-import java.util.Iterator;
-
-/**
- * Converts a project created with the activity creator into an
- * Android project.
- */
-public class ConvertToAndroidAction implements IObjectActionDelegate {
-
-    private ISelection mSelection;
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
-     */
-    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-        // pass
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see IActionDelegate#run(IAction)
-     */
-    public void run(IAction action) {
-        if (mSelection instanceof IStructuredSelection) {
-            for (Iterator<?> it = ((IStructuredSelection)mSelection).iterator(); it.hasNext();) {
-                Object element = it.next();
-                IProject project = null;
-                if (element instanceof IProject) {
-                    project = (IProject)element;
-                } else if (element instanceof IAdaptable) {
-                    project = (IProject)((IAdaptable)element).getAdapter(IProject.class);
-                }
-                if (project != null) {
-                    convertProject(project);
-                }
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see IActionDelegate#selectionChanged(IAction, ISelection)
-     */
-    public void selectionChanged(IAction action, ISelection selection) {
-        this.mSelection = selection;
-    }
-
-    /**
-     * Toggles sample nature on a project
-     * 
-     * @param project to have sample nature added or removed
-     */
-    private void convertProject(final IProject project) {
-        new Job("Convert Project") {
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                try {
-                    if (monitor != null) {
-                        monitor.beginTask(String.format(
-                                "Convert %1$s to Android", project.getName()), 5);
-                    }
-
-                    IProjectDescription description = project.getDescription();
-                    String[] natures = description.getNatureIds();
-
-                    // check if the project already has the android nature.
-                    for (int i = 0; i < natures.length; ++i) {
-                        if (AndroidConstants.NATURE.equals(natures[i])) {
-                            // we shouldn't be here as the visibility of the item
-                            // is dependent on the project.
-                            return new Status(Status.WARNING, AdtPlugin.PLUGIN_ID,
-                                    "Project is already an Android project");
-                        }
-                    }
-
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-
-                    String[] newNatures = new String[natures.length + 1];
-                    System.arraycopy(natures, 0, newNatures, 1, natures.length);
-                    newNatures[0] = AndroidConstants.NATURE;
-
-                    // set the new nature list in the project
-                    description.setNatureIds(newNatures);
-                    project.setDescription(description, null);
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-
-                    // Fix the classpath entries.
-                    // get a java project
-                    IJavaProject javaProject = JavaCore.create(project);
-                    ProjectHelper.fixProjectClasspathEntries(javaProject);
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-
-                    return Status.OK_STATUS;
-                } catch (JavaModelException e) {
-                    return e.getJavaModelStatus();
-                } catch (CoreException e) {
-                    return e.getStatus();
-                } finally {
-                    if (monitor != null) {
-                        monitor.done();
-                    }
-                }
-            }
-        }.schedule();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/FixProjectAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/FixProjectAction.java
deleted file mode 100644
index cb4f7e7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/FixProjectAction.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.actions;
-
-import com.android.ide.eclipse.adt.internal.project.AndroidNature;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-
-import java.util.Iterator;
-
-/**
- * Action to fix the project properties:
- * <ul>
- * <li>Make sure the framework archive is present with the link to the java
- * doc</li>
- * </ul>
- */
-public class FixProjectAction implements IObjectActionDelegate {
-
-    private ISelection mSelection;
-
-    /**
-     * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
-     */
-    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-    }
-
-    public void run(IAction action) {
-        if (mSelection instanceof IStructuredSelection) {
-
-            for (Iterator<?> it = ((IStructuredSelection) mSelection).iterator();
-                    it.hasNext();) {
-                Object element = it.next();
-                IProject project = null;
-                if (element instanceof IProject) {
-                    project = (IProject) element;
-                } else if (element instanceof IAdaptable) {
-                    project = (IProject) ((IAdaptable) element)
-                            .getAdapter(IProject.class);
-                }
-                if (project != null) {
-                    fixProject(project);
-                }
-            }
-        }
-    }
-
-    public void selectionChanged(IAction action, ISelection selection) {
-        this.mSelection = selection;
-    }
-
-    private void fixProject(final IProject project) {
-        new Job("Fix Project Properties") {
-
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                try {
-                    if (monitor != null) {
-                        monitor.beginTask("Fix Project Properties", 6);
-                    }
-
-                    ProjectHelper.fixProject(project);
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-                    
-                    // fix the nature order to have the proper project icon
-                    ProjectHelper.fixProjectNatureOrder(project);
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-
-                    // now we fix the builders
-                    AndroidNature.configureResourceManagerBuilder(project);
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-
-                    AndroidNature.configurePreBuilder(project);
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-
-                    AndroidNature.configureApkBuilder(project);
-                    if (monitor != null) {
-                        monitor.worked(1);
-                    }
-                    
-                    return Status.OK_STATUS;
-                } catch (JavaModelException e) {
-                    return e.getJavaModelStatus();
-                } catch (CoreException e) {
-                    return e.getStatus();
-                } finally {
-                    if (monitor != null) {
-                        monitor.done();
-                    }
-                }
-            }
-        }.schedule();
-    }
-
-    /**
-     * @see IWorkbenchWindowActionDelegate#init
-     */
-    public void init(IWorkbenchWindow window) {
-        // pass
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java
deleted file mode 100644
index 1ed5123..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java
+++ /dev/null
@@ -1,1215 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.ApkInstallManager;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.DexWrapper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.jarutils.DebugKeyProvider;
-import com.android.jarutils.JavaResourceFilter;
-import com.android.jarutils.SignedJarBuilder;
-import com.android.jarutils.DebugKeyProvider.IKeyGenOutput;
-import com.android.jarutils.DebugKeyProvider.KeytoolException;
-import com.android.jarutils.SignedJarBuilder.IZipEntryFilter;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.internal.project.ApkSettings;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-public class ApkBuilder extends BaseBuilder {
-
-    public static final String ID = "com.android.ide.eclipse.adt.ApkBuilder"; //$NON-NLS-1$
-
-    private static final String PROPERTY_CONVERT_TO_DEX = "convertToDex"; //$NON-NLS-1$
-    private static final String PROPERTY_PACKAGE_RESOURCES = "packageResources"; //$NON-NLS-1$
-    private static final String PROPERTY_BUILD_APK = "buildApk"; //$NON-NLS-1$
-
-    private static final String DX_PREFIX = "Dx"; //$NON-NLS-1$
-
-    /**
-     * Dex conversion flag. This is set to true if one of the changed/added/removed
-     * file is a .class file. Upon visiting all the delta resource, if this
-     * flag is true, then we know we'll have to make the "classes.dex" file.
-     */
-    private boolean mConvertToDex = false;
-
-    /**
-     * Package resources flag. This is set to true if one of the changed/added/removed
-     * file is a resource file. Upon visiting all the delta resource, if
-     * this flag is true, then we know we'll have to repackage the resources.
-     */
-    private boolean mPackageResources = false;
-
-    /**
-     * Final package build flag.
-     */
-    private boolean mBuildFinalPackage = false;
-
-    private PrintStream mOutStream = null;
-    private PrintStream mErrStream = null;
-
-    /**
-     * Basic Resource Delta Visitor class to check if a referenced project had a change in its
-     * compiled java files.
-     */
-    private static class ReferencedProjectDeltaVisitor implements IResourceDeltaVisitor {
-
-        private boolean mConvertToDex = false;
-        private boolean mMakeFinalPackage;
-
-        private IPath mOutputFolder;
-        private ArrayList<IPath> mSourceFolders;
-
-        private ReferencedProjectDeltaVisitor(IJavaProject javaProject) {
-            try {
-                mOutputFolder = javaProject.getOutputLocation();
-                mSourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
-            } catch (JavaModelException e) {
-            } finally {
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         * @throws CoreException
-         */
-        public boolean visit(IResourceDelta delta) throws CoreException {
-            //  no need to keep looking if we already know we need to convert
-            // to dex and make the final package.
-            if (mConvertToDex && mMakeFinalPackage) {
-                return false;
-            }
-
-            // get the resource and the path segments.
-            IResource resource = delta.getResource();
-            IPath resourceFullPath = resource.getFullPath();
-
-            if (mOutputFolder.isPrefixOf(resourceFullPath)) {
-                int type = resource.getType();
-                if (type == IResource.FILE) {
-                    String ext = resource.getFileExtension();
-                    if (AndroidConstants.EXT_CLASS.equals(ext)) {
-                        mConvertToDex = true;
-                    }
-                }
-                return true;
-            } else {
-                for (IPath sourceFullPath : mSourceFolders) {
-                    if (sourceFullPath.isPrefixOf(resourceFullPath)) {
-                        int type = resource.getType();
-                        if (type == IResource.FILE) {
-                            // check if the file is a valid file that would be
-                            // included during the final packaging.
-                            if (checkFileForPackaging((IFile)resource)) {
-                                mMakeFinalPackage = true;
-                            }
-
-                            return false;
-                        } else if (type == IResource.FOLDER) {
-                            // if this is a folder, we check if this is a valid folder as well.
-                            // If this is a folder that needs to be ignored, we must return false,
-                            // so that we ignore its content.
-                            return checkFolderForPackaging((IFolder)resource);
-                        }
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        /**
-         * Returns if one of the .class file was modified.
-         */
-        boolean needDexConvertion() {
-            return mConvertToDex;
-        }
-
-        boolean needMakeFinalPackage() {
-            return mMakeFinalPackage;
-        }
-    }
-
-    /**
-     * {@link IZipEntryFilter} to filter out everything that is not a standard java resources.
-     * <p/>Used in {@link SignedJarBuilder#writeZip(java.io.InputStream, IZipEntryFilter)} when
-     * we only want the java resources from external jars.
-     */
-    private final IZipEntryFilter mJavaResourcesFilter = new JavaResourceFilter();
-
-    public ApkBuilder() {
-        super();
-    }
-
-    // build() returns a list of project from which this project depends for future compilation.
-    @SuppressWarnings("unchecked")
-    @Override
-    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
-            throws CoreException {
-        // get a project object
-        IProject project = getProject();
-
-        // list of referenced projects.
-        IProject[] referencedProjects = null;
-
-        try {
-            // Top level check to make sure the build can move forward.
-            abortOnBadSetup(project);
-
-            // get the list of referenced projects.
-            referencedProjects = ProjectHelper.getReferencedProjects(project);
-            IJavaProject[] referencedJavaProjects = getJavaProjects(referencedProjects);
-
-            // get the output folder, this method returns the path with a trailing
-            // separator
-            IJavaProject javaProject = JavaCore.create(project);
-            IFolder outputFolder = BaseProjectHelper.getOutputFolder(project);
-
-            // now we need to get the classpath list
-            ArrayList<IPath> sourceList = BaseProjectHelper.getSourceClasspaths(javaProject);
-
-            // First thing we do is go through the resource delta to not
-            // lose it if we have to abort the build for any reason.
-            ApkDeltaVisitor dv = null;
-            if (kind == FULL_BUILD) {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                        Messages.Start_Full_Apk_Build);
-
-                mPackageResources = true;
-                mConvertToDex = true;
-                mBuildFinalPackage = true;
-            } else {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                        Messages.Start_Inc_Apk_Build);
-
-                // go through the resources and see if something changed.
-                IResourceDelta delta = getDelta(project);
-                if (delta == null) {
-                    mPackageResources = true;
-                    mConvertToDex = true;
-                    mBuildFinalPackage = true;
-                } else {
-                    dv = new ApkDeltaVisitor(this, sourceList, outputFolder);
-                    delta.accept(dv);
-
-                    // save the state
-                    mPackageResources |= dv.getPackageResources();
-                    mConvertToDex |= dv.getConvertToDex();
-                    mBuildFinalPackage |= dv.getMakeFinalPackage();
-                }
-
-                // also go through the delta for all the referenced projects, until we are forced to
-                // compile anyway
-                for (int i = 0 ; i < referencedJavaProjects.length &&
-                        (mBuildFinalPackage == false || mConvertToDex == false); i++) {
-                    IJavaProject referencedJavaProject = referencedJavaProjects[i];
-                    delta = getDelta(referencedJavaProject.getProject());
-                    if (delta != null) {
-                        ReferencedProjectDeltaVisitor refProjectDv = new ReferencedProjectDeltaVisitor(
-                                referencedJavaProject);
-                        delta.accept(refProjectDv);
-
-                        // save the state
-                        mConvertToDex |= refProjectDv.needDexConvertion();
-                        mBuildFinalPackage |= refProjectDv.needMakeFinalPackage();
-                    }
-                }
-            }
-
-            // store the build status in the persistent storage
-            saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , mConvertToDex);
-            saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
-            saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
-
-            if (dv != null && dv.mXmlError) {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                Messages.Xml_Error);
-
-                // if there was some XML errors, we just return w/o doing
-                // anything since we've put some markers in the files anyway
-                return referencedProjects;
-            }
-
-            if (outputFolder == null) {
-                // mark project and exit
-                markProject(AdtConstants.MARKER_ADT, Messages.Failed_To_Get_Output,
-                        IMarker.SEVERITY_ERROR);
-                return referencedProjects;
-            }
-
-            // first thing we do is check that the SDK directory has been setup.
-            String osSdkFolder = AdtPlugin.getOsSdkFolder();
-
-            if (osSdkFolder.length() == 0) {
-                // this has already been checked in the precompiler. Therefore,
-                // while we do have to cancel the build, we don't have to return
-                // any error or throw anything.
-                return referencedProjects;
-            }
-
-            // get the APK configs for the project.
-            ApkSettings apkSettings = Sdk.getCurrent().getApkSettings(project);
-            Set<Entry<String, String>> apkfilters = null;
-            if (apkSettings != null) {
-                Map<String, String> filterMap = apkSettings.getResourceFilters();
-                if (filterMap != null && filterMap.size() > 0) {
-                    apkfilters = filterMap.entrySet();
-                }
-            }
-
-            // do some extra check, in case the output files are not present. This
-            // will force to recreate them.
-            IResource tmp = null;
-
-            if (mPackageResources == false) {
-                // check the full resource package
-                tmp = outputFolder.findMember(AndroidConstants.FN_RESOURCES_AP_);
-                if (tmp == null || tmp.exists() == false) {
-                    mPackageResources = true;
-                    mBuildFinalPackage = true;
-                } else {
-                    // if the full package is present, we check the filtered resource packages
-                    // as well
-                    if (apkfilters != null) {
-                        for (Entry<String, String> entry : apkfilters) {
-                            String filename = String.format(AndroidConstants.FN_RESOURCES_S_AP_,
-                                    entry.getKey());
-
-                            tmp = outputFolder.findMember(filename);
-                            if (tmp == null || (tmp instanceof IFile &&
-                                    tmp.exists() == false)) {
-                                String msg = String.format(Messages.s_Missing_Repackaging,
-                                        filename);
-                                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
-                                        project, msg);
-                                mPackageResources = true;
-                                mBuildFinalPackage = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-
-            // check classes.dex is present. If not we force to recreate it.
-            if (mConvertToDex == false) {
-                tmp = outputFolder.findMember(AndroidConstants.FN_CLASSES_DEX);
-                if (tmp == null || tmp.exists() == false) {
-                    mConvertToDex = true;
-                    mBuildFinalPackage = true;
-                }
-            }
-
-            // also check the final file(s)!
-            String finalPackageName = ProjectHelper.getApkFilename(project, null /*config*/);
-            if (mBuildFinalPackage == false) {
-                tmp = outputFolder.findMember(finalPackageName);
-                if (tmp == null || (tmp instanceof IFile &&
-                        tmp.exists() == false)) {
-                    String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName);
-                    AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
-                    mBuildFinalPackage = true;
-                } else if (apkfilters != null) {
-                    // if the full apk is present, we check the filtered apk as well
-                    for (Entry<String, String> entry : apkfilters) {
-                        String filename = ProjectHelper.getApkFilename(project, entry.getKey());
-
-                        tmp = outputFolder.findMember(filename);
-                        if (tmp == null || (tmp instanceof IFile &&
-                                tmp.exists() == false)) {
-                            String msg = String.format(Messages.s_Missing_Repackaging, filename);
-                            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
-                            mBuildFinalPackage = true;
-                            break;
-                        }
-                    }
-                }
-            }
-
-            // at this point we know if we need to recreate the temporary apk
-            // or the dex file, but we don't know if we simply need to recreate them
-            // because they are missing
-
-            // refresh the output directory first
-            IContainer ic = outputFolder.getParent();
-            if (ic != null) {
-                ic.refreshLocal(IResource.DEPTH_ONE, monitor);
-            }
-
-            // we need to test all three, as we may need to make the final package
-            // but not the intermediary ones.
-            if (mPackageResources || mConvertToDex || mBuildFinalPackage) {
-                IPath binLocation = outputFolder.getLocation();
-                if (binLocation == null) {
-                    markProject(AdtConstants.MARKER_ADT, Messages.Output_Missing,
-                            IMarker.SEVERITY_ERROR);
-                    return referencedProjects;
-                }
-                String osBinPath = binLocation.toOSString();
-
-                // Remove the old .apk.
-                // This make sure that if the apk is corrupted, then dx (which would attempt
-                // to open it), will not fail.
-                String osFinalPackagePath = osBinPath + File.separator + finalPackageName;
-                File finalPackage = new File(osFinalPackagePath);
-
-                // if delete failed, this is not really a problem, as the final package generation
-                // handle already present .apk, and if that one failed as well, the user will be
-                // notified.
-                finalPackage.delete();
-
-                if (apkfilters != null) {
-                    for (Entry<String, String> entry : apkfilters) {
-                        String packageFilepath = osBinPath + File.separator +
-                                ProjectHelper.getApkFilename(project, entry.getKey());
-
-                        finalPackage = new File(packageFilepath);
-                        finalPackage.delete();
-                    }
-                }
-
-                // first we check if we need to package the resources.
-                if (mPackageResources) {
-                    // remove some aapt_package only markers.
-                    removeMarkersFromContainer(project, AndroidConstants.MARKER_AAPT_PACKAGE);
-
-                    // need to figure out some path before we can execute aapt;
-
-                    // resource to the AndroidManifest.xml file
-                    IResource manifestResource = project .findMember(
-                            AndroidConstants.WS_SEP + AndroidConstants.FN_ANDROID_MANIFEST);
-
-                    if (manifestResource == null
-                            || manifestResource.exists() == false) {
-                        // mark project and exit
-                        String msg = String.format(Messages.s_File_Missing,
-                                AndroidConstants.FN_ANDROID_MANIFEST);
-                        markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-                        return referencedProjects;
-                    }
-
-                    // get the resource folder
-                    IFolder resFolder = project.getFolder(
-                            AndroidConstants.WS_RESOURCES);
-
-                    // and the assets folder
-                    IFolder assetsFolder = project.getFolder(
-                            AndroidConstants.WS_ASSETS);
-
-                    // we need to make sure this one exists.
-                    if (assetsFolder.exists() == false) {
-                        assetsFolder = null;
-                    }
-
-                    IPath resLocation = resFolder.getLocation();
-                    IPath manifestLocation = manifestResource.getLocation();
-
-                    if (resLocation != null && manifestLocation != null) {
-                        String osResPath = resLocation.toOSString();
-                        String osManifestPath = manifestLocation.toOSString();
-
-                        String osAssetsPath = null;
-                        if (assetsFolder != null) {
-                            osAssetsPath = assetsFolder.getLocation().toOSString();
-                        }
-
-                        // build the default resource package
-                        if (executeAapt(project, osManifestPath, osResPath,
-                                osAssetsPath, osBinPath + File.separator +
-                                AndroidConstants.FN_RESOURCES_AP_, null /*configFilter*/) == false) {
-                            // aapt failed. Whatever files that needed to be marked
-                            // have already been marked. We just return.
-                            return referencedProjects;
-                        }
-
-                        // now do the same thing for all the configured resource packages.
-                        if (apkfilters != null) {
-                            for (Entry<String, String> entry : apkfilters) {
-                                String outPathFormat = osBinPath + File.separator +
-                                        AndroidConstants.FN_RESOURCES_S_AP_;
-                                String outPath = String.format(outPathFormat, entry.getKey());
-                                if (executeAapt(project, osManifestPath, osResPath,
-                                        osAssetsPath, outPath, entry.getValue()) == false) {
-                                    // aapt failed. Whatever files that needed to be marked
-                                    // have already been marked. We just return.
-                                    return referencedProjects;
-                                }
-                            }
-                        }
-
-                        // build has been done. reset the state of the builder
-                        mPackageResources = false;
-
-                        // and store it
-                        saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
-                    }
-                }
-
-                // then we check if we need to package the .class into classes.dex
-                if (mConvertToDex) {
-                    if (executeDx(javaProject, osBinPath, osBinPath + File.separator +
-                            AndroidConstants.FN_CLASSES_DEX, referencedJavaProjects) == false) {
-                        // dx failed, we return
-                        return referencedProjects;
-                    }
-
-                    // build has been done. reset the state of the builder
-                    mConvertToDex = false;
-
-                    // and store it
-                    saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
-                }
-
-                // now we need to make the final package from the intermediary apk
-                // and classes.dex.
-                // This is the default package with all the resources.
-
-                String classesDexPath = osBinPath + File.separator + AndroidConstants.FN_CLASSES_DEX;
-                if (finalPackage(osBinPath + File.separator + AndroidConstants.FN_RESOURCES_AP_,
-                                classesDexPath,osFinalPackagePath, javaProject,
-                                referencedJavaProjects) == false) {
-                    return referencedProjects;
-                }
-
-                // now do the same thing for all the configured resource packages.
-                if (apkfilters != null) {
-                    String resPathFormat = osBinPath + File.separator +
-                            AndroidConstants.FN_RESOURCES_S_AP_;
-
-                    for (Entry<String, String> entry : apkfilters) {
-                        // make the filename for the resource package.
-                        String resPath = String.format(resPathFormat, entry.getKey());
-
-                        // make the filename for the apk to generate
-                        String apkOsFilePath = osBinPath + File.separator +
-                                ProjectHelper.getApkFilename(project, entry.getKey());
-                        if (finalPackage(resPath, classesDexPath, apkOsFilePath, javaProject,
-                                referencedJavaProjects) == false) {
-                            return referencedProjects;
-                        }
-                    }
-                }
-
-                // we are done.
-
-                // get the resource to bin
-                outputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
-
-                // build has been done. reset the state of the builder
-                mBuildFinalPackage = false;
-
-                // and store it
-                saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
-
-                // reset the installation manager to force new installs of this project
-                ApkInstallManager.getInstance().resetInstallationFor(project);
-
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                        "Build Success!");
-            }
-        } catch (Exception exception) {
-            // try to catch other exception to actually display an error. This will be useful
-            // if we get an NPE or something so that we can at least notify the user that something
-            // went wrong.
-
-            // first check if this is a CoreException we threw to cancel the build.
-            if (exception instanceof CoreException) {
-                if (((CoreException)exception).getStatus().getSeverity() == IStatus.CANCEL) {
-                    // Project is already marked with an error. Nothing to do
-                    return referencedProjects;
-                }
-            }
-
-            String msg = exception.getMessage();
-            if (msg == null) {
-                msg = exception.getClass().getCanonicalName();
-            }
-
-            msg = String.format("Unknown error: %1$s", msg);
-            AdtPlugin.printErrorToConsole(project, msg);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-        }
-
-        return referencedProjects;
-    }
-
-    @Override
-    protected void startupOnInitialize() {
-        super.startupOnInitialize();
-
-        // load the build status. We pass true as the default value to
-        // force a recompile in case the property was not found
-        mConvertToDex = loadProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , true);
-        mPackageResources = loadProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, true);
-        mBuildFinalPackage = loadProjectBooleanProperty(PROPERTY_BUILD_APK, true);
-    }
-
-    /**
-     * Executes aapt. If any error happen, files or the project will be marked.
-     * @param project The Project
-     * @param osManifestPath The path to the manifest file
-     * @param osResPath The path to the res folder
-     * @param osAssetsPath The path to the assets folder. This can be null.
-     * @param osOutFilePath The path to the temporary resource file to create.
-     * @param configFilter The configuration filter for the resources to include
-     * (used with -c option, for example "port,en,fr" to include portrait, English and French
-     * resources.)
-     * @return true if success, false otherwise.
-     */
-    private boolean executeAapt(IProject project, String osManifestPath,
-            String osResPath, String osAssetsPath, String osOutFilePath, String configFilter) {
-        IAndroidTarget target = Sdk.getCurrent().getTarget(project);
-
-        // Create the command line.
-        ArrayList<String> commandArray = new ArrayList<String>();
-        commandArray.add(target.getPath(IAndroidTarget.AAPT));
-        commandArray.add("package"); //$NON-NLS-1$
-        commandArray.add("-f");//$NON-NLS-1$
-        if (AdtPlugin.getBuildVerbosity() == AdtConstants.BUILD_VERBOSE) {
-            commandArray.add("-v"); //$NON-NLS-1$
-        }
-        if (configFilter != null) {
-            commandArray.add("-c"); //$NON-NLS-1$
-            commandArray.add(configFilter);
-        }
-        commandArray.add("-M"); //$NON-NLS-1$
-        commandArray.add(osManifestPath);
-        commandArray.add("-S"); //$NON-NLS-1$
-        commandArray.add(osResPath);
-        if (osAssetsPath != null) {
-            commandArray.add("-A"); //$NON-NLS-1$
-            commandArray.add(osAssetsPath);
-        }
-        commandArray.add("-I"); //$NON-NLS-1$
-        commandArray.add(target.getPath(IAndroidTarget.ANDROID_JAR));
-        commandArray.add("-F"); //$NON-NLS-1$
-        commandArray.add(osOutFilePath);
-
-        String command[] = commandArray.toArray(
-                new String[commandArray.size()]);
-
-        if (AdtPlugin.getBuildVerbosity() == AdtConstants.BUILD_VERBOSE) {
-            StringBuilder sb = new StringBuilder();
-            for (String c : command) {
-                sb.append(c);
-                sb.append(' ');
-            }
-            AdtPlugin.printToConsole(project, sb.toString());
-        }
-
-        // launch
-        int execError = 1;
-        try {
-            // launch the command line process
-            Process process = Runtime.getRuntime().exec(command);
-
-            // list to store each line of stderr
-            ArrayList<String> results = new ArrayList<String>();
-
-            // get the output and return code from the process
-            execError = grabProcessOutput(process, results);
-
-            // attempt to parse the error output
-            boolean parsingError = parseAaptOutput(results, project);
-
-            // if we couldn't parse the output we display it in the console.
-            if (parsingError) {
-                if (execError != 0) {
-                    AdtPlugin.printErrorToConsole(project, results.toArray());
-                } else {
-                    AdtPlugin.printBuildToConsole(AdtConstants.BUILD_ALWAYS, project,
-                            results.toArray());
-                }
-            }
-
-            // We need to abort if the exec failed.
-            if (execError != 0) {
-                // if the exec failed, and we couldn't parse the error output (and therefore
-                // not all files that should have been marked, were marked), we put a generic
-                // marker on the project and abort.
-                if (parsingError) {
-                    markProject(AdtConstants.MARKER_ADT, Messages.Unparsed_AAPT_Errors,
-                            IMarker.SEVERITY_ERROR);
-                }
-
-                // abort if exec failed.
-                return false;
-            }
-        } catch (IOException e1) {
-            String msg = String.format(Messages.AAPT_Exec_Error, command[0]);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        } catch (InterruptedException e) {
-            String msg = String.format(Messages.AAPT_Exec_Error, command[0]);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Execute the Dx tool for dalvik code conversion.
-     * @param javaProject The java project
-     * @param osBinPath the path to the output folder of the project
-     * @param osOutFilePath the path of the dex file to create.
-     * @param referencedJavaProjects the list of referenced projects for this project.
-     *
-     * @throws CoreException
-     */
-    private boolean executeDx(IJavaProject javaProject, String osBinPath, String osOutFilePath,
-            IJavaProject[] referencedJavaProjects) throws CoreException {
-        IAndroidTarget target = Sdk.getCurrent().getTarget(javaProject.getProject());
-        AndroidTargetData targetData = Sdk.getCurrent().getTargetData(target);
-        if (targetData == null) {
-            throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                    Messages.ApkBuilder_UnableBuild_Dex_Not_loaded));
-        }
-
-        // get the dex wrapper
-        DexWrapper wrapper = targetData.getDexWrapper();
-
-        if (wrapper == null) {
-            throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                    Messages.ApkBuilder_UnableBuild_Dex_Not_loaded));
-        }
-
-        // make sure dx use the proper output streams.
-        // first make sure we actually have the streams available.
-        if (mOutStream == null) {
-            IProject project = getProject();
-            mOutStream = AdtPlugin.getOutPrintStream(project, DX_PREFIX);
-            mErrStream = AdtPlugin.getErrPrintStream(project, DX_PREFIX);
-        }
-
-        try {
-            // get the list of libraries to include with the source code
-            String[] libraries = getExternalJars();
-
-            // get the list of referenced projects output to add
-            String[] projectOutputs = getProjectOutputs(referencedJavaProjects);
-
-            String[] fileNames = new String[1 + projectOutputs.length + libraries.length];
-
-            // first this project output
-            fileNames[0] = osBinPath;
-
-            // then other project output
-            System.arraycopy(projectOutputs, 0, fileNames, 1, projectOutputs.length);
-
-            // then external jars.
-            System.arraycopy(libraries, 0, fileNames, 1 + projectOutputs.length, libraries.length);
-
-            int res = wrapper.run(osOutFilePath, fileNames,
-                    AdtPlugin.getBuildVerbosity() == AdtConstants.BUILD_VERBOSE,
-                    mOutStream, mErrStream);
-
-            if (res != 0) {
-                // output error message and marker the project.
-                String message = String.format(Messages.Dalvik_Error_d,
-                        res);
-                AdtPlugin.printErrorToConsole(getProject(), message);
-                markProject(AdtConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
-                return false;
-            }
-        } catch (Throwable ex) {
-            String message = ex.getMessage();
-            if (message == null) {
-                message = ex.getClass().getCanonicalName();
-            }
-            message = String.format(Messages.Dalvik_Error_s, message);
-            AdtPlugin.printErrorToConsole(getProject(), message);
-            markProject(AdtConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
-            if ((ex instanceof NoClassDefFoundError)
-                    || (ex instanceof NoSuchMethodError)) {
-                AdtPlugin.printErrorToConsole(getProject(), Messages.Incompatible_VM_Warning,
-                        Messages.Requires_1_5_Error);
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Makes the final package. Package the dex files, the temporary resource file into the final
-     * package file.
-     * @param intermediateApk The path to the temporary resource file.
-     * @param dex The path to the dex file.
-     * @param output The path to the final package file to create.
-     * @param javaProject
-     * @param referencedJavaProjects
-     * @return true if success, false otherwise.
-     */
-    private boolean finalPackage(String intermediateApk, String dex, String output,
-            final IJavaProject javaProject, IJavaProject[] referencedJavaProjects) {
-        FileOutputStream fos = null;
-        try {
-            IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
-            String osKeyPath = store.getString(AdtPlugin.PREFS_CUSTOM_DEBUG_KEYSTORE);
-            if (osKeyPath == null || new File(osKeyPath).exists() == false) {
-                osKeyPath = DebugKeyProvider.getDefaultKeyStoreOsPath();
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                        Messages.ApkBuilder_Using_Default_Key);
-            } else {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                        String.format(Messages.ApkBuilder_Using_s_To_Sign, osKeyPath));
-            }
-
-            // TODO: get the store type from somewhere else.
-            DebugKeyProvider provider = new DebugKeyProvider(osKeyPath, null /* storeType */,
-                    new IKeyGenOutput() {
-                        public void err(String message) {
-                            AdtPlugin.printErrorToConsole(javaProject.getProject(),
-                                    Messages.ApkBuilder_Signing_Key_Creation_s + message);
-                        }
-
-                        public void out(String message) {
-                            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
-                                    javaProject.getProject(),
-                                    Messages.ApkBuilder_Signing_Key_Creation_s + message);
-                        }
-            });
-            PrivateKey key = provider.getDebugKey();
-            X509Certificate certificate = (X509Certificate)provider.getCertificate();
-
-            if (key == null) {
-                String msg = String.format(Messages.Final_Archive_Error_s,
-                        Messages.ApkBuilder_Unable_To_Gey_Key);
-                AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
-                markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-                return false;
-            }
-
-            // compare the certificate expiration date
-            if (certificate != null && certificate.getNotAfter().compareTo(new Date()) < 0) {
-                // TODO, regenerate a new one.
-                String msg = String.format(Messages.Final_Archive_Error_s,
-                    String.format(Messages.ApkBuilder_Certificate_Expired_on_s,
-                            DateFormat.getInstance().format(certificate.getNotAfter())));
-                AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
-                markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-                return false;
-            }
-
-            // create the jar builder.
-            fos = new FileOutputStream(output);
-            SignedJarBuilder builder = new SignedJarBuilder(fos, key, certificate);
-
-            // add the intermediate file containing the compiled resources.
-            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                    String.format(Messages.ApkBuilder_Packaging_s, intermediateApk));
-            FileInputStream fis = new FileInputStream(intermediateApk);
-            try {
-                builder.writeZip(fis, null /* filter */);
-            } finally {
-                fis.close();
-            }
-
-            // Now we add the new file to the zip archive for the classes.dex file.
-            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                    String.format(Messages.ApkBuilder_Packaging_s, AndroidConstants.FN_CLASSES_DEX));
-            File entryFile = new File(dex);
-            builder.writeFile(entryFile, AndroidConstants.FN_CLASSES_DEX);
-
-            // Now we write the standard resources from the project and the referenced projects.
-            writeStandardResources(builder, javaProject, referencedJavaProjects);
-
-            // Now we write the standard resources from the external libraries
-            for (String libraryOsPath : getExternalJars()) {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                        String.format(Messages.ApkBuilder_Packaging_s, libraryOsPath));
-                try {
-                    fis = new FileInputStream(libraryOsPath);
-                    builder.writeZip(fis, mJavaResourcesFilter);
-                } finally {
-                    fis.close();
-                }
-            }
-
-            // now write the native libraries.
-            // First look if the lib folder is there.
-            IResource libFolder = javaProject.getProject().findMember(SdkConstants.FD_NATIVE_LIBS);
-            if (libFolder != null && libFolder.exists() &&
-                    libFolder.getType() == IResource.FOLDER) {
-                // look inside and put .so in lib/* by keeping the relative folder path.
-                writeNativeLibraries(libFolder.getFullPath().segmentCount(), builder, libFolder);
-            }
-
-            // close the jar file and write the manifest and sign it.
-            builder.close();
-        } catch (GeneralSecurityException e1) {
-            // mark project and return
-            String msg = String.format(Messages.Final_Archive_Error_s, e1.getMessage());
-            AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        } catch (IOException e1) {
-            // mark project and return
-            String msg = String.format(Messages.Final_Archive_Error_s, e1.getMessage());
-            AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        } catch (KeytoolException e) {
-            String eMessage = e.getMessage();
-
-            // mark the project with the standard message
-            String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
-            // output more info in the console
-            AdtPlugin.printErrorToConsole(javaProject.getProject(),
-                    msg,
-                    String.format(Messages.ApkBuilder_JAVA_HOME_is_s, e.getJavaHome()),
-                    Messages.ApkBuilder_Update_or_Execute_manually_s,
-                    e.getCommandLine());
-        } catch (AndroidLocationException e) {
-            String eMessage = e.getMessage();
-
-            // mark the project with the standard message
-            String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
-            // and also output it in the console
-            AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
-        } catch (CoreException e) {
-            // mark project and return
-            String msg = String.format(Messages.Final_Archive_Error_s, e.getMessage());
-            AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        } catch (Exception e) {
-            // try to catch other exception to actually display an error. This will be useful
-            // if we get an NPE or something so that we can at least notify the user that something
-            // went wrong (otherwise the build appears to succeed but the zip archive is not closed
-            // and therefore invalid.
-            String msg = e.getMessage();
-            if (msg == null) {
-                msg = e.getClass().getCanonicalName();
-            }
-
-            msg = String.format("Unknown error: %1$s", msg);
-            AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        } finally {
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException e) {
-                    // pass.
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Writes native libraries into a {@link SignedJarBuilder}.
-     * <p/>This recursively go through folder and writes .so files.
-     * The path in the archive is based on the root folder containing the libraries in the project.
-     * Its segment count is passed to the method to compute the resources path relative to the root
-     * folder.
-     * Native libraries in the archive must be in a "lib" folder. Everything in the project native
-     * lib folder directly goes in this "lib" folder in the archive.
-     *
-     *
-     * @param rootSegmentCount The number of segment of the path of the folder containing the
-     * libraries. This is used to compute the path in the archive.
-     * @param jarBuilder the {@link SignedJarBuilder} used to create the archive.
-     * @param resource the IResource to write.
-     * @throws CoreException
-     * @throws IOException
-     */
-    private void writeNativeLibraries(int rootSegmentCount, SignedJarBuilder jarBuilder,
-            IResource resource) throws CoreException, IOException {
-        if (resource.getType() == IResource.FILE) {
-            IPath path = resource.getFullPath();
-
-            // check the extension.
-            String ext = path.getFileExtension();
-            if (ext != null && ext.equalsIgnoreCase(AndroidConstants.EXT_NATIVE_LIB)) {
-                // remove the first segment to build the path inside the archive.
-                path = path.removeFirstSegments(rootSegmentCount);
-
-                // add it to the archive.
-                IPath apkPath = new Path(SdkConstants.FD_APK_NATIVE_LIBS);
-                apkPath = apkPath.append(path);
-
-                // writes the file in the apk.
-                jarBuilder.writeFile(resource.getLocation().toFile(), apkPath.toString());
-            }
-        } else if (resource.getType() == IResource.FOLDER &&
-                checkFolderForPackaging((IFolder)resource)) {
-            IResource[] members = ((IFolder)resource).members();
-            for (IResource member : members) {
-                writeNativeLibraries(rootSegmentCount, jarBuilder, member);
-            }
-        }
-    }
-
-    /**
-     * Writes the standard resources of a project and its referenced projects
-     * into a {@link SignedJarBuilder}.
-     * Standard resources are non java/aidl files placed in the java package folders.
-     * @param jarBuilder the {@link SignedJarBuilder}.
-     * @param javaProject the javaProject object.
-     * @param referencedJavaProjects the java projects that this project references.
-     * @throws IOException
-     * @throws CoreException
-     */
-    private void writeStandardResources(SignedJarBuilder jarBuilder, IJavaProject javaProject,
-            IJavaProject[] referencedJavaProjects) throws IOException, CoreException {
-        IWorkspace ws = ResourcesPlugin.getWorkspace();
-        IWorkspaceRoot wsRoot = ws.getRoot();
-
-        // create a list of path already put into the archive, in order to detect conflict
-        ArrayList<String> list = new ArrayList<String>();
-
-        writeStandardProjectResources(jarBuilder, javaProject, wsRoot, list);
-
-        for (IJavaProject referencedJavaProject : referencedJavaProjects) {
-            // only include output from non android referenced project
-            // (This is to handle the case of reference Android projects in the context of
-            // instrumentation projects that need to reference the projects to be tested).
-            if (referencedJavaProject.getProject().hasNature(AndroidConstants.NATURE) == false) {
-                writeStandardProjectResources(jarBuilder, referencedJavaProject, wsRoot, list);
-            }
-        }
-    }
-
-    /**
-     * Writes the standard resources of a {@link IJavaProject} into a {@link SignedJarBuilder}.
-     * Standard resources are non java/aidl files placed in the java package folders.
-     * @param jarBuilder the {@link SignedJarBuilder}.
-     * @param javaProject the javaProject object.
-     * @param wsRoot the {@link IWorkspaceRoot}.
-     * @param list a list of files already added to the archive, to detect conflicts.
-     * @throws IOException
-     */
-    private void writeStandardProjectResources(SignedJarBuilder jarBuilder,
-            IJavaProject javaProject, IWorkspaceRoot wsRoot, ArrayList<String> list)
-            throws IOException {
-        // get the source pathes
-        ArrayList<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
-
-        // loop on them and then recursively go through the content looking for matching files.
-        for (IPath sourcePath : sourceFolders) {
-            IResource sourceResource = wsRoot.findMember(sourcePath);
-            if (sourceResource != null && sourceResource.getType() == IResource.FOLDER) {
-                writeStandardSourceFolderResources(jarBuilder, sourcePath, (IFolder)sourceResource,
-                        list);
-            }
-        }
-    }
-
-    /**
-     * Recursively writes the standard resources of a source folder into a {@link SignedJarBuilder}.
-     * Standard resources are non java/aidl files placed in the java package folders.
-     * @param jarBuilder the {@link SignedJarBuilder}.
-     * @param sourceFolder the {@link IPath} of the source folder.
-     * @param currentFolder The current folder we're recursively processing.
-     * @param list a list of files already added to the archive, to detect conflicts.
-     * @throws IOException
-     */
-    private void writeStandardSourceFolderResources(SignedJarBuilder jarBuilder, IPath sourceFolder,
-            IFolder currentFolder, ArrayList<String> list) throws IOException {
-        try {
-            IResource[] members = currentFolder.members();
-
-            for (IResource member : members) {
-                int type = member.getType();
-                if (type == IResource.FILE && member.exists()) {
-                    if (checkFileForPackaging((IFile)member)) {
-                        // this files must be added to the archive.
-                        IPath fullPath = member.getFullPath();
-
-                        // We need to create its path inside the archive.
-                        // This path is relative to the source folder.
-                        IPath relativePath = fullPath.removeFirstSegments(
-                                sourceFolder.segmentCount());
-                        String zipPath = relativePath.toString();
-
-                        // lets check it's not already in the list of path added to the archive
-                        if (list.indexOf(zipPath) != -1) {
-                            AdtPlugin.printErrorToConsole(getProject(),
-                                    String.format(
-                                            Messages.ApkBuilder_s_Conflict_with_file_s,
-                                            fullPath, zipPath));
-                        } else {
-                            // get the File object
-                            File entryFile = member.getLocation().toFile();
-
-                            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                                    String.format(Messages.ApkBuilder_Packaging_s_into_s, fullPath, zipPath));
-
-                            // write it in the zip archive
-                            jarBuilder.writeFile(entryFile, zipPath);
-
-                            // and add it to the list of entries
-                            list.add(zipPath);
-                        }
-                    }
-                } else if (type == IResource.FOLDER) {
-                    if (checkFolderForPackaging((IFolder)member)) {
-                        writeStandardSourceFolderResources(jarBuilder, sourceFolder,
-                                (IFolder)member, list);
-                    }
-                }
-            }
-        } catch (CoreException e) {
-            // if we can't get the members of the folder, we just don't do anything.
-        }
-    }
-
-    /**
-     * Returns the list of the output folders for the specified {@link IJavaProject} objects, if
-     * they are Android projects.
-     *
-     * @param referencedJavaProjects the java projects.
-     * @return an array, always. Can be empty.
-     * @throws CoreException
-     */
-    private String[] getProjectOutputs(IJavaProject[] referencedJavaProjects) throws CoreException {
-        ArrayList<String> list = new ArrayList<String>();
-
-        IWorkspace ws = ResourcesPlugin.getWorkspace();
-        IWorkspaceRoot wsRoot = ws.getRoot();
-
-        for (IJavaProject javaProject : referencedJavaProjects) {
-            // only include output from non android referenced project
-            // (This is to handle the case of reference Android projects in the context of
-            // instrumentation projects that need to reference the projects to be tested).
-            if (javaProject.getProject().hasNature(AndroidConstants.NATURE) == false) {
-                // get the output folder
-                IPath path = null;
-                try {
-                    path = javaProject.getOutputLocation();
-                } catch (JavaModelException e) {
-                    continue;
-                }
-
-                IResource outputResource = wsRoot.findMember(path);
-                if (outputResource != null && outputResource.getType() == IResource.FOLDER) {
-                    String outputOsPath = outputResource.getLocation().toOSString();
-
-                    list.add(outputOsPath);
-                }
-            }
-        }
-
-        return list.toArray(new String[list.size()]);
-    }
-
-    /**
-     * Returns an array of {@link IJavaProject} matching the provided {@link IProject} objects.
-     * @param projects the IProject objects.
-     * @return an array, always. Can be empty.
-     * @throws CoreException
-     */
-    private IJavaProject[] getJavaProjects(IProject[] projects) throws CoreException {
-        ArrayList<IJavaProject> list = new ArrayList<IJavaProject>();
-
-        for (IProject p : projects) {
-            if (p.isOpen() && p.hasNature(JavaCore.NATURE_ID)) {
-
-                list.add(JavaCore.create(p));
-            }
-        }
-
-        return list.toArray(new IJavaProject[list.size()]);
-    }
-
-    /**
-     * Checks a {@link IFile} to make sure it should be packaged as standard resources.
-     * @param file the IFile representing the file.
-     * @return true if the file should be packaged as standard java resources.
-     */
-    static boolean checkFileForPackaging(IFile file) {
-        String name = file.getName();
-
-        String ext = file.getFileExtension();
-        return JavaResourceFilter.checkFileForPackaging(name, ext);
-    }
-
-    /**
-     * Checks whether an {@link IFolder} and its content is valid for packaging into the .apk as
-     * standard Java resource.
-     * @param folder the {@link IFolder} to check.
-     */
-    static boolean checkFolderForPackaging(IFolder folder) {
-        String name = folder.getName();
-        return JavaResourceFilter.checkFolderForPackaging(name);
-    }
-
-    @Override
-    protected void abortOnBadSetup(IProject project) throws CoreException {
-        super.abortOnBadSetup(project);
-
-        // for this version, we stop on any marker (ie also markers coming from JDT)
-        IMarker[] markers = project.findMarkers(null /*type*/, false /*includeSubtypes*/,
-                IResource.DEPTH_ZERO);
-
-        if (markers.length > 0) {
-            stopBuild("");
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java
deleted file mode 100644
index 2cebd91..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.build.BaseBuilder.BaseDeltaVisitor;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-
-import java.util.ArrayList;
-
-/**
- * Delta resource visitor looking for changes that will trigger a new packaging of an Android
- * application.
- * <p/>
- * This looks for the following changes:
- * <ul>
- * <li>Any change to the AndroidManifest.xml file</li>
- * <li>Any change inside the assets/ folder</li>
- * <li>Any file change inside the res/ folder</li>
- * <li>Any .class file change inside the output folder</li>
- * <li>Any change to the classes.dex inside the output folder</li>
- * <li>Any change to the packaged resources file inside the output folder</li>
- * <li>Any change to a non java/aidl file inside the source folders</li>
- * <li>Any change to .so file inside the lib (native library) folder</li>
- * </ul>
- */
-public class ApkDeltaVisitor extends BaseDeltaVisitor
-        implements IResourceDeltaVisitor {
-
-    /**
-     * compile flag. This is set to true if one of the changed/added/removed
-     * file is a .class file. Upon visiting all the delta resources, if this
-     * flag is true, then we know we'll have to make the "classes.dex" file.
-     */
-    private boolean mConvertToDex = false;
-
-    /**
-     * compile flag. This is set to true if one of the changed/added/removed
-     * file is a resource file. Upon visiting all the delta resources, if
-     * this flag is true, then we know we'll have to make the intermediate
-     * apk file.
-     */
-    private boolean mPackageResources = false;
-    
-    /**
-     * Final package flag. This is set to true if one of the changed/added/removed
-     * file is a non java file (or aidl) in the resource folder. Upon visiting all the
-     * delta resources, if this flag is true, then we know we'll have to make the final
-     * package.
-     */
-    private boolean mMakeFinalPackage = false;
-
-    /** List of source folders. */
-    private ArrayList<IPath> mSourceFolders;
-
-    private IPath mOutputPath;
-
-    private IPath mAssetPath;
-
-    private IPath mResPath;
-
-    private IPath mLibFolder;
-
-    /**
-     * Builds the object with a specified output folder.
-     * @param builder the xml builder using this object to visit the
-     *  resource delta.
-     * @param sourceFolders the list of source folders for the project, relative to the workspace.
-     * @param outputfolder the output folder of the project.
-     */
-    public ApkDeltaVisitor(BaseBuilder builder, ArrayList<IPath> sourceFolders,
-            IFolder outputfolder) {
-        super(builder);
-        mSourceFolders = sourceFolders;
-        
-        if (outputfolder != null) {
-            mOutputPath = outputfolder.getFullPath();
-        }
-        
-        IResource assetFolder = builder.getProject().findMember(SdkConstants.FD_ASSETS);
-        if (assetFolder != null) {
-            mAssetPath = assetFolder.getFullPath();
-        }
-
-        IResource resFolder = builder.getProject().findMember(SdkConstants.FD_RESOURCES);
-        if (resFolder != null) {
-            mResPath = resFolder.getFullPath();
-        }
-        
-        IResource libFolder = builder.getProject().findMember(SdkConstants.FD_NATIVE_LIBS);
-        if (libFolder != null) {
-            mLibFolder = libFolder.getFullPath();
-        }
-    }
-
-    public boolean getConvertToDex() {
-        return mConvertToDex;
-    }
-
-    public boolean getPackageResources() {
-        return mPackageResources;
-    }
-    
-    public boolean getMakeFinalPackage() {
-        return mMakeFinalPackage;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @throws CoreException 
-     *
-     * @see org.eclipse.core.resources.IResourceDeltaVisitor
-     *      #visit(org.eclipse.core.resources.IResourceDelta)
-     */
-    public boolean visit(IResourceDelta delta) throws CoreException {
-        // if all flags are true, we can stop going through the resource delta.
-        if (mConvertToDex && mPackageResources && mMakeFinalPackage) {
-            return false;
-        }
-
-        // we are only going to look for changes in res/, src/ and in
-        // AndroidManifest.xml since the delta visitor goes through the main
-        // folder before its childre we can check when the path segment
-        // count is 2 (format will be /$Project/folder) and make sure we are
-        // processing res/, src/ or AndroidManifest.xml
-        IResource resource = delta.getResource();
-        IPath path = resource.getFullPath();
-        String[] pathSegments = path.segments();
-        int type = resource.getType();
-
-        // since the delta visitor also visits the root we return true if
-        // segments.length = 1
-        if (pathSegments.length == 1) {
-            return true;
-        }
-
-        // check the manifest.
-        if (pathSegments.length == 2 &&
-                AndroidConstants.FN_ANDROID_MANIFEST.equalsIgnoreCase(pathSegments[1])) {
-            // if the manifest changed we have to repackage the
-            // resources.
-            mPackageResources = true;
-            mMakeFinalPackage = true;
-
-            // we don't want to go to the children, not like they are
-            // any for this resource anyway.
-            return false;
-        }
-        
-        // check the other folders.
-        if (mOutputPath != null && mOutputPath.isPrefixOf(path)) {
-            // a resource changed inside the output folder.
-            if (type == IResource.FILE) {
-                // just check this is a .class file. Any modification will
-                // trigger a change in the classes.dex file
-                String ext = resource.getFileExtension();
-                if (AndroidConstants.EXT_CLASS.equalsIgnoreCase(ext)) {
-                    mConvertToDex = true;
-                    mMakeFinalPackage = true;
-    
-                    // no need to check the children, as we are in a package
-                    // and there can only be subpackage children containing
-                    // only .class files
-                    return false;
-                }
-
-                // check for a few files directly in the output folder and force
-                // rebuild if they have been deleted.
-                if (delta.getKind() == IResourceDelta.REMOVED) {
-                    IPath parentPath = path.removeLastSegments(1);
-                    if (mOutputPath.equals(parentPath)) {
-                        String resourceName = resource.getName();
-                        // check if classes.dex was removed
-                        if (resourceName.equalsIgnoreCase(AndroidConstants.FN_CLASSES_DEX)) {
-                            mConvertToDex = true;
-                            mMakeFinalPackage = true;
-                        } else if (resourceName.equalsIgnoreCase(
-                                AndroidConstants.FN_RESOURCES_AP_) ||
-                                AndroidConstants.PATTERN_RESOURCES_S_AP_.matcher(
-                                        resourceName).matches()) {
-                            // or if the default resources.ap_ or a configured version
-                            // (resources-###.ap_) was removed.
-                            mPackageResources = true;
-                            mMakeFinalPackage = true;
-                        }
-                    }
-                }
-            }
-
-            // if this is a folder, we only go visit it if we don't already know
-            // that we need to convert to dex already.
-            return mConvertToDex == false;
-        } else if (mResPath != null && mResPath.isPrefixOf(path)) {
-            // in the res folder we are looking for any file modification
-            // (we don't care about folder being added/removed, only content
-            // is important)
-            if (type == IResource.FILE) {
-                mPackageResources = true;
-                mMakeFinalPackage = true;
-                return false;
-            }
-
-            // for folders, return true only if we don't already know we have to
-            // package the resources.
-            return mPackageResources == false;
-        } else if (mAssetPath != null && mAssetPath.isPrefixOf(path)) {
-            // this is the assets folder that was modified.
-            // we don't care what content was changed. All we care
-            // about is that something changed inside. No need to visit
-            // the children even.
-            mPackageResources = true;
-            mMakeFinalPackage = true;
-            return false;
-        } else if (mLibFolder != null && mLibFolder.isPrefixOf(path)) {
-            // inside the native library folder. Test if the changed resource is a .so file.
-            if (type == IResource.FILE &&
-                    path.getFileExtension().equalsIgnoreCase(AndroidConstants.EXT_NATIVE_LIB)) {
-                mMakeFinalPackage = true;
-                return false; // return false for file.
-            }
-
-            // for folders, return true only if we don't already know we have to make the
-            // final package.
-            return mMakeFinalPackage == false;
-        } else {
-            // we are in a folder that is neither the resource folders, nor the output.
-            // check against all the source folders, unless we already know we need to do
-            // the final package.
-            // This could be a source folder or a folder leading to a source folder.
-            // However we only check this if we don't already know that we need to build the
-            // package anyway
-            if (mMakeFinalPackage == false) {
-                for (IPath sourcePath : mSourceFolders) {
-                    if (sourcePath.isPrefixOf(path)) {
-                        // In the source folders, we are looking for any kind of
-                        // modification related to file that are not java files.
-                        // Also excluded are aidl files, and package.html files
-                        if (type == IResource.FOLDER) {
-                            // always visit the subfolders, unless the folder is not to be included
-                            return ApkBuilder.checkFolderForPackaging((IFolder)resource);
-                        } else if (type == IResource.FILE) {
-                            if (ApkBuilder.checkFileForPackaging((IFile)resource)) {
-                                mMakeFinalPackage = true;
-                            }
-
-                            return false;
-                        }
-                        
-                    }
-                }
-            }
-        }
-        
-        // if the folder is not inside one of the folders we are interested in (res, assets, output,
-        // source folders), it could be a folder leading to them, so we return true.
-        return true;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java
deleted file mode 100644
index 1512d4b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
-import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.xml.sax.SAXException;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Base builder for XML files. This class allows for basic XML parsing with
- * error checking and marking the files for errors/warnings.
- */
-abstract class BaseBuilder extends IncrementalProjectBuilder {
-
-    // TODO: rename the pattern to something that makes sense + javadoc comments.
-
-    /**
-     * Single line aapt warning for skipping files.<br>
-     * "  (skipping hidden file '&lt;file path&gt;'"
-     */
-    private final static Pattern sPattern0Line1 = Pattern.compile(
-            "^\\s+\\(skipping hidden file\\s'(.*)'\\)$"); //$NON-NLS-1$
-
-    /**
-     * First line of dual line aapt error.<br>
-     * "ERROR at line &lt;line&gt;: &lt;error&gt;"<br>
-     * " (Occurred while parsing &lt;path&gt;)"
-     */
-    private final static Pattern sPattern1Line1 = Pattern.compile(
-            "^ERROR\\s+at\\s+line\\s+(\\d+):\\s+(.*)$"); //$NON-NLS-1$
-    /**
-     * Second line of dual line aapt error.<br>
-     * "ERROR at line &lt;line&gt;: &lt;error&gt;"<br>
-     * " (Occurred while parsing &lt;path&gt;)"<br>
-     * @see #sPattern1Line1
-     */
-    private final static Pattern sPattern1Line2 = Pattern.compile(
-            "^\\s+\\(Occurred while parsing\\s+(.*)\\)$");  //$NON-NLS-1$
-    /**
-     * First line of dual line aapt error.<br>
-     * "ERROR: &lt;error&gt;"<br>
-     * "Defined at file &lt;path&gt; line &lt;line&gt;"
-     */
-    private final static Pattern sPattern2Line1 = Pattern.compile(
-            "^ERROR:\\s+(.+)$"); //$NON-NLS-1$
-    /**
-     * Second line of dual line aapt error.<br>
-     * "ERROR: &lt;error&gt;"<br>
-     * "Defined at file &lt;path&gt; line &lt;line&gt;"<br>
-     * @see #sPattern2Line1
-     */
-    private final static Pattern sPattern2Line2 = Pattern.compile(
-            "Defined\\s+at\\s+file\\s+(.+)\\s+line\\s+(\\d+)"); //$NON-NLS-1$
-    /**
-     * Single line aapt error<br>
-     * "&lt;path&gt; line &lt;line&gt;: &lt;error&gt;"
-     */
-    private final static Pattern sPattern3Line1 = Pattern.compile(
-            "^(.+)\\sline\\s(\\d+):\\s(.+)$"); //$NON-NLS-1$
-    /**
-     * First line of dual line aapt error.<br>
-     * "ERROR parsing XML file &lt;path&gt;"<br>
-     * "&lt;error&gt; at line &lt;line&gt;"
-     */
-    private final static Pattern sPattern4Line1 = Pattern.compile(
-            "^Error\\s+parsing\\s+XML\\s+file\\s(.+)$"); //$NON-NLS-1$
-    /**
-     * Second line of dual line aapt error.<br>
-     * "ERROR parsing XML file &lt;path&gt;"<br>
-     * "&lt;error&gt; at line &lt;line&gt;"<br>
-     * @see #sPattern4Line1
-     */
-    private final static Pattern sPattern4Line2 = Pattern.compile(
-            "^(.+)\\s+at\\s+line\\s+(\\d+)$"); //$NON-NLS-1$
-
-    /**
-     * Single line aapt warning<br>
-     * "&lt;path&gt;:&lt;line&gt;: &lt;error&gt;"
-     */
-    private final static Pattern sPattern5Line1 = Pattern.compile(
-            "^(.+?):(\\d+):\\s+WARNING:(.+)$"); //$NON-NLS-1$
-
-    /**
-     * Single line aapt error<br>
-     * "&lt;path&gt;:&lt;line&gt;: &lt;error&gt;"
-     */
-    private final static Pattern sPattern6Line1 = Pattern.compile(
-            "^(.+?):(\\d+):\\s+(.+)$"); //$NON-NLS-1$
-
-    /**
-     * 4 line aapt error<br>
-     * "ERROR: 9-path image &lt;path&gt; malformed"<br>
-     * Line 2 and 3 are taken as-is while line 4 is ignored (it repeats with<br>
-     * 'ERROR: failure processing &lt;path&gt;)
-     */
-    private final static Pattern sPattern7Line1 = Pattern.compile(
-            "^ERROR:\\s+9-patch\\s+image\\s+(.+)\\s+malformed\\.$"); //$NON-NLS-1$
-
-    private final static Pattern sPattern8Line1 = Pattern.compile(
-            "^(invalid resource directory name): (.*)$"); //$NON-NLS-1$
-
-    /**
-     * 2 line aapt error<br>
-     * "ERROR: Invalid configuration: foo"<br>
-     * "                              ^^^"<br>
-     * There's no need to parse the 2nd line.
-     */
-    private final static Pattern sPattern9Line1 = Pattern.compile(
-            "^Invalid configuration: (.+)$"); //$NON-NLS-1$
-
-    /** SAX Parser factory. */
-    private SAXParserFactory mParserFactory;
-
-    /**
-     * Base Resource Delta Visitor to handle XML error
-     */
-    protected static class BaseDeltaVisitor implements XmlErrorListener {
-
-        /** The Xml builder used to validate XML correctness. */
-        protected BaseBuilder mBuilder;
-
-        /**
-         * XML error flag. if true, we keep parsing the ResourceDelta but the
-         * compilation will not happen (we're putting markers)
-         */
-        public boolean mXmlError = false;
-
-        public BaseDeltaVisitor(BaseBuilder builder) {
-            mBuilder = builder;
-        }
-
-        /**
-         * Finds a matching Source folder for the current path. This checkds if the current path
-         * leads to, or is a source folder.
-         * @param sourceFolders The list of source folders
-         * @param pathSegments The segments of the current path
-         * @return The segments of the source folder, or null if no match was found
-         */
-        protected static String[] findMatchingSourceFolder(ArrayList<IPath> sourceFolders,
-                String[] pathSegments) {
-
-            for (IPath p : sourceFolders) {
-                // check if we are inside one of those source class path
-
-                // get the segments
-                String[] srcSegments = p.segments();
-
-                // compare segments. We want the path of the resource
-                // we're visiting to be
-                boolean valid = true;
-                int segmentCount = pathSegments.length;
-
-                for (int i = 0 ; i < segmentCount; i++) {
-                    String s1 = pathSegments[i];
-                    String s2 = srcSegments[i];
-
-                    if (s1.equalsIgnoreCase(s2) == false) {
-                        valid = false;
-                        break;
-                    }
-                }
-
-                if (valid) {
-                    // this folder, or one of this children is a source
-                    // folder!
-                    // we return its segments
-                    return srcSegments;
-                }
-            }
-
-            return null;
-        }
-
-        /**
-         * Sent when an XML error is detected.
-         * @see XmlErrorListener
-         */
-        public void errorFound() {
-            mXmlError = true;
-        }
-    }
-
-    public BaseBuilder() {
-        super();
-        mParserFactory = SAXParserFactory.newInstance();
-
-        // FIXME when the compiled XML support for namespace is in, set this to true.
-        mParserFactory.setNamespaceAware(false);
-    }
-
-    /**
-     * Checks an Xml file for validity. Errors/warnings will be marked on the
-     * file
-     * @param resource the resource to check
-     * @param visitor a valid resource delta visitor
-     */
-    protected final void checkXML(IResource resource, BaseDeltaVisitor visitor) {
-
-        // first make sure this is an xml file
-        if (resource instanceof IFile) {
-            IFile file = (IFile)resource;
-
-            // remove previous markers
-            removeMarkersFromFile(file, AndroidConstants.MARKER_XML);
-
-            // create  the error handler
-            XmlErrorHandler reporter = new XmlErrorHandler(file, visitor);
-            try {
-                // parse
-                getParser().parse(file.getContents(), reporter);
-            } catch (Exception e1) {
-            }
-        }
-    }
-
-    /**
-     * Returns the SAXParserFactory, instantiating it first if it's not already
-     * created.
-     * @return the SAXParserFactory object
-     * @throws ParserConfigurationException
-     * @throws SAXException
-     */
-    protected final SAXParser getParser() throws ParserConfigurationException,
-            SAXException {
-        return mParserFactory.newSAXParser();
-    }
-
-    /**
-     * Adds a marker to the current project.
-     *
-     * @param markerId The id of the marker to add.
-     * @param message the message associated with the mark
-     * @param severity the severity of the marker.
-     */
-    protected final void markProject(String markerId, String message, int severity) {
-        BaseProjectHelper.addMarker(getProject(), markerId, message, severity);
-    }
-
-
-    /**
-     * Removes markers from a file.
-     * @param file The file from which to delete the markers.
-     * @param markerId The id of the markers to remove. If null, all marker of
-     * type <code>IMarker.PROBLEM</code> will be removed.
-     */
-    protected final void removeMarkersFromFile(IFile file, String markerId) {
-        try {
-            if (file.exists()) {
-                file.deleteMarkers(markerId, true, IResource.DEPTH_ZERO);
-            }
-        } catch (CoreException ce) {
-            String msg = String.format(Messages.Marker_Delete_Error, markerId, file.toString());
-            AdtPlugin.printErrorToConsole(getProject(), msg);
-        }
-    }
-
-    /**
-     * Removes markers from a container and its children.
-     * @param folder The container from which to delete the markers.
-     * @param markerId The id of the markers to remove. If null, all marker of
-     * type <code>IMarker.PROBLEM</code> will be removed.
-     */
-    protected final void removeMarkersFromContainer(IContainer folder, String markerId) {
-        try {
-            if (folder.exists()) {
-                folder.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE);
-            }
-        } catch (CoreException ce) {
-            String msg = String.format(Messages.Marker_Delete_Error, markerId, folder.toString());
-            AdtPlugin.printErrorToConsole(getProject(), msg);
-        }
-    }
-
-    /**
-     * Removes markers from a project and its children.
-     * @param project The project from which to delete the markers
-     * @param markerId The id of the markers to remove. If null, all marker of
-     * type <code>IMarker.PROBLEM</code> will be removed.
-     */
-    protected final static void removeMarkersFromProject(IProject project,
-            String markerId) {
-        try {
-            if (project.exists()) {
-                project.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE);
-            }
-        } catch (CoreException ce) {
-            String msg = String.format(Messages.Marker_Delete_Error, markerId, project.getName());
-            AdtPlugin.printErrorToConsole(project, msg);
-        }
-    }
-
-    /**
-     * Get the stderr output of a process and return when the process is done.
-     * @param process The process to get the ouput from
-     * @param results The array to store the stderr output
-     * @return the process return code.
-     * @throws InterruptedException
-     */
-    protected final int grabProcessOutput(final Process process,
-            final ArrayList<String> results)
-            throws InterruptedException {
-        // Due to the limited buffer size on windows for the standard io (stderr, stdout), we
-        // *need* to read both stdout and stderr all the time. If we don't and a process output
-        // a large amount, this could deadlock the process.
-
-        // read the lines as they come. if null is returned, it's
-        // because the process finished
-        new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            results.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        }.start();
-
-        new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                IProject project = getProject();
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
-                                    project, line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-
-        }.start();
-
-        // get the return code from the process
-        return process.waitFor();
-    }
-
-    /**
-     * Parse the output of aapt and mark the incorrect file with error markers
-     *
-     * @param results the output of aapt
-     * @param project the project containing the file to mark
-     * @return true if the parsing failed, false if success.
-     */
-    protected final boolean parseAaptOutput(ArrayList<String> results,
-            IProject project) {
-        // nothing to parse? just return false;
-        if (results.size() == 0) {
-            return false;
-        }
-
-        // get the root of the project so that we can make IFile from full
-        // file path
-        String osRoot = project.getLocation().toOSString();
-
-        Matcher m;
-
-        for (int i = 0; i < results.size(); i++) {
-            String p = results.get(i);
-
-            m = sPattern0Line1.matcher(p);
-            if (m.matches()) {
-                // we ignore those (as this is an ignore message from aapt)
-                continue;
-            }
-
-            m = sPattern1Line1.matcher(p);
-            if (m.matches()) {
-                String lineStr = m.group(1);
-                String msg = m.group(2);
-
-                // get the matcher for the next line.
-                m = getNextLineMatcher(results, ++i, sPattern1Line2);
-                if (m == null) {
-                    return true;
-                }
-
-                String location = m.group(1);
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(location, lineStr, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-                continue;
-            }
-
-            // this needs to be tested before Pattern2 since they both start with 'ERROR:'
-            m = sPattern7Line1.matcher(p);
-            if (m.matches()) {
-                String location = m.group(1);
-                String msg = p; // default msg is the line in case we don't find anything else
-
-                if (++i < results.size()) {
-                    msg = results.get(i).trim();
-                    if (++i < results.size()) {
-                        msg = msg + " - " + results.get(i).trim(); //$NON-NLS-1$
-
-                        // skip the next line
-                        i++;
-                    }
-                }
-
-                // display the error
-                if (checkAndMark(location, null, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-
-                // success, go to the next line
-                continue;
-            }
-
-            m =  sPattern2Line1.matcher(p);
-            if (m.matches()) {
-                // get the msg
-                String msg = m.group(1);
-
-                // get the matcher for the next line.
-                m = getNextLineMatcher(results, ++i, sPattern2Line2);
-                if (m == null) {
-                    return true;
-                }
-
-                String location = m.group(1);
-                String lineStr = m.group(2);
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(location, lineStr, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-                continue;
-            }
-
-            m = sPattern3Line1.matcher(p);
-            if (m.matches()) {
-                String location = m.group(1);
-                String lineStr = m.group(2);
-                String msg = m.group(3);
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(location, lineStr, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-
-                // success, go to the next line
-                continue;
-            }
-
-            m = sPattern4Line1.matcher(p);
-            if (m.matches()) {
-                // get the filename.
-                String location = m.group(1);
-
-                // get the matcher for the next line.
-                m = getNextLineMatcher(results, ++i, sPattern4Line2);
-                if (m == null) {
-                    return true;
-                }
-
-                String msg = m.group(1);
-                String lineStr = m.group(2);
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(location, lineStr, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-
-                // success, go to the next line
-                continue;
-            }
-
-            m = sPattern5Line1.matcher(p);
-            if (m.matches()) {
-                String location = m.group(1);
-                String lineStr = m.group(2);
-                String msg = m.group(3);
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(location, lineStr, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_WARNING) == false) {
-                    return true;
-                }
-
-                // success, go to the next line
-                continue;
-            }
-
-            m = sPattern6Line1.matcher(p);
-            if (m.matches()) {
-                String location = m.group(1);
-                String lineStr = m.group(2);
-                String msg = m.group(3);
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(location, lineStr, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-
-                // success, go to the next line
-                continue;
-            }
-
-            m = sPattern8Line1.matcher(p);
-            if (m.matches()) {
-                String location = m.group(2);
-                String msg = m.group(1);
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(location, null, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-
-                // success, go to the next line
-                continue;
-            }
-
-            m = sPattern9Line1.matcher(p);
-            if (m.matches()) {
-                String badConfig = m.group(1);
-                String msg = String.format("APK Configuration filter '%1$s' is invalid", badConfig);
-
-                // skip the next line
-                i++;
-
-                // check the values and attempt to mark the file.
-                if (checkAndMark(null /*location*/, null, msg, osRoot, project,
-                        AndroidConstants.MARKER_AAPT_PACKAGE, IMarker.SEVERITY_ERROR) == false) {
-                    return true;
-                }
-
-                // success, go to the next line
-                continue;
-            }
-
-            // invalid line format, flag as error, and bail
-            return true;
-        }
-
-        return false;
-    }
-
-
-
-    /**
-     * Saves a String property into the persistent storage of the project.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param value the value to save
-     * @return true if the save succeeded.
-     */
-    protected boolean saveProjectStringProperty(String propertyName, String value) {
-        IProject project = getProject();
-        return ProjectHelper.saveStringProperty(project, propertyName, value);
-    }
-
-
-    /**
-     * Loads a String property from the persistent storage of the project.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @return the property value or null if it was not found.
-     */
-    protected String loadProjectStringProperty(String propertyName) {
-        IProject project = getProject();
-        return ProjectHelper.loadStringProperty(project, propertyName);
-    }
-
-    /**
-     * Saves a property into the persistent storage of the project.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param value the value to save
-     * @return true if the save succeeded.
-     */
-    protected boolean saveProjectBooleanProperty(String propertyName, boolean value) {
-        IProject project = getProject();
-        return ProjectHelper.saveStringProperty(project, propertyName, Boolean.toString(value));
-    }
-
-    /**
-     * Loads a boolean property from the persistent storage of the project.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param defaultValue The default value to return if the property was not found.
-     * @return the property value or the default value if the property was not found.
-     */
-    protected boolean loadProjectBooleanProperty(String propertyName, boolean defaultValue) {
-        IProject project = getProject();
-        return ProjectHelper.loadBooleanProperty(project, propertyName, defaultValue);
-    }
-
-    /**
-     * Saves the path of a resource into the persistent storate of the project.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param resource the resource which path is saved.
-     * @return true if the save succeeded
-     */
-    protected boolean saveProjectResourceProperty(String propertyName, IResource resource) {
-        return ProjectHelper.saveResourceProperty(getProject(), propertyName, resource);
-    }
-
-    /**
-     * Loads the path of a resource from the persistent storage of the project, and returns the
-     * corresponding IResource object.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @return The corresponding IResource object (or children interface) or null
-     */
-    protected IResource loadProjectResourceProperty(String propertyName) {
-        IProject project = getProject();
-        return ProjectHelper.loadResourceProperty(project, propertyName);
-    }
-
-    /**
-     * Check if the parameters gotten from the error output are valid, and mark
-     * the file with an AAPT marker.
-     * @param location the full OS path of the error file. If null, the project is marked
-     * @param lineStr
-     * @param message
-     * @param root The root directory of the project, in OS specific format.
-     * @param project
-     * @param markerId The marker id to put.
-     * @param severity The severity of the marker to put (IMarker.SEVERITY_*)
-     * @return true if the parameters were valid and the file was marked successfully.
-     *
-     * @see IMarker
-     */
-    private final  boolean checkAndMark(String location, String lineStr,
-            String message, String root, IProject project, String markerId, int severity) {
-        // check this is in fact a file
-        if (location != null) {
-            File f = new File(location);
-            if (f.exists() == false) {
-                return false;
-            }
-        }
-
-        // get the line number
-        int line = -1; // default value for error with no line.
-
-        if (lineStr != null) {
-            try {
-                line = Integer.parseInt(lineStr);
-            } catch (NumberFormatException e) {
-                // looks like the string we extracted wasn't a valid
-                // file number. Parsing failed and we return true
-                return false;
-            }
-        }
-
-        // add the marker
-        IResource f2 = project;
-        if (location != null) {
-            f2 = getResourceFromFullPath(location, root, project);
-            if (f2 == null) {
-                return false;
-            }
-        }
-
-        // check if there's a similar marker already, since aapt is launched twice
-        boolean markerAlreadyExists = false;
-        try {
-            IMarker[] markers = f2.findMarkers(markerId, true, IResource.DEPTH_ZERO);
-
-            for (IMarker marker : markers) {
-                int tmpLine = marker.getAttribute(IMarker.LINE_NUMBER, -1);
-                if (tmpLine != line) {
-                    break;
-                }
-
-                int tmpSeverity = marker.getAttribute(IMarker.SEVERITY, -1);
-                if (tmpSeverity != severity) {
-                    break;
-                }
-
-                String tmpMsg = marker.getAttribute(IMarker.MESSAGE, null);
-                if (tmpMsg == null || tmpMsg.equals(message) == false) {
-                    break;
-                }
-
-                // if we're here, all the marker attributes are equals, we found it
-                // and exit
-                markerAlreadyExists = true;
-                break;
-            }
-
-        } catch (CoreException e) {
-            // if we couldn't get the markers, then we just mark the file again
-            // (since markerAlreadyExists is initialized to false, we do nothing)
-        }
-
-        if (markerAlreadyExists == false) {
-            if (line != -1) {
-                BaseProjectHelper.addMarker(f2, markerId, message, line,
-                        severity);
-            } else {
-                BaseProjectHelper.addMarker(f2, markerId, message, severity);
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns a matching matcher for the next line
-     * @param lines The array of lines
-     * @param nextIndex The index of the next line
-     * @param pattern The pattern to match
-     * @return null if error or no match, the matcher otherwise.
-     */
-    private final Matcher getNextLineMatcher(ArrayList<String> lines,
-            int nextIndex, Pattern pattern) {
-        // unless we can't, because we reached the last line
-        if (nextIndex == lines.size()) {
-            // we expected a 2nd line, so we flag as error
-            // and we bail
-            return null;
-        }
-
-        Matcher m = pattern.matcher(lines.get(nextIndex));
-        if (m.matches()) {
-           return m;
-        }
-
-        return null;
-    }
-
-    private IResource getResourceFromFullPath(String filename, String root,
-            IProject project) {
-        if (filename.startsWith(root)) {
-            String file = filename.substring(root.length());
-
-            // get the resource
-            IResource r = project.findMember(file);
-
-            // if the resource is valid, we add the marker
-            if (r.exists()) {
-                return r;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns an array of external jar files used by the project.
-     * @return an array of OS-specific absolute file paths
-     */
-    protected final String[] getExternalJars() {
-        // get the current project
-        IProject project = getProject();
-
-        // get a java project from it
-        IJavaProject javaProject = JavaCore.create(project);
-
-        IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
-
-        ArrayList<String> oslibraryList = new ArrayList<String>();
-        IClasspathEntry[] classpaths = javaProject.readRawClasspath();
-        if (classpaths != null) {
-            for (IClasspathEntry e : classpaths) {
-                if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY ||
-                        e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
-                    // if this is a classpath variable reference, we resolve it.
-                    if (e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
-                        e = JavaCore.getResolvedClasspathEntry(e);
-                    }
-
-                    // get the IPath
-                    IPath path = e.getPath();
-
-                    // check the name ends with .jar
-                    if (AndroidConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
-                        boolean local = false;
-                        IResource resource = wsRoot.findMember(path);
-                        if (resource != null && resource.exists() &&
-                                resource.getType() == IResource.FILE) {
-                            local = true;
-                            oslibraryList.add(resource.getLocation().toOSString());
-                        }
-
-                        if (local == false) {
-                            // if the jar path doesn't match a workspace resource,
-                            // then we get an OSString and check if this links to a valid file.
-                            String osFullPath = path.toOSString();
-
-                            File f = new File(osFullPath);
-                            if (f.exists()) {
-                                oslibraryList.add(osFullPath);
-                            } else {
-                                String message = String.format( Messages.Couldnt_Locate_s_Error,
-                                        path);
-                                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
-                                        project, message);
-
-                                // Also put a warning marker on the project
-                                markProject(AdtConstants.MARKER_ADT, message,
-                                        IMarker.SEVERITY_WARNING);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return oslibraryList.toArray(new String[oslibraryList.size()]);
-    }
-
-    /**
-     * Aborts the build if the SDK/project setups are broken. This does not
-     * display any errors.
-     *
-     * @param project The {@link IJavaProject} being compiled.
-     * @throws CoreException
-     */
-    protected void abortOnBadSetup(IProject project) throws CoreException {
-        // check if we have finished loading the SDK.
-        if (AdtPlugin.getDefault().getSdkLoadStatus() != LoadStatus.LOADED) {
-            // we exit silently
-            stopBuild("SDK is not loaded yet");
-        }
-
-        // abort if there are TARGET or ADT type markers
-        IMarker[] markers = project.findMarkers(AdtConstants.MARKER_TARGET,
-                false /*includeSubtypes*/, IResource.DEPTH_ZERO);
-
-        if (markers.length > 0) {
-            stopBuild("");
-        }
-
-        markers = project.findMarkers(AdtConstants.MARKER_ADT, false /*includeSubtypes*/,
-                IResource.DEPTH_ZERO);
-
-        if (markers.length > 0) {
-            stopBuild("");
-        }
-    }
-
-    /**
-     * Throws an exception to cancel the build.
-     *
-     * @param error the error message
-     * @param args the printf-style arguments to the error message.
-     * @throws CoreException
-     */
-    protected final void stopBuild(String error, Object... args) throws CoreException {
-        throw new CoreException(new Status(IStatus.CANCEL, AdtPlugin.PLUGIN_ID,
-                String.format(error, args)));
-    }
-
-    /**
-     * Recursively delete all the derived resources.
-     */
-    protected void removeDerivedResources(IResource resource, IProgressMonitor monitor)
-            throws CoreException {
-        if (resource.exists()) {
-            if (resource.isDerived()) {
-                resource.delete(true, new SubProgressMonitor(monitor, 10));
-            } else if (resource.getType() == IResource.FOLDER) {
-                IFolder folder = (IFolder)resource;
-                IResource[] members = folder.members();
-                for (IResource member : members) {
-                    removeDerivedResources(member, monitor);
-                }
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java
deleted file mode 100644
index c1698da..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java
+++ /dev/null
@@ -1,137 +0,0 @@
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-    private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.internal.build.build_messages"; //$NON-NLS-1$
-
-    public static String AAPT_Error;
-
-    public static String AAPT_Exec_Error;
-
-    public static String Added_s_s_Needs_Updating;
-
-    public static String AIDL_Exec_Error;
-
-    public static String AIDL_Java_Conflict;
-
-    public static String ApkBuilder_Certificate_Expired_on_s;
-
-    public static String ApkBuilder_JAVA_HOME_is_s;
-
-    public static String ApkBuilder_Packaging_s;
-
-    public static String ApkBuilder_Packaging_s_into_s;
-
-    public static String ApkBuilder_s_Conflict_with_file_s;
-
-    public static String ApkBuilder_Signing_Key_Creation_s;
-
-    public static String ApkBuilder_Unable_To_Gey_Key;
-
-    public static String ApkBuilder_UnableBuild_Dex_Not_loaded;
-
-    public static String ApkBuilder_Update_or_Execute_manually_s;
-
-    public static String ApkBuilder_Using_Default_Key;
-
-    public static String ApkBuilder_Using_s_To_Sign;
-
-    public static String Checking_Package_Change;
-
-    public static String Compiler_Compliance_Error;
-
-    public static String Couldnt_Locate_s_Error;
-
-    public static String Dalvik_Error_d;
-
-    public static String Dalvik_Error_s;
-
-    public static String Delete_Obsolete_Error;
-
-    public static String DexWrapper_Dex_Loader;
-
-    public static String DexWrapper_Failed_to_load_s;
-
-    public static String DexWrapper_s_does_not_exists;
-
-    public static String DexWrapper_SecuryEx_Unable_To_Find_API;
-
-    public static String DexWrapper_SecuryEx_Unable_To_Find_Field;
-
-    public static String DexWrapper_SecuryEx_Unable_To_Find_Method;
-
-    public static String DexWrapper_Unable_To_Execute_Dex_s;
-
-    public static String DX_Jar_Error;
-
-    public static String Failed_To_Get_Output;
-
-    public static String Final_Archive_Error_s;
-
-    public static String Incompatible_VM_Warning;
-
-    public static String Marker_Delete_Error;
-
-    public static String No_SDK_Setup_Error;
-
-    public static String Nothing_To_Compile;
-
-    public static String Output_Missing;
-
-    public static String Package_s_Doesnt_Exist_Error;
-
-    public static String Preparing_Generated_Files;
-
-    public static String Project_Has_Errors;
-
-    public static String Refreshing_Res;
-
-    public static String Removing_Generated_Classes;
-
-    public static String Requires_1_5_Error;
-
-    public static String Requires_Class_Compatibility_5;
-
-    public static String Requires_Compiler_Compliance_5;
-
-    public static String Requires_Source_Compatibility_5;
-
-    public static String s_Contains_Xml_Error;
-
-    public static String s_Doesnt_Declare_Package_Error;
-
-    public static String s_File_Missing;
-
-    public static String s_Missing_Repackaging;
-
-    public static String s_Modified_Manually_Recreating_s;
-
-    public static String s_Modified_Recreating_s;
-
-    public static String s_Removed_Recreating_s;
-
-    public static String s_Removed_s_Needs_Updating;
-
-    public static String Start_Full_Apk_Build;
-
-    public static String Start_Full_Pre_Compiler;
-
-    public static String Start_Inc_Apk_Build;
-
-    public static String Start_Inc_Pre_Compiler;
-
-    public static String Unparsed_AAPT_Errors;
-
-    public static String Unparsed_AIDL_Errors;
-
-    public static String Xml_Error;
-    static {
-        // initialize resource bundle
-        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
-    }
-
-    private Messages() {
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java
deleted file mode 100644
index 5b6293c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.FixLaunchConfig;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.BasicXmlErrorListener;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.xml.AndroidManifest;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Pre Java Compiler.
- * This incremental builder performs 2 tasks:
- * <ul>
- * <li>compiles the resources located in the res/ folder, along with the
- * AndroidManifest.xml file into the R.java class.</li>
- * <li>compiles any .aidl files into a corresponding java file.</li>
- * </ul>
- *
- */
-public class PreCompilerBuilder extends BaseBuilder {
-
-    public static final String ID = "com.android.ide.eclipse.adt.PreCompilerBuilder"; //$NON-NLS-1$
-
-    private static final String PROPERTY_PACKAGE = "manifestPackage"; //$NON-NLS-1$
-
-    private static final String PROPERTY_COMPILE_RESOURCES = "compileResources"; //$NON-NLS-1$
-    private static final String PROPERTY_COMPILE_AIDL = "compileAidl"; //$NON-NLS-1$
-
-    /**
-     * Single line aidl error<br>
-     * "&lt;path&gt;:&lt;line&gt;: &lt;error&gt;"
-     * or
-     * "&lt;path&gt;:&lt;line&gt; &lt;error&gt;"
-     */
-    private static Pattern sAidlPattern1 = Pattern.compile("^(.+?):(\\d+):?\\s(.+)$"); //$NON-NLS-1$
-
-    /**
-     * Data to temporarly store aidl source file information
-     */
-    static class AidlData {
-        IFile aidlFile;
-        IFolder sourceFolder;
-
-        AidlData(IFolder sourceFolder, IFile aidlFile) {
-            this.sourceFolder = sourceFolder;
-            this.aidlFile = aidlFile;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-
-            if (obj instanceof AidlData) {
-                AidlData file = (AidlData)obj;
-                return aidlFile.equals(file.aidlFile) && sourceFolder.equals(file.sourceFolder);
-            }
-
-            return false;
-        }
-    }
-
-    /**
-     * Resource Compile flag. This flag is reset to false after each successful compilation, and
-     * stored in the project persistent properties. This allows the builder to remember its state
-     * when the project is closed/opened.
-     */
-    private boolean mMustCompileResources = false;
-
-    /** List of .aidl files found that are modified or new. */
-    private final ArrayList<AidlData> mAidlToCompile = new ArrayList<AidlData>();
-
-    /** List of .aidl files that have been removed. */
-    private final ArrayList<AidlData> mAidlToRemove = new ArrayList<AidlData>();
-
-    /** cache of the java package defined in the manifest */
-    private String mManifestPackage;
-
-    /** Output folder for generated Java File. Created on the Builder init
-     * @see #startupOnInitialize()
-     */
-    private IFolder mGenFolder;
-
-    /**
-     * Progress monitor used at the end of every build to refresh the content of the 'gen' folder
-     * and set the generated files as derived.
-     */
-    private DerivedProgressMonitor mDerivedProgressMonitor;
-
-    /**
-     * Progress monitor waiting the end of the process to set a persistent value
-     * in a file. This is typically used in conjunction with <code>IResource.refresh()</code>,
-     * since this call is asysnchronous, and we need to wait for it to finish for the file
-     * to be known by eclipse, before we can call <code>resource.setPersistentProperty</code> on
-     * a new file.
-     */
-    private static class DerivedProgressMonitor implements IProgressMonitor {
-        private boolean mCancelled = false;
-        private final ArrayList<IFile> mFileList = new ArrayList<IFile>();
-        private boolean mDone = false;
-        public DerivedProgressMonitor() {
-        }
-
-        void addFile(IFile file) {
-            mFileList.add(file);
-        }
-
-        void reset() {
-            mFileList.clear();
-            mDone = false;
-        }
-
-        public void beginTask(String name, int totalWork) {
-        }
-
-        public void done() {
-            if (mDone == false) {
-                mDone = true;
-                for (IFile file : mFileList) {
-                    if (file.exists()) {
-                        try {
-                            file.setDerived(true);
-                        } catch (CoreException e) {
-                            // This really shouldn't happen since we check that the resource exist.
-                            // Worst case scenario, the resource isn't marked as derived.
-                        }
-                    }
-                }
-            }
-        }
-
-        public void internalWorked(double work) {
-        }
-
-        public boolean isCanceled() {
-            return mCancelled;
-        }
-
-        public void setCanceled(boolean value) {
-            mCancelled = value;
-        }
-
-        public void setTaskName(String name) {
-        }
-
-        public void subTask(String name) {
-        }
-
-        public void worked(int work) {
-        }
-    }
-
-    public PreCompilerBuilder() {
-        super();
-    }
-
-    // build() returns a list of project from which this project depends for future compilation.
-    @SuppressWarnings("unchecked")
-    @Override
-    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
-            throws CoreException {
-        try {
-            mDerivedProgressMonitor.reset();
-
-            // First thing we do is go through the resource delta to not
-            // lose it if we have to abort the build for any reason.
-
-            // get the project objects
-            IProject project = getProject();
-
-            // Top level check to make sure the build can move forward.
-            abortOnBadSetup(project);
-
-            IJavaProject javaProject = JavaCore.create(project);
-            IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
-
-            // now we need to get the classpath list
-            ArrayList<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(
-                    javaProject);
-
-            PreCompilerDeltaVisitor dv = null;
-            String javaPackage = null;
-            String minSdkVersion = null;
-
-            if (kind == FULL_BUILD) {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                        Messages.Start_Full_Pre_Compiler);
-                mMustCompileResources = true;
-                buildAidlCompilationList(project, sourceFolderPathList);
-            } else {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                        Messages.Start_Inc_Pre_Compiler);
-
-                // Go through the resources and see if something changed.
-                // Even if the mCompileResources flag is true from a previously aborted
-                // build, we need to go through the Resource delta to get a possible
-                // list of aidl files to compile/remove.
-                IResourceDelta delta = getDelta(project);
-                if (delta == null) {
-                    mMustCompileResources = true;
-                    buildAidlCompilationList(project, sourceFolderPathList);
-                } else {
-                    dv = new PreCompilerDeltaVisitor(this, sourceFolderPathList);
-                    delta.accept(dv);
-
-                    // record the state
-                    mMustCompileResources |= dv.getCompileResources();
-
-                    if (dv.getForceAidlCompile()) {
-                        buildAidlCompilationList(project, sourceFolderPathList);
-                    } else {
-                        // handle aidl modification, and update mMustCompileAidl
-                        mergeAidlFileModifications(dv.getAidlToCompile(),
-                                dv.getAidlToRemove());
-                    }
-
-                    // get the java package from the visitor
-                    javaPackage = dv.getManifestPackage();
-                    minSdkVersion = dv.getMinSdkVersion();
-                }
-            }
-
-            // store the build status in the persistent storage
-            saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES , mMustCompileResources);
-
-            // if there was some XML errors, we just return w/o doing
-            // anything since we've put some markers in the files anyway.
-            if (dv != null && dv.mXmlError) {
-                AdtPlugin.printErrorToConsole(project, Messages.Xml_Error);
-
-                // This interrupts the build. The next builders will not run.
-                stopBuild(Messages.Xml_Error);
-            }
-
-
-            // get the manifest file
-            IFile manifest = AndroidManifestParser.getManifest(project);
-
-            if (manifest == null) {
-                String msg = String.format(Messages.s_File_Missing,
-                        AndroidConstants.FN_ANDROID_MANIFEST);
-                AdtPlugin.printErrorToConsole(project, msg);
-                markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
-                // This interrupts the build. The next builders will not run.
-                stopBuild(msg);
-
-                // TODO: document whether code below that uses manifest (which is now guaranteed
-                // to be null) will actually be executed or not.
-            }
-
-            // lets check the XML of the manifest first, if that hasn't been done by the
-            // resource delta visitor yet.
-            if (dv == null || dv.getCheckedManifestXml() == false) {
-                BasicXmlErrorListener errorListener = new BasicXmlErrorListener();
-                AndroidManifestParser parser = BaseProjectHelper.parseManifestForError(manifest,
-                        errorListener);
-
-                if (errorListener.mHasXmlError == true) {
-                    // there was an error in the manifest, its file has been marked,
-                    // by the XmlErrorHandler.
-                    // We return;
-                    String msg = String.format(Messages.s_Contains_Xml_Error,
-                            AndroidConstants.FN_ANDROID_MANIFEST);
-                    AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
-
-                    // This interrupts the build. The next builders will not run.
-                    stopBuild(msg);
-                }
-
-                // get the java package from the parser
-                javaPackage = parser.getPackage();
-                minSdkVersion = parser.getApiLevelRequirement();
-            }
-
-            if (minSdkVersion != null) {
-                int minSdkValue = -1;
-                try {
-                    minSdkValue = Integer.parseInt(minSdkVersion);
-                } catch (NumberFormatException e) {
-                    // it's ok, it means minSdkVersion contains a (hopefully) valid codename.
-                }
-
-                AndroidVersion projectVersion = projectTarget.getVersion();
-
-                if (minSdkValue != -1) {
-                    String codename = projectVersion.getCodename();
-                    if (codename != null) {
-                        // integer minSdk when the target is a preview => fatal error
-                        String msg = String.format(
-                                "Platform %1$s is a preview and requires appication manifest to set %2$s to '%1$s'",
-                                codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
-                        AdtPlugin.printErrorToConsole(project, msg);
-                        BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
-                                IMarker.SEVERITY_ERROR);
-                        stopBuild(msg);
-                    } else if (minSdkValue < projectVersion.getApiLevel()) {
-                        // integer minSdk is not high enough for the target => warning
-                        String msg = String.format(
-                                "Attribute %1$s (%2$d) is lower than the project target API level (%3$d)",
-                                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
-                                minSdkValue, projectVersion.getApiLevel());
-                        AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
-                        BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
-                                IMarker.SEVERITY_WARNING);
-                    } else if (minSdkValue > projectVersion.getApiLevel()) {
-                        // integer minSdk is too high for the target => warning
-                        String msg = String.format(
-                                "Attribute %1$s (%2$d) is higher than the project target API level (%3$d)",
-                                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
-                                minSdkValue, projectVersion.getApiLevel());
-                        AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
-                        BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
-                                IMarker.SEVERITY_WARNING);
-                    }
-                } else {
-                    // looks like the min sdk is a codename, check it matches the codename
-                    // of the platform
-                    String codename = projectVersion.getCodename();
-                    if (codename == null) {
-                        // platform is not a preview => fatal error
-                        String msg = String.format(
-                                "Manifest attribute '%1$s' is set to '%2$s'. Integer is expected.",
-                                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, minSdkVersion);
-                        AdtPlugin.printErrorToConsole(project, msg);
-                        BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
-                                IMarker.SEVERITY_ERROR);
-                        stopBuild(msg);
-                    } else if (codename.equals(minSdkVersion) == false) {
-                        // platform and manifest codenames don't match => fatal error.
-                        String msg = String.format(
-                                "Value of manifest attribute '%1$s' does not match platform codename '%2$s'",
-                                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, codename);
-                        AdtPlugin.printErrorToConsole(project, msg);
-                        BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
-                                IMarker.SEVERITY_ERROR);
-                        stopBuild(msg);
-                    }
-                }
-            } else if (projectTarget.getVersion().isPreview()) {
-                // else the minSdkVersion is not set but we are using a preview target.
-                // Display an error
-                String codename = projectTarget.getVersion().getCodename();
-                String msg = String.format(
-                        "Platform %1$s is a preview and requires appication manifests to set %2$s to '%1$s'",
-                        codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
-                AdtPlugin.printErrorToConsole(project, msg);
-                BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
-                        IMarker.SEVERITY_ERROR);
-                stopBuild(msg);
-            }
-
-            if (javaPackage == null || javaPackage.length() == 0) {
-                // looks like the AndroidManifest file isn't valid.
-                String msg = String.format(Messages.s_Doesnt_Declare_Package_Error,
-                        AndroidConstants.FN_ANDROID_MANIFEST);
-                AdtPlugin.printErrorToConsole(project, msg);
-                markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
-                // This interrupts the build. The next builders will not run.
-                stopBuild(msg);
-
-                // TODO: document whether code below that uses javaPackage (which is now guaranteed
-                // to be null) will actually be executed or not.
-            }
-
-            // at this point we have the java package. We need to make sure it's not a different
-            // package than the previous one that were built.
-            if (javaPackage != null && javaPackage.equals(mManifestPackage) == false) {
-                // The manifest package has changed, the user may want to update
-                // the launch configuration
-                if (mManifestPackage != null) {
-                    AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                            Messages.Checking_Package_Change);
-
-                    FixLaunchConfig flc = new FixLaunchConfig(project, mManifestPackage,
-                            javaPackage);
-                    flc.start();
-                }
-
-                // now we delete the generated classes from their previous location
-                deleteObsoleteGeneratedClass(AndroidConstants.FN_RESOURCE_CLASS,
-                        mManifestPackage);
-                deleteObsoleteGeneratedClass(AndroidConstants.FN_MANIFEST_CLASS,
-                        mManifestPackage);
-
-                // record the new manifest package, and save it.
-                mManifestPackage = javaPackage;
-                saveProjectStringProperty(PROPERTY_PACKAGE, mManifestPackage);
-            }
-
-            if (mMustCompileResources) {
-                // we need to figure out where to store the R class.
-                // get the parent folder for R.java and update mManifestPackageSourceFolder
-                IFolder packageFolder = getGenManifestPackageFolder(project);
-
-                // get the resource folder
-                IFolder resFolder = project.getFolder(AndroidConstants.WS_RESOURCES);
-
-                // get the file system path
-                IPath outputLocation = mGenFolder.getLocation();
-                IPath resLocation = resFolder.getLocation();
-                IPath manifestLocation = manifest == null ? null : manifest.getLocation();
-
-                // those locations have to exist for us to do something!
-                if (outputLocation != null && resLocation != null
-                        && manifestLocation != null) {
-                    String osOutputPath = outputLocation.toOSString();
-                    String osResPath = resLocation.toOSString();
-                    String osManifestPath = manifestLocation.toOSString();
-
-                    // remove the aapt markers
-                    removeMarkersFromFile(manifest, AndroidConstants.MARKER_AAPT_COMPILE);
-                    removeMarkersFromContainer(resFolder, AndroidConstants.MARKER_AAPT_COMPILE);
-
-                    AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                            Messages.Preparing_Generated_Files);
-
-                    // since the R.java file may be already existing in read-only
-                    // mode we need to make it readable so that aapt can overwrite
-                    // it
-                    IFile rJavaFile = packageFolder.getFile(AndroidConstants.FN_RESOURCE_CLASS);
-
-                    // do the same for the Manifest.java class
-                    IFile manifestJavaFile = packageFolder.getFile(
-                            AndroidConstants.FN_MANIFEST_CLASS);
-
-                    // we actually need to delete the manifest.java as it may become empty and
-                    // in this case aapt doesn't generate an empty one, but instead doesn't
-                    // touch it.
-                    manifestJavaFile.delete(true, null);
-
-                    // launch aapt: create the command line
-                    ArrayList<String> array = new ArrayList<String>();
-                    array.add(projectTarget.getPath(IAndroidTarget.AAPT));
-                    array.add("package"); //$NON-NLS-1$
-                    array.add("-m"); //$NON-NLS-1$
-                    if (AdtPlugin.getBuildVerbosity() == AdtConstants.BUILD_VERBOSE) {
-                        array.add("-v"); //$NON-NLS-1$
-                    }
-                    array.add("-J"); //$NON-NLS-1$
-                    array.add(osOutputPath);
-                    array.add("-M"); //$NON-NLS-1$
-                    array.add(osManifestPath);
-                    array.add("-S"); //$NON-NLS-1$
-                    array.add(osResPath);
-                    array.add("-I"); //$NON-NLS-1$
-                    array.add(projectTarget.getPath(IAndroidTarget.ANDROID_JAR));
-
-                    if (AdtPlugin.getBuildVerbosity() == AdtConstants.BUILD_VERBOSE) {
-                        StringBuilder sb = new StringBuilder();
-                        for (String c : array) {
-                            sb.append(c);
-                            sb.append(' ');
-                        }
-                        String cmd_line = sb.toString();
-                        AdtPlugin.printToConsole(project, cmd_line);
-                    }
-
-                    // launch
-                    int execError = 1;
-                    try {
-                        // launch the command line process
-                        Process process = Runtime.getRuntime().exec(
-                                array.toArray(new String[array.size()]));
-
-                        // list to store each line of stderr
-                        ArrayList<String> results = new ArrayList<String>();
-
-                        // get the output and return code from the process
-                        execError = grabProcessOutput(process, results);
-
-                        // attempt to parse the error output
-                        boolean parsingError = parseAaptOutput(results, project);
-
-                        // if we couldn't parse the output we display it in the console.
-                        if (parsingError) {
-                            if (execError != 0) {
-                                AdtPlugin.printErrorToConsole(project, results.toArray());
-                            } else {
-                                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_NORMAL,
-                                        project, results.toArray());
-                            }
-                        }
-
-                        if (execError != 0) {
-                            // if the exec failed, and we couldn't parse the error output
-                            // (and therefore not all files that should have been marked,
-                            // were marked), we put a generic marker on the project and abort.
-                            if (parsingError) {
-                                markProject(AdtConstants.MARKER_ADT, Messages.Unparsed_AAPT_Errors,
-                                        IMarker.SEVERITY_ERROR);
-                            }
-
-                            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                                    Messages.AAPT_Error);
-
-                            // abort if exec failed.
-                            // This interrupts the build. The next builders will not run.
-                            stopBuild(Messages.AAPT_Error);
-                        }
-                    } catch (IOException e1) {
-                        // something happen while executing the process,
-                        // mark the project and exit
-                        String msg = String.format(Messages.AAPT_Exec_Error, array.get(0));
-                        markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
-                        // This interrupts the build. The next builders will not run.
-                        stopBuild(msg);
-                    } catch (InterruptedException e) {
-                        // we got interrupted waiting for the process to end...
-                        // mark the project and exit
-                        String msg = String.format(Messages.AAPT_Exec_Error, array.get(0));
-                        markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
-                        // This interrupts the build. The next builders will not run.
-                        stopBuild(msg);
-                    }
-
-                    // if the return code was OK, we refresh the folder that
-                    // contains R.java to force a java recompile.
-                    if (execError == 0) {
-                        // now add the R.java/Manifest.java to the list of file to be marked
-                        // as derived.
-                        mDerivedProgressMonitor.addFile(rJavaFile);
-                        mDerivedProgressMonitor.addFile(manifestJavaFile);
-
-                        // build has been done. reset the state of the builder
-                        mMustCompileResources = false;
-
-                        // and store it
-                        saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES,
-                                mMustCompileResources);
-                    }
-                }
-            } else {
-                // nothing to do
-            }
-
-            // now handle the aidl stuff.
-            boolean aidlStatus = handleAidl(projectTarget, sourceFolderPathList, monitor);
-
-            if (aidlStatus == false && mMustCompileResources == false) {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                        Messages.Nothing_To_Compile);
-            }
-        } finally {
-            // refresh the 'gen' source folder. Once this is done with the custom progress
-            // monitor to mark all new files as derived
-            mGenFolder.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
-        }
-
-        return null;
-    }
-
-    @Override
-    protected void clean(IProgressMonitor monitor) throws CoreException {
-        super.clean(monitor);
-
-        AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
-                Messages.Removing_Generated_Classes);
-
-        // remove all the derived resources from the 'gen' source folder.
-        removeDerivedResources(mGenFolder, monitor);
-    }
-
-    @Override
-    protected void startupOnInitialize() {
-        super.startupOnInitialize();
-
-        mDerivedProgressMonitor = new DerivedProgressMonitor();
-
-        IProject project = getProject();
-
-        // load the previous IFolder and java package.
-        mManifestPackage = loadProjectStringProperty(PROPERTY_PACKAGE);
-
-        // get the source folder in which all the Java files are created
-        mGenFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES);
-
-        // Load the current compile flags. We ask for true if not found to force a
-        // recompile.
-        mMustCompileResources = loadProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, true);
-        boolean mustCompileAidl = loadProjectBooleanProperty(PROPERTY_COMPILE_AIDL, true);
-
-        // if we stored that we have to compile some aidl, we build the list that will compile them
-        // all
-        if (mustCompileAidl) {
-            IJavaProject javaProject = JavaCore.create(project);
-            ArrayList<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(
-                    javaProject);
-
-            buildAidlCompilationList(project, sourceFolderPathList);
-        }
-    }
-
-    /**
-     * Delete the a generated java class associated with the specified java package.
-     * @param filename Name of the generated file to remove.
-     * @param javaPackage the old java package
-     */
-    private void deleteObsoleteGeneratedClass(String filename, String javaPackage) {
-        if (javaPackage == null) {
-            return;
-        }
-
-        IPath packagePath = getJavaPackagePath(javaPackage);
-        IPath iPath = packagePath.append(filename);
-
-        // Find a matching resource object.
-        IResource javaFile = mGenFolder.findMember(iPath);
-        if (javaFile != null && javaFile.exists() && javaFile.getType() == IResource.FILE) {
-            try {
-                // delete
-                javaFile.delete(true, null);
-
-                // refresh parent
-                javaFile.getParent().refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
-
-            } catch (CoreException e) {
-                // failed to delete it, the user will have to delete it manually.
-                String message = String.format(Messages.Delete_Obsolete_Error,
-                        javaFile.getFullPath());
-                IProject project = getProject();
-                AdtPlugin.printErrorToConsole(project, message);
-                AdtPlugin.printErrorToConsole(project, e.getMessage());
-            }
-        }
-    }
-
-    /**
-     * Creates a relative {@link IPath} from a java package.
-     * @param javaPackageName the java package.
-     */
-    private IPath getJavaPackagePath(String javaPackageName) {
-        // convert the java package into path
-        String[] segments = javaPackageName.split(AndroidConstants.RE_DOT);
-
-        StringBuilder path = new StringBuilder();
-        for (String s : segments) {
-           path.append(AndroidConstants.WS_SEP_CHAR);
-           path.append(s);
-        }
-
-        return new Path(path.toString());
-    }
-
-    /**
-     * Returns an {@link IFolder} (located inside the 'gen' source folder), that matches the
-     * package defined in the manifest. This {@link IFolder} may not actually exist
-     * (aapt will create it anyway).
-     * @param project The project.
-     * @return the {@link IFolder} that will contain the R class or null if the folder was not found.
-     * @throws CoreException
-     */
-    private IFolder getGenManifestPackageFolder(IProject project)
-            throws CoreException {
-        // get the path for the package
-        IPath packagePath = getJavaPackagePath(mManifestPackage);
-
-        // get a folder for this path under the 'gen' source folder, and return it.
-        // This IFolder may not reference an actual existing folder.
-        return mGenFolder.getFolder(packagePath);
-    }
-
-    /**
-     * Compiles aidl files into java. This will also removes old java files
-     * created from aidl files that are now gone.
-     * @param projectTarget Target of the project
-     * @param sourceFolders the list of source folders, relative to the workspace.
-     * @param monitor the projess monitor
-     * @returns true if it did something
-     * @throws CoreException
-     */
-    private boolean handleAidl(IAndroidTarget projectTarget, ArrayList<IPath> sourceFolders,
-            IProgressMonitor monitor) throws CoreException {
-        if (mAidlToCompile.size() == 0 && mAidlToRemove.size() == 0) {
-            return false;
-        }
-
-        // create the command line
-        String[] command = new String[4 + sourceFolders.size()];
-        int index = 0;
-        command[index++] = projectTarget.getPath(IAndroidTarget.AIDL);
-        command[index++] = "-p" + Sdk.getCurrent().getTarget(getProject()).getPath( //$NON-NLS-1$
-                IAndroidTarget.ANDROID_AIDL);
-
-        // since the path are relative to the workspace and not the project itself, we need
-        // the workspace root.
-        IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
-        for (IPath p : sourceFolders) {
-            IFolder f = wsRoot.getFolder(p);
-            command[index++] = "-I" + f.getLocation().toOSString(); //$NON-NLS-1$
-        }
-
-        // list of files that have failed compilation.
-        ArrayList<AidlData> stillNeedCompilation = new ArrayList<AidlData>();
-
-        // if an aidl file is being removed before we managed to compile it, it'll be in
-        // both list. We *need* to remove it from the compile list or it'll never go away.
-        for (AidlData aidlFile : mAidlToRemove) {
-            int pos = mAidlToCompile.indexOf(aidlFile);
-            if (pos != -1) {
-                mAidlToCompile.remove(pos);
-            }
-        }
-
-        // loop until we've compile them all
-        for (AidlData aidlData : mAidlToCompile) {
-            // Remove the AIDL error markers from the aidl file
-            removeMarkersFromFile(aidlData.aidlFile, AndroidConstants.MARKER_AIDL);
-
-            // get the path of the source file.
-            IPath sourcePath = aidlData.aidlFile.getLocation();
-            String osSourcePath = sourcePath.toOSString();
-
-            IFile javaFile = getGenDestinationFile(aidlData, true /*createFolders*/, monitor);
-
-            // finish to set the command line.
-            command[index] = osSourcePath;
-            command[index + 1] = javaFile.getLocation().toOSString();
-
-            // launch the process
-            if (execAidl(command, aidlData.aidlFile) == false) {
-                // aidl failed. File should be marked. We add the file to the list
-                // of file that will need compilation again.
-                stillNeedCompilation.add(aidlData);
-
-                // and we move on to the next one.
-                continue;
-            } else {
-                // make sure the file will be marked as derived once we refresh the 'gen' source
-                // folder.
-                mDerivedProgressMonitor.addFile(javaFile);
-            }
-        }
-
-        // change the list to only contains the file that have failed compilation
-        mAidlToCompile.clear();
-        mAidlToCompile.addAll(stillNeedCompilation);
-
-        // Remove the java files created from aidl files that have been removed.
-        for (AidlData aidlData : mAidlToRemove) {
-            IFile javaFile = getGenDestinationFile(aidlData, false /*createFolders*/, monitor);
-            if (javaFile.exists()) {
-                // This confirms the java file was generated by the builder,
-                // we can delete the aidlFile.
-                javaFile.delete(true, null);
-
-                // Refresh parent.
-                javaFile.getParent().refreshLocal(IResource.DEPTH_ONE, monitor);
-            }
-        }
-
-        mAidlToRemove.clear();
-
-        // store the build state. If there are any files that failed to compile, we will
-        // force a full aidl compile on the next project open. (unless a full compilation succeed
-        // before the project is closed/re-opened.)
-        // TODO: Optimize by saving only the files that need compilation
-        saveProjectBooleanProperty(PROPERTY_COMPILE_AIDL , mAidlToCompile.size() > 0);
-
-        return true;
-    }
-
-    /**
-     * Returns the {@link IFile} handle to the destination file for a given aild source file
-     * ({@link AidlData}).
-     * @param aidlData the data for the aidl source file.
-     * @param createFolders whether or not the parent folder of the destination should be created
-     * if it does not exist.
-     * @param monitor the progress monitor
-     * @return the handle to the destination file.
-     * @throws CoreException
-     */
-    private IFile getGenDestinationFile(AidlData aidlData, boolean createFolders,
-            IProgressMonitor monitor) throws CoreException {
-        // build the destination folder path.
-        // Use the path of the source file, except for the path leading to its source folder,
-        // and for the last segment which is the filename.
-        int segmentToSourceFolderCount = aidlData.sourceFolder.getFullPath().segmentCount();
-        IPath packagePath = aidlData.aidlFile.getFullPath().removeFirstSegments(
-                segmentToSourceFolderCount).removeLastSegments(1);
-        Path destinationPath = new Path(packagePath.toString());
-
-        // get an IFolder for this path. It's relative to the 'gen' folder already
-        IFolder destinationFolder = mGenFolder.getFolder(destinationPath);
-
-        // create it if needed.
-        if (destinationFolder.exists() == false && createFolders) {
-            createFolder(destinationFolder, monitor);
-        }
-
-        // Build the Java file name from the aidl name.
-        String javaName = aidlData.aidlFile.getName().replaceAll(AndroidConstants.RE_AIDL_EXT,
-                AndroidConstants.DOT_JAVA);
-
-        // get the resource for the java file.
-        IFile javaFile = destinationFolder.getFile(javaName);
-        return javaFile;
-    }
-
-    /**
-     * Creates the destination folder. Because
-     * {@link IFolder#create(boolean, boolean, IProgressMonitor)} only works if the parent folder
-     * already exists, this goes and ensure that all the parent folders actually exist, or it
-     * creates them as well.
-     * @param destinationFolder The folder to create
-     * @param monitor the {@link IProgressMonitor},
-     * @throws CoreException
-     */
-    private void createFolder(IFolder destinationFolder, IProgressMonitor monitor)
-            throws CoreException {
-
-        // check the parent exist and create if necessary.
-        IContainer parent = destinationFolder.getParent();
-        if (parent.getType() == IResource.FOLDER && parent.exists() == false) {
-            createFolder((IFolder)parent, monitor);
-        }
-
-        // create the folder.
-        destinationFolder.create(true /*force*/, true /*local*/,
-                new SubProgressMonitor(monitor, 10));
-    }
-
-    /**
-     * Execute the aidl command line, parse the output, and mark the aidl file
-     * with any reported errors.
-     * @param command the String array containing the command line to execute.
-     * @param file The IFile object representing the aidl file being
-     *      compiled.
-     * @return false if the exec failed, and build needs to be aborted.
-     */
-    private boolean execAidl(String[] command, IFile file) {
-        // do the exec
-        try {
-            Process p = Runtime.getRuntime().exec(command);
-
-            // list to store each line of stderr
-            ArrayList<String> results = new ArrayList<String>();
-
-            // get the output and return code from the process
-            int result = grabProcessOutput(p, results);
-
-            // attempt to parse the error output
-            boolean error = parseAidlOutput(results, file);
-
-            // If the process failed and we couldn't parse the output
-            // we pring a message, mark the project and exit
-            if (result != 0 && error == true) {
-                // display the message in the console.
-                AdtPlugin.printErrorToConsole(getProject(), results.toArray());
-
-                // mark the project and exit
-                markProject(AdtConstants.MARKER_ADT, Messages.Unparsed_AIDL_Errors,
-                        IMarker.SEVERITY_ERROR);
-                return false;
-            }
-        } catch (IOException e) {
-            // mark the project and exit
-            String msg = String.format(Messages.AIDL_Exec_Error, command[0]);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        } catch (InterruptedException e) {
-            // mark the project and exit
-            String msg = String.format(Messages.AIDL_Exec_Error, command[0]);
-            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Goes through the build paths and fills the list of aidl files to compile
-     * ({@link #mAidlToCompile}).
-     * @param project The project.
-     * @param sourceFolderPathList The list of source folder paths.
-     */
-    private void buildAidlCompilationList(IProject project,
-            ArrayList<IPath> sourceFolderPathList) {
-        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-        for (IPath sourceFolderPath : sourceFolderPathList) {
-            IFolder sourceFolder = root.getFolder(sourceFolderPath);
-            // we don't look in the 'gen' source folder as there will be no source in there.
-            if (sourceFolder.exists() && sourceFolder.equals(mGenFolder) == false) {
-                scanFolderForAidl(sourceFolder, sourceFolder);
-            }
-        }
-    }
-
-    /**
-     * Scans a folder and fills the list of aidl files to compile.
-     * @param sourceFolder the root source folder.
-     * @param folder The folder to scan.
-     */
-    private void scanFolderForAidl(IFolder sourceFolder, IFolder folder) {
-        try {
-            IResource[] members = folder.members();
-            for (IResource r : members) {
-                // get the type of the resource
-               switch (r.getType()) {
-                   case IResource.FILE:
-                       // if this a file, check that the file actually exist
-                       // and that it's an aidl file
-                       if (r.exists() &&
-                               AndroidConstants.EXT_AIDL.equalsIgnoreCase(r.getFileExtension())) {
-                           mAidlToCompile.add(new AidlData(sourceFolder, (IFile)r));
-                       }
-                       break;
-                   case IResource.FOLDER:
-                       // recursively go through children
-                       scanFolderForAidl(sourceFolder, (IFolder)r);
-                       break;
-                   default:
-                       // this would mean it's a project or the workspace root
-                       // which is unlikely to happen. we do nothing
-                       break;
-               }
-            }
-        } catch (CoreException e) {
-            // Couldn't get the members list for some reason. Just return.
-        }
-    }
-
-
-    /**
-     * Parse the output of aidl and mark the file with any errors.
-     * @param lines The output to parse.
-     * @param file The file to mark with error.
-     * @return true if the parsing failed, false if success.
-     */
-    private boolean parseAidlOutput(ArrayList<String> lines, IFile file) {
-        // nothing to parse? just return false;
-        if (lines.size() == 0) {
-            return false;
-        }
-
-        Matcher m;
-
-        for (int i = 0; i < lines.size(); i++) {
-            String p = lines.get(i);
-
-            m = sAidlPattern1.matcher(p);
-            if (m.matches()) {
-                // we can ignore group 1 which is the location since we already
-                // have a IFile object representing the aidl file.
-                String lineStr = m.group(2);
-                String msg = m.group(3);
-
-                // get the line number
-                int line = 0;
-                try {
-                    line = Integer.parseInt(lineStr);
-                } catch (NumberFormatException e) {
-                    // looks like the string we extracted wasn't a valid
-                    // file number. Parsing failed and we return true
-                    return true;
-                }
-
-                // mark the file
-                BaseProjectHelper.addMarker(file, AndroidConstants.MARKER_AIDL, msg, line,
-                        IMarker.SEVERITY_ERROR);
-
-                // success, go to the next line
-                continue;
-            }
-
-            // invalid line format, flag as error, and bail
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Merge the current list of aidl file to compile/remove with the new one.
-     * @param toCompile List of file to compile
-     * @param toRemove List of file to remove
-     */
-    private void mergeAidlFileModifications(ArrayList<AidlData> toCompile,
-            ArrayList<AidlData> toRemove) {
-        // loop through the new toRemove list, and add it to the old one,
-        // plus remove any file that was still to compile and that are now
-        // removed
-        for (AidlData r : toRemove) {
-            if (mAidlToRemove.indexOf(r) == -1) {
-                mAidlToRemove.add(r);
-            }
-
-            int index = mAidlToCompile.indexOf(r);
-            if (index != -1) {
-                mAidlToCompile.remove(index);
-            }
-        }
-
-        // now loop through the new files to compile and add it to the list.
-        // Also look for them in the remove list, this would mean that they
-        // were removed, then added back, and we shouldn't remove them, just
-        // recompile them.
-        for (AidlData r : toCompile) {
-            if (mAidlToCompile.indexOf(r) == -1) {
-                mAidlToCompile.add(r);
-            }
-
-            int index = mAidlToRemove.indexOf(r);
-            if (index != -1) {
-                mAidlToRemove.remove(index);
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java
deleted file mode 100644
index d5e6365..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.build.BaseBuilder.BaseDeltaVisitor;
-import com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder.AidlData;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-
-import java.util.ArrayList;
-
-/**
- * Resource Delta visitor for the pre-compiler.
- * <p/>This delta visitor only cares about files that are the source or the result of actions of the
- * {@link PreCompilerBuilder}:
- * <ul><li>R.java/Manifest.java generated by compiling the resources</li>
- * <li>Any Java files generated by <code>aidl</code></li></ul>.
- *
- * Therefore it looks for the following:
- * <ul><li>Any modification in the resource folder</li>
- * <li>Removed files from the source folder receiving generated Java files</li>
- * <li>Any modification to aidl files.</li>
- *
- */
-class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
-        IResourceDeltaVisitor {
-
-    private enum AidlType {
-        UNKNOWN, INTERFACE, PARCELABLE;
-    }
-
-    // See comment in #getAidlType()
-//    private final static Pattern sParcelablePattern = Pattern.compile(
-//            "^\\s*parcelable\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*;\\s*$");
-//
-//    private final static Pattern sInterfacePattern = Pattern.compile(
-//            "^\\s*interface\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?:\\{.*)?$");
-
-    // Result fields.
-    /**
-     * Compile flag. This is set to true if one of the changed/added/removed
-     * file is a resource file. Upon visiting all the delta resources, if
-     * this flag is true, then we know we'll have to compile the resources
-     * into R.java
-     */
-    private boolean mCompileResources = false;
-
-    /**
-     * Aidl force recompilation flag. If true, we'll attempt to recompile all aidl files.
-     */
-    private boolean mForceAidlCompile = false;
-
-    /** List of .aidl files found that are modified or new. */
-    private final ArrayList<AidlData> mAidlToCompile = new ArrayList<AidlData>();
-
-    /** List of .aidl files that have been removed. */
-    private final ArrayList<AidlData> mAidlToRemove = new ArrayList<AidlData>();
-
-    /** Manifest check/parsing flag. */
-    private boolean mCheckedManifestXml = false;
-
-    /** Application Package, gathered from the parsing of the manifest */
-    private String mJavaPackage = null;
-    /** minSDKVersion attribute value, gathered from the parsing of the manifest */
-    private String mMinSdkVersion = null;
-
-    // Internal usage fields.
-    /**
-     * In Resource folder flag. This allows us to know if we're in the
-     * resource folder.
-     */
-    private boolean mInRes = false;
-
-    /**
-     * Current Source folder. This allows us to know if we're in a source
-     * folder, and which folder.
-     */
-    private IFolder mSourceFolder = null;
-
-    /** List of source folders. */
-    private ArrayList<IPath> mSourceFolders;
-    private boolean mIsGenSourceFolder = false;
-
-    private IWorkspaceRoot mRoot;
-
-
-    public PreCompilerDeltaVisitor(BaseBuilder builder, ArrayList<IPath> sourceFolders) {
-        super(builder);
-        mSourceFolders = sourceFolders;
-        mRoot = ResourcesPlugin.getWorkspace().getRoot();
-    }
-
-    public boolean getCompileResources() {
-        return mCompileResources;
-    }
-
-    public boolean getForceAidlCompile() {
-        return mForceAidlCompile;
-    }
-
-    public ArrayList<AidlData> getAidlToCompile() {
-        return mAidlToCompile;
-    }
-
-    public ArrayList<AidlData> getAidlToRemove() {
-        return mAidlToRemove;
-    }
-
-    /**
-     * Returns whether the manifest file was parsed/checked for error during the resource delta
-     * visiting.
-     */
-    public boolean getCheckedManifestXml() {
-        return mCheckedManifestXml;
-    }
-
-    /**
-     * Returns the manifest package if the manifest was checked/parsed.
-     * <p/>
-     * This can return null in two cases:
-     * <ul>
-     * <li>The manifest was not part of the resource change delta, and the manifest was
-     * not checked/parsed ({@link #getCheckedManifestXml()} returns <code>false</code>)</li>
-     * <li>The manifest was parsed ({@link #getCheckedManifestXml()} returns <code>true</code>),
-     * but the package declaration is missing</li>
-     * </ul>
-     * @return the manifest package or null.
-     */
-    public String getManifestPackage() {
-        return mJavaPackage;
-    }
-
-    /**
-     * Returns the minSDkVersion attribute from the manifest if it was checked/parsed.
-     * <p/>
-     * This can return null in two cases:
-     * <ul>
-     * <li>The manifest was not part of the resource change delta, and the manifest was
-     * not checked/parsed ({@link #getCheckedManifestXml()} returns <code>false</code>)</li>
-     * <li>The manifest was parsed ({@link #getCheckedManifestXml()} returns <code>true</code>),
-     * but the package declaration is missing</li>
-     * </ul>
-     * @return the minSdkVersion or null.
-     */
-    public String getMinSdkVersion() {
-        return mMinSdkVersion;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.core.resources.IResourceDeltaVisitor
-     *      #visit(org.eclipse.core.resources.IResourceDelta)
-     */
-    public boolean visit(IResourceDelta delta) throws CoreException {
-        // we are only going to look for changes in res/, source folders and in
-        // AndroidManifest.xml since the delta visitor goes through the main
-        // folder before its children we can check when the path segment
-        // count is 2 (format will be /$Project/folder) and make sure we are
-        // processing res/, source folders or AndroidManifest.xml
-
-        IResource resource = delta.getResource();
-        IPath path = resource.getFullPath();
-        String[] segments = path.segments();
-
-        // since the delta visitor also visits the root we return true if
-        // segments.length = 1
-        if (segments.length == 1) {
-            // FIXME: check this is an Android project.
-            return true;
-        } else if (segments.length == 2) {
-            // if we are at an item directly under the root directory,
-            // then we are not yet in a source or resource folder
-            mInRes = false;
-            mSourceFolder = null;
-
-            if (SdkConstants.FD_RESOURCES.equalsIgnoreCase(segments[1])) {
-                // this is the resource folder that was modified. we want to
-                // see its content.
-
-                // since we're going to visit its children next, we set the
-                // flag
-                mInRes = true;
-                mSourceFolder = null;
-                return true;
-            } else if (AndroidConstants.FN_ANDROID_MANIFEST.equalsIgnoreCase(segments[1])) {
-                // any change in the manifest could trigger a new R.java
-                // class, so we don't need to check the delta kind
-                if (delta.getKind() != IResourceDelta.REMOVED) {
-                    // parse the manifest for errors
-                    AndroidManifestParser parser = BaseProjectHelper.parseManifestForError(
-                            (IFile)resource, this);
-
-                    if (parser != null) {
-                        mJavaPackage = parser.getPackage();
-                        mMinSdkVersion = parser.getApiLevelRequirement();
-                    }
-
-                    mCheckedManifestXml = true;
-                }
-                mCompileResources = true;
-
-                // we don't want to go to the children, not like they are
-                // any for this resource anyway.
-                return false;
-            }
-        }
-
-        // at this point we can either be in the source folder or in the
-        // resource folder or in a different folder that contains a source
-        // folder.
-        // This is due to not all source folder being src/. Some could be
-        // something/somethingelse/src/
-
-        // so first we test if we already know we are in a source or
-        // resource folder.
-
-        if (mSourceFolder != null) {
-            // if we are in the res folder, we are looking for the following changes:
-            // - added/removed/modified aidl files.
-            // - missing R.java file
-
-            // if the resource is a folder, we just go straight to the children
-            if (resource.getType() == IResource.FOLDER) {
-                return true;
-            }
-
-            if (resource.getType() != IResource.FILE) {
-                return false;
-            }
-            IFile file = (IFile)resource;
-
-            // get the modification kind
-            int kind = delta.getKind();
-
-            // we process normal source folder and the 'gen' source folder differently.
-            if (mIsGenSourceFolder) {
-                // this is the generated java file source folder.
-                // - if R.java/Manifest.java are removed/modified, we recompile the resources
-                // - if aidl files are removed/modified, we recompile them.
-
-                boolean outputWarning = false;
-
-                String fileName = resource.getName();
-
-                // Special case of R.java/Manifest.java.
-                if (AndroidConstants.FN_RESOURCE_CLASS.equals(fileName) ||
-                        AndroidConstants.FN_MANIFEST_CLASS.equals(fileName)) {
-                    // if it was removed, there's a possibility that it was removed due to a
-                    // package change, or an aidl that was removed, but the only thing
-                    // that will happen is that we'll have an extra build. Not much of a problem.
-                    mCompileResources = true;
-
-                    // we want a warning
-                    outputWarning = true;
-                } else {
-                    // this has to be a Java file created from an aidl file.
-                    // Look for the source aidl file in all the source folders.
-                    String aidlFileName = fileName.replaceAll(AndroidConstants.RE_JAVA_EXT,
-                            AndroidConstants.DOT_AIDL);
-
-                    for (IPath sourceFolderPath : mSourceFolders) {
-                        // do not search in the current source folder as it is the 'gen' folder.
-                        if (sourceFolderPath.equals(mSourceFolder.getFullPath())) {
-                            continue;
-                        }
-
-                        IFolder sourceFolder = getFolder(sourceFolderPath);
-                        if (sourceFolder != null) {
-                            // go recursively, segment by segment.
-                            // index starts at 2 (0 is project, 1 is 'gen'
-                            IFile sourceFile = findFile(sourceFolder, segments, 2, aidlFileName);
-
-                            if (sourceFile != null) {
-                                // found the source. add it to the list of files to compile
-                                mAidlToCompile.add(new AidlData(sourceFolder, sourceFile));
-                                outputWarning = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                if (outputWarning) {
-                    if (kind == IResourceDelta.REMOVED) {
-                        // We pring an error just so that it's red, but it's just a warning really.
-                        String msg = String.format(Messages.s_Removed_Recreating_s, fileName);
-                        AdtPlugin.printErrorToConsole(mBuilder.getProject(), msg);
-                    } else if (kind == IResourceDelta.CHANGED) {
-                        // the file was modified manually! we can't allow it.
-                        String msg = String.format(Messages.s_Modified_Manually_Recreating_s,
-                                fileName);
-                        AdtPlugin.printErrorToConsole(mBuilder.getProject(), msg);
-                    }
-                }
-            } else {
-                // this is another source folder.
-                // We only care about aidl files being added/modified/removed.
-
-                // get the extension of the resource
-                String ext = resource.getFileExtension();
-                if (AndroidConstants.EXT_AIDL.equalsIgnoreCase(ext)) {
-                    // first check whether it's a regular file or a parcelable.
-                    AidlType type = getAidlType(file);
-
-                    if (type == AidlType.INTERFACE) {
-                        if (kind == IResourceDelta.REMOVED) {
-                            // we'll have to remove the generated file.
-                            mAidlToRemove.add(new AidlData(mSourceFolder, file));
-                        } else if (mForceAidlCompile == false) {
-                            // add the aidl file to the list of file to (re)compile
-                            mAidlToCompile.add(new AidlData(mSourceFolder, file));
-                        }
-                    } else {
-                        // force recompilations of all Aidl Files.
-                        mForceAidlCompile = true;
-                        mAidlToCompile.clear();
-                    }
-                }
-            }
-
-            // no children.
-            return false;
-        } else if (mInRes) {
-            // if we are in the res folder, we are looking for the following
-            // changes:
-            // - added/removed/modified xml files.
-            // - added/removed files of any other type
-
-            // if the resource is a folder, we just go straight to the
-            // children
-            if (resource.getType() == IResource.FOLDER) {
-                return true;
-            }
-
-            // get the extension of the resource
-            String ext = resource.getFileExtension();
-            int kind = delta.getKind();
-
-            String p = resource.getProjectRelativePath().toString();
-            String message = null;
-            switch (kind) {
-                case IResourceDelta.CHANGED:
-                    // display verbose message
-                    message = String.format(Messages.s_Modified_Recreating_s, p,
-                            AndroidConstants.FN_RESOURCE_CLASS);
-                    break;
-                case IResourceDelta.ADDED:
-                    // display verbose message
-                    message = String.format(Messages.Added_s_s_Needs_Updating, p,
-                            AndroidConstants.FN_RESOURCE_CLASS);
-                    break;
-                case IResourceDelta.REMOVED:
-                    // display verbose message
-                    message = String.format(Messages.s_Removed_s_Needs_Updating, p,
-                            AndroidConstants.FN_RESOURCE_CLASS);
-                    break;
-            }
-            if (message != null) {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
-                        mBuilder.getProject(), message);
-            }
-
-            if (AndroidConstants.EXT_XML.equalsIgnoreCase(ext)) {
-                if (kind != IResourceDelta.REMOVED) {
-                    // check xml Validity
-                    mBuilder.checkXML(resource, this);
-                }
-
-                // if we are going through this resource, it was modified
-                // somehow.
-                // we don't care if it was an added/removed/changed event
-                mCompileResources = true;
-                return false;
-            } else {
-                // this is a non xml resource.
-                if (kind == IResourceDelta.ADDED
-                        || kind == IResourceDelta.REMOVED) {
-                    mCompileResources = true;
-                    return false;
-                }
-            }
-        } else if (resource instanceof IFolder) {
-            // in this case we may be inside a folder that contains a source
-            // folder, go through the list of known source folders
-
-            for (IPath sourceFolderPath : mSourceFolders) {
-                // first check if they match exactly.
-                if (sourceFolderPath.equals(path)) {
-                    // this is a source folder!
-                    mInRes = false;
-                    mSourceFolder = getFolder(sourceFolderPath); // all non null due to test above
-                    mIsGenSourceFolder = path.segmentCount() == 2 &&
-                            path.segment(1).equals(SdkConstants.FD_GEN_SOURCES);
-                    return true;
-                }
-
-                // check if we are on the way to a source folder.
-                int count = sourceFolderPath.matchingFirstSegments(path);
-                if (count == path.segmentCount()) {
-                    mInRes = false;
-                    return true;
-                }
-            }
-
-            // if we're here, we are visiting another folder
-            // like /$Project/bin/ for instance (we get notified for changes
-            // in .class!)
-            // This could also be another source folder and we have found
-            // R.java in a previous source folder
-            // We don't want to visit its children
-            return false;
-        }
-
-        return false;
-    }
-
-    /**
-     * Searches for and return a file in a folder. The file is defined by its segments, and a new
-     * name (replacing the last segment).
-     * @param folder the folder we are searching
-     * @param segments the segments of the file to search.
-     * @param index the index of the current segment we are looking for
-     * @param filename the new name to replace the last segment.
-     * @return the {@link IFile} representing the searched file, or null if not found
-     */
-    private IFile findFile(IFolder folder, String[] segments, int index, String filename) {
-        boolean lastSegment = index == segments.length - 1;
-        IResource resource = folder.findMember(lastSegment ? filename : segments[index]);
-        if (resource != null && resource.exists()) {
-            if (lastSegment) {
-                if (resource.getType() == IResource.FILE) {
-                    return (IFile)resource;
-                }
-            } else {
-                if (resource.getType() == IResource.FOLDER) {
-                    return findFile((IFolder)resource, segments, index+1, filename);
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns a handle to the folder identified by the given path in this container.
-     * <p/>The different with {@link IContainer#getFolder(IPath)} is that this returns a non
-     * null object only if the resource actually exists and is a folder (and not a file)
-     * @param path the path of the folder to return.
-     * @return a handle to the folder if it exists, or null otherwise.
-     */
-    private IFolder getFolder(IPath path) {
-        IResource resource = mRoot.findMember(path);
-        if (resource != null && resource.exists() && resource.getType() == IResource.FOLDER) {
-            return (IFolder)resource;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the type of the aidl file. Aidl files can either declare interfaces, or declare
-     * parcelables. This method will attempt to parse the file and return the type. If the type
-     * cannot be determined, then it will return {@link AidlType#UNKNOWN}.
-     * @param file The aidl file
-     * @return the type of the aidl.
-     * @throws CoreException
-     */
-    private AidlType getAidlType(IFile file) throws CoreException {
-        // At this time, parsing isn't available, so we return UNKNOWN. This will force
-        // a recompilation of all aidl file as soon as one is changed.
-        return AidlType.UNKNOWN;
-
-        // TODO: properly parse aidl file to determine type and generate dependency graphs.
-//
-//        String className = file.getName().substring(0,
-//                file.getName().length() - AndroidConstants.DOT_AIDL.length());
-//
-//        InputStream input = file.getContents(true /* force*/);
-//        try {
-//            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
-//            String line;
-//            while ((line = reader.readLine()) != null) {
-//                if (line.length() == 0) {
-//                    continue;
-//                }
-//
-//                Matcher m = sParcelablePattern.matcher(line);
-//                if (m.matches() && m.group(1).equals(className)) {
-//                    return AidlType.PARCELABLE;
-//                }
-//
-//                m = sInterfacePattern.matcher(line);
-//                if (m.matches() && m.group(1).equals(className)) {
-//                    return AidlType.INTERFACE;
-//                }
-//            }
-//        } catch (IOException e) {
-//            throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-//                    "Error parsing aidl file", e));
-//        } finally {
-//            try {
-//                input.close();
-//            } catch (IOException e) {
-//                throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-//                        "Error parsing aidl file", e));
-//            }
-//        }
-//
-//        return AidlType.UNKNOWN;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ResourceManagerBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ResourceManagerBuilder.java
deleted file mode 100644
index a277e87..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ResourceManagerBuilder.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-
-import java.util.ArrayList;
-import java.util.Map;
-
-/**
- * Resource manager builder whose only purpose is to refresh the resource folder
- * so that the other builder use an up to date version.
- */
-public class ResourceManagerBuilder extends BaseBuilder {
-
-    public static final String ID = "com.android.ide.eclipse.adt.ResourceManagerBuilder"; //$NON-NLS-1$
-
-    public ResourceManagerBuilder() {
-        super();
-    }
-
-    // build() returns a list of project from which this project depends for future compilation.
-    @SuppressWarnings("unchecked")
-    @Override
-    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
-            throws CoreException {
-        // Get the project.
-        IProject project = getProject();
-
-        // Clear the project of the generic markers
-        BaseBuilder.removeMarkersFromProject(project, AdtConstants.MARKER_ADT);
-        
-        // check for existing target marker, in which case we abort.
-        // (this means: no SDK, no target, or unresolvable target.)
-        abortOnBadSetup(project);
-
-        // Check the compiler compliance level, displaying the error message
-        // since this is the first builder.
-        int res = ProjectHelper.checkCompilerCompliance(project);
-        String errorMessage = null;
-        switch (res) {
-            case ProjectHelper.COMPILER_COMPLIANCE_LEVEL:
-                errorMessage = Messages.Requires_Compiler_Compliance_5;
-            case ProjectHelper.COMPILER_COMPLIANCE_SOURCE:
-                errorMessage = Messages.Requires_Source_Compatibility_5;
-            case ProjectHelper.COMPILER_COMPLIANCE_CODEGEN_TARGET:
-                errorMessage = Messages.Requires_Class_Compatibility_5;
-        }
-
-        if (errorMessage != null) {
-            BaseProjectHelper.addMarker(project, AdtConstants.MARKER_ADT, errorMessage,
-                    IMarker.SEVERITY_ERROR);
-            AdtPlugin.printErrorToConsole(project, errorMessage);
-            
-            // interrupt the build. The next builders will not run.
-            stopBuild(errorMessage);
-        }
-
-        // Check that the SDK directory has been setup.
-        String osSdkFolder = AdtPlugin.getOsSdkFolder();
-
-        if (osSdkFolder == null || osSdkFolder.length() == 0) {
-            AdtPlugin.printErrorToConsole(project, Messages.No_SDK_Setup_Error);
-            markProject(AdtConstants.MARKER_ADT, Messages.No_SDK_Setup_Error,
-                    IMarker.SEVERITY_ERROR);
-
-            // This interrupts the build. The next builders will not run.
-            stopBuild(Messages.No_SDK_Setup_Error);
-        }
-
-        // check the project has a target
-        IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
-        if (projectTarget == null) {
-            // no target. marker has been set by the container initializer: exit silently.
-            // This interrupts the build. The next builders will not run.
-            stopBuild("Project has no target");
-        }
-        
-        // check the 'gen' source folder is present
-        boolean hasGenSrcFolder = false; // whether the project has a 'gen' source folder setup
-        IJavaProject javaProject = JavaCore.create(project);
-        
-        IClasspathEntry[] classpaths = javaProject.readRawClasspath();
-        if (classpaths != null) {
-            for (IClasspathEntry e : classpaths) {
-                if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
-                    IPath path = e.getPath();
-                    if (path.segmentCount() == 2 &&
-                            path.segment(1).equals(SdkConstants.FD_GEN_SOURCES)) {
-                        hasGenSrcFolder = true;
-                        break;
-                    }
-                }
-            }
-        }
-
-        boolean genFolderPresent = false; // whether the gen folder actually exists
-        IResource resource = project.findMember(SdkConstants.FD_GEN_SOURCES);
-        genFolderPresent = resource != null && resource.exists();
-        
-        if (hasGenSrcFolder == false && genFolderPresent) {
-            // No source folder setup for 'gen' in the project, but there's already a
-            // 'gen' resource (file or folder).
-            String message;
-            if (resource.getType() == IResource.FOLDER) {
-                // folder exists already! This is an error. If the folder had been created
-                // by the NewProjectWizard, it'd be a source folder.
-                message = String.format("%1$s already exists but is not a source folder. Convert to a source folder or rename it.",
-                        resource.getFullPath().toString());
-            } else {
-                // resource exists but is not a folder.
-                message = String.format(
-                        "Resource %1$s is in the way. ADT needs a source folder called 'gen' to work. Rename or delete resource.",
-                        resource.getFullPath().toString());
-            }
-
-            AdtPlugin.printErrorToConsole(project, message);
-            markProject(AdtConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
-
-            // This interrupts the build. The next builders will not run.
-            stopBuild(message);
-        } else if (hasGenSrcFolder == false || genFolderPresent == false) {
-            // either there is no 'gen' source folder in the project (older SDK),
-            // or the folder does not exist (was deleted, or was a fresh svn checkout maybe.)
-
-            // In case we are migrating from an older SDK, we go through the current source
-            // folders and delete the generated Java files.
-            ArrayList<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
-            IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-            for (IPath path : sourceFolders) {
-                IResource member = root.findMember(path);
-                if (member != null) {
-                    removeDerivedResources(member, monitor);
-                }
-            }
-
-            // create the new source folder, if needed
-            IFolder genFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES);
-            if (genFolderPresent == false) {
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                        "Creating 'gen' source folder for generated Java files");
-                genFolder.create(true /* force */, true /* local */,
-                        new SubProgressMonitor(monitor, 10));
-                genFolder.setDerived(true);
-            }
-            
-            // add it to the source folder list, if needed only (or it will throw)
-            if (hasGenSrcFolder == false) {
-                IClasspathEntry[] entries = javaProject.getRawClasspath();
-                entries = ProjectHelper.addEntryToClasspath(entries,
-                        JavaCore.newSourceEntry(genFolder.getFullPath()));
-                javaProject.setRawClasspath(entries, new SubProgressMonitor(monitor, 10));
-            }
-            
-            // refresh the whole project
-            project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 10));
-        }
-
-        // Check the preference to be sure we are supposed to refresh
-        // the folders.
-        if (AdtPlugin.getAutoResRefresh()) {
-            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
-                    Messages.Refreshing_Res);
-
-            // refresh the res folder.
-            IFolder resFolder = project.getFolder(
-                    AndroidConstants.WS_RESOURCES);
-            resFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
-
-            // Also refresh the assets folder to make sure the ApkBuilder
-            // will now it's changed and will force a new resource packaging.
-            IFolder assetsFolder = project.getFolder(
-                    AndroidConstants.WS_ASSETS);
-            assetsFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
-        }
-
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties
deleted file mode 100644
index 8ba43d4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties
+++ /dev/null
@@ -1,61 +0,0 @@
-Start_Full_Apk_Build=Starting full Package build.
-Start_Full_Pre_Compiler=Starting full Pre Compiler.
-Start_Inc_Apk_Build=Starting incremental Package build: Checking resource changes.
-Start_Inc_Pre_Compiler=Starting incremental Pre Compiler: Checking resource changes.
-Xml_Error=Error in an XML file: aborting build.
-s_Missing_Repackaging=%1$s missing. Repackaging.
-Project_Has_Errors=Project contains error(s). Package Builder aborted.
-Failed_To_Get_Output=Failed to get project output folder\!
-Output_Missing=Output folder missing\! Make sure your project is configured properly.
-s_File_Missing=%1$s file missing\!
-Unparsed_AAPT_Errors=Unparsed aapt error(s)\! Check the console for output.
-Unparsed_AIDL_Errors=Unparsed aidl error\! Check the console for output.
-AAPT_Exec_Error=Error executing aapt. Please check aapt is present at %1$s
-Dalvik_Error_d=Conversion to Dalvik format failed with error %1$d
-DX_Jar_Error=Dx.jar is not found inside the plugin. Reinstall ADT\!
-Dalvik_Error_s=Conversion to Dalvik format failed: %1$s
-Incompatible_VM_Warning=Note: You may be using an incompatible virtual machine or class library.
-Requires_1_5_Error=This program requires JDK 1.5 compatibility.
-Final_Archive_Error_s=Error generating final archive: %1$s
-Marker_Delete_Error=Failed to delete marker '%1$s' for %2$s
-Couldnt_Locate_s_Error=Could not locate '%1$s'. This will not be added to the package.
-Compiler_Compliance_Error=Compiler compliance level not compatible: Build aborted.
-No_SDK_Setup_Error=SDK directory has not been setup. Please go to the Android preferences and enter the location of the SDK.
-s_Contains_Xml_Error=%1$s contains XML error: Build aborted.
-s_Doesnt_Declare_Package_Error=%1$s does not declare a Java package: Build aborted.
-Checking_Package_Change=Checking Java package value did not change...
-Package_s_Doesnt_Exist_Error=Package '%1$s' does not exist\!
-Preparing_Generated_Files=Preparing generated java files for update/creation.
-AAPT_Error='aapt' error. Pre Compiler Build aborted.
-Nothing_To_Compile=Nothing to pre compile\!
-Removing_Generated_Classes=Removing generated java classes.
-Delete_Obsolete_Error=Failed to delete obsolete %1$s, please delete it manually
-DexWrapper_Dex_Loader=Dex Loader
-AIDL_Java_Conflict=%1$s is in the way of %2$s, remove it or rename of one the files.
-AIDL_Exec_Error=Error executing aidl. Please check aidl is present at %1$s
-s_Removed_Recreating_s=%1$s was removed\! Recreating %1$s\!
-s_Modified_Manually_Recreating_s=%1$s was modified manually\! Reverting to generated version\!
-s_Modified_Recreating_s='%1$s' was modified, %2$s needs to be updated.
-Added_s_s_Needs_Updating=New resource file: '%1$s', %2$s needs to be updated.
-s_Removed_s_Needs_Updating='%1$s' was removed, %2$s needs to be updated.
-Requires_Compiler_Compliance_5=Android requires compiler compliance level 5.0. Please fix project properties.
-Requires_Source_Compatibility_5=Android requires source compatibility set to 5.0. Please fix project properties.
-Requires_Class_Compatibility_5=Android requires .class compatibility set to 5.0. Please fix project properties.
-Refreshing_Res=Refreshing resource folders.
-DexWrapper_s_does_not_exists=%1$s does not exist or is not a file
-DexWrapper_Failed_to_load_s=Failed to load %1$s
-DexWrapper_Unable_To_Execute_Dex_s=Unable to execute dex: %1$s
-DexWrapper_SecuryEx_Unable_To_Find_API=SecurityException: Unable to find API for dex.jar
-DexWrapper_SecuryEx_Unable_To_Find_Method=SecurityException: Unable to find method for dex.jar
-DexWrapper_SecuryEx_Unable_To_Find_Field=SecurityException: Unable to find field for dex.jar
-ApkBuilder_UnableBuild_Dex_Not_loaded=Unable to build: the file dex.jar was not loaded from the SDK folder\!
-ApkBuilder_Using_Default_Key=Using default debug key to sign package
-ApkBuilder_Using_s_To_Sign=Using '%1$s' to sign package
-ApkBuilder_Signing_Key_Creation_s=Signing Key Creation: 
-ApkBuilder_Unable_To_Gey_Key=Unable to get debug signature key
-ApkBuilder_Certificate_Expired_on_s=Debug certificate expired on %1$s\!
-ApkBuilder_Packaging_s=Packaging %1$s
-ApkBuilder_JAVA_HOME_is_s=The Java VM Home used is: %1$s
-ApkBuilder_Update_or_Execute_manually_s=Update it if necessary, or manually execute the following command:
-ApkBuilder_s_Conflict_with_file_s=%1$s conflicts with another file already put at %2$s
-ApkBuilder_Packaging_s_into_s=Packaging %1$s into %2$s
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java
deleted file mode 100644
index 75d33b3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextValueDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiFlagAttributeNode;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.TextSelection;
-import org.eclipse.jface.text.contentassist.CompletionProposal;
-import org.eclipse.jface.text.contentassist.ICompletionProposal;
-import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
-import org.eclipse.jface.text.contentassist.IContextInformation;
-import org.eclipse.jface.text.contentassist.IContextInformationValidator;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.regex.Pattern;
-
-/**
- * Content Assist Processor for Android XML files
- */
-public abstract class AndroidContentAssist implements IContentAssistProcessor {
-
-    /** Regexp to detect a full attribute after an element tag.
-     * <pre>Syntax:
-     *    name = "..." quoted string with all but < and "
-     * or:
-     *    name = '...' quoted string with all but < and '
-     * </pre>
-     */
-    private static Pattern sFirstAttribute = Pattern.compile(
-            "^ *[a-zA-Z_:]+ *= *(?:\"[^<\"]*\"|'[^<']*')");  //$NON-NLS-1$
-
-    /** Regexp to detect an element tag name */
-    private static Pattern sFirstElementWord = Pattern.compile("^[a-zA-Z0-9_:]+"); //$NON-NLS-1$
-
-    /** Regexp to detect whitespace */
-    private static Pattern sWhitespace = Pattern.compile("\\s+"); //$NON-NLS-1$
-
-    protected final static String ROOT_ELEMENT = "";
-
-    /** Descriptor of the root of the XML hierarchy. This a "fake" ElementDescriptor which
-     *  is used to list all the possible roots given by actual implementations.
-     *  DO NOT USE DIRECTLY. Call {@link #getRootDescriptor()} instead. */
-    private ElementDescriptor mRootDescriptor;
-
-    private final int mDescriptorId;
-
-    private AndroidEditor mEditor;
-
-    /**
-     * Constructor for AndroidContentAssist
-     * @param descriptorId An id for {@link AndroidTargetData#getDescriptorProvider(int)}.
-     *      The Id can be one of {@link AndroidTargetData#DESCRIPTOR_MANIFEST},
-     *      {@link AndroidTargetData#DESCRIPTOR_LAYOUT},
-     *      {@link AndroidTargetData#DESCRIPTOR_MENU},
-     *      or {@link AndroidTargetData#DESCRIPTOR_XML}.
-     *      All other values will throw an {@link IllegalArgumentException} later at runtime.
-     */
-    public AndroidContentAssist(int descriptorId) {
-        mDescriptorId = descriptorId;
-    }
-
-    /**
-     * Returns a list of completion proposals based on the
-     * specified location within the document that corresponds
-     * to the current cursor position within the text viewer.
-     *
-     * @param viewer the viewer whose document is used to compute the proposals
-     * @param offset an offset within the document for which completions should be computed
-     * @return an array of completion proposals or <code>null</code> if no proposals are possible
-     *
-     * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
-     */
-    public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
-
-        if (mEditor == null) {
-            mEditor = getAndroidEditor(viewer);
-            if (mEditor == null) {
-                // This should not happen. Duck and forget.
-                AdtPlugin.log(IStatus.ERROR, "Editor not found during completion");
-                return null;
-            }
-        }
-
-        UiElementNode rootUiNode = mEditor.getUiRootNode();
-
-        Object[] choices = null; /* An array of ElementDescriptor, or AttributeDescriptor
-                                    or String or null */
-        String parent = "";      //$NON-NLS-1$
-        String wordPrefix = extractElementPrefix(viewer, offset);
-        char needTag = 0;
-        boolean isElement = false;
-        boolean isAttribute = false;
-
-        Node currentNode = getNode(viewer, offset);
-        if (currentNode == null)
-            return null;
-
-        // check to see if we can find a UiElementNode matching this XML node
-        UiElementNode currentUiNode =
-            rootUiNode == null ? null : rootUiNode.findXmlNode(currentNode);
-
-        if (currentNode == null) {
-            // Should not happen (an XML doc always has at least a doc node). Just give up.
-            return null;
-        }
-
-        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
-            parent = currentNode.getNodeName();
-
-            if (wordPrefix.equals(parent)) {
-                // We are still editing the element's tag name, not the attributes
-                // (the element's tag name may not even be complete)
-                isElement = true;
-                choices = getChoicesForElement(parent, currentNode);
-            } else {
-                // We're not editing the current node name, so we might be editing its
-                // attributes instead...
-                isAttribute = true;
-                AttribInfo info = parseAttributeInfo(viewer, offset);
-                if (info != null) {
-                    // We're editing attributes in an element node (either the attributes' names
-                    // or their values).
-                    choices = getChoicesForAttribute(parent, currentNode, currentUiNode, info);
-
-                    if (info.correctedPrefix != null) {
-                        wordPrefix = info.correctedPrefix;
-                    }
-                    needTag = info.needTag;
-                }
-            }
-        } else if (currentNode.getNodeType() == Node.TEXT_NODE) {
-            isElement = true;
-            // Examine the parent of the text node.
-            choices = getChoicesForTextNode(currentNode);
-        }
-
-        // Abort if we can't recognize the context or there are no completion choices
-        if (choices == null || choices.length == 0) return null;
-
-        if (isElement) {
-            // If we found some suggestions, do we need to add an opening "<" bracket
-            // for the element? We don't if the cursor is right after "<" or "</".
-            // Per XML Spec, there's no whitespace between "<" or "</" and the tag name.
-            int offset2 = offset - wordPrefix.length() - 1;
-            int c1 = extractChar(viewer, offset2);
-            if (!((c1 == '<') || (c1 == '/' && extractChar(viewer, offset2 - 1) == '<'))) {
-                needTag = '<';
-            }
-        }
-
-        // get the selection length
-        int selectionLength = 0;
-        ISelection selection = viewer.getSelectionProvider().getSelection();
-        if (selection instanceof TextSelection) {
-            TextSelection textSelection = (TextSelection)selection;
-            selectionLength = textSelection.getLength();
-        }
-
-        return computeProposals(offset, currentNode, choices, wordPrefix, needTag,
-                isAttribute, selectionLength);
-    }
-
-    /**
-     * Returns the namespace prefix matching the Android Resource URI.
-     * If no such declaration is found, returns the default "android" prefix.
-     *
-     * @param node The current node. Must not be null.
-     * @param nsUri The namespace URI of which the prefix is to be found,
-     *              e.g. {@link SdkConstants#NS_RESOURCES}
-     * @return The first prefix declared or the default "android" prefix.
-     */
-    private String lookupNamespacePrefix(Node node, String nsUri) {
-        // Note: Node.lookupPrefix is not implemented in wst/xml/core NodeImpl.java
-        // The following emulates this:
-        //   String prefix = node.lookupPrefix(SdkConstants.NS_RESOURCES);
-
-        if (XmlnsAttributeDescriptor.XMLNS_URI.equals(nsUri)) {
-            return "xmlns"; //$NON-NLS-1$
-        }
-
-        HashSet<String> visited = new HashSet<String>();
-
-        String prefix = null;
-        for (; prefix == null &&
-                    node != null &&
-                    node.getNodeType() == Node.ELEMENT_NODE;
-               node = node.getParentNode()) {
-            NamedNodeMap attrs = node.getAttributes();
-            for (int n = attrs.getLength() - 1; n >= 0; --n) {
-                Node attr = attrs.item(n);
-                if ("xmlns".equals(attr.getPrefix())) {  //$NON-NLS-1$
-                    String uri = attr.getNodeValue();
-                    if (SdkConstants.NS_RESOURCES.equals(uri)) {
-                        return attr.getLocalName();
-                    }
-                    visited.add(uri);
-                }
-            }
-        }
-
-        // Use a sensible default prefix if we can't find one.
-        // We need to make sure the prefix is not one that was declared in the scope
-        // visited above.
-        prefix = SdkConstants.NS_RESOURCES.equals(nsUri) ? "android" : "ns"; //$NON-NLS-1$ //$NON-NLS-2$
-        String base = prefix;
-        for (int i = 1; visited.contains(prefix); i++) {
-            prefix = base + Integer.toString(i);
-        }
-        return prefix;
-    }
-
-    /**
-     * Gets the choices when the user is editing the name of an XML element.
-     * <p/>
-     * The user is editing the name of an element (the "parent").
-     * Find the grand-parent and if one is found, return its children element list.
-     * The name which is being edited should be one of those.
-     * <p/>
-     * Example: <manifest><applic*cursor* => returns the list of all elements that
-     * can be found under <manifest>, of which <application> is one of the choices.
-     *
-     * @return an ElementDescriptor[] or null if no valid element was found.
-     */
-    private Object[] getChoicesForElement(String parent, Node current_node) {
-        ElementDescriptor grandparent = null;
-        if (current_node.getParentNode().getNodeType() == Node.ELEMENT_NODE) {
-            grandparent = getDescriptor(current_node.getParentNode().getNodeName());
-        } else if (current_node.getParentNode().getNodeType() == Node.DOCUMENT_NODE) {
-            grandparent = getRootDescriptor();
-        }
-        if (grandparent != null) {
-            for (ElementDescriptor e : grandparent.getChildren()) {
-                if (e.getXmlName().startsWith(parent)) {
-                    return grandparent.getChildren();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Gets the choices when the user is editing an XML attribute.
-     * <p/>
-     * In input, attrInfo contains details on the analyzed context, namely whether the
-     * user is editing an attribute value (isInValue) or an attribute name.
-     * <p/>
-     * In output, attrInfo also contains two possible new values (this is a hack to circumvent
-     * the lack of out-parameters in Java):
-     * - AttribInfo.correctedPrefix if the user has been editing an attribute value and it has
-     *   been detected that what the user typed is different from what extractElementPrefix()
-     *   predicted. This happens because extractElementPrefix() stops when a character that
-     *   cannot be an element name appears whereas parseAttributeInfo() uses a grammar more
-     *   lenient as suitable for attribute values.
-     * - AttribInfo.needTag will be non-zero if we find that the attribute completion proposal
-     *   must be double-quoted.
-     * @param currentUiNode
-     *
-     * @return an AttributeDescriptor[] if the user is editing an attribute name.
-     *         a String[] if the user is editing an attribute value with some known values,
-     *         or null if nothing is known about the context.
-     */
-    private Object[] getChoicesForAttribute(String parent,
-            Node currentNode, UiElementNode currentUiNode, AttribInfo attrInfo) {
-        Object[] choices = null;
-        if (attrInfo.isInValue) {
-            // Editing an attribute's value... Get the attribute name and then the
-            // possible choices for the tuple(parent,attribute)
-            String value = attrInfo.value;
-            if (value.startsWith("'") || value.startsWith("\"")) {   //$NON-NLS-1$   //$NON-NLS-2$
-                value = value.substring(1);
-                // The prefix that was found at the beginning only scan for characters
-                // valid for tag name. We now know the real prefix for this attribute's
-                // value, which is needed to generate the completion choices below.
-                attrInfo.correctedPrefix = value;
-            } else {
-                attrInfo.needTag = '"';
-            }
-
-            if (currentUiNode != null) {
-                // look for an UI attribute matching the current attribute name
-                String attrName = attrInfo.name;
-                // remove any namespace prefix from the attribute name
-                int pos = attrName.indexOf(':');
-                if (pos >= 0) {
-                    attrName = attrName.substring(pos + 1);
-                }
-
-                UiAttributeNode currAttrNode = null;
-                for (UiAttributeNode attrNode : currentUiNode.getUiAttributes()) {
-                    if (attrNode.getDescriptor().getXmlLocalName().equals(attrName)) {
-                        currAttrNode = attrNode;
-                        break;
-                    }
-                }
-
-                if (currAttrNode != null) {
-                    choices = currAttrNode.getPossibleValues(value);
-
-                    if (currAttrNode instanceof UiFlagAttributeNode) {
-                        // A "flag" can consist of several values separated by "or" (|).
-                        // If the correct prefix contains such a pipe character, we change
-                        // it so that only the currently edited value is completed.
-                        pos = value.indexOf('|');
-                        if (pos >= 0) {
-                            attrInfo.correctedPrefix = value = value.substring(pos + 1);
-                            attrInfo.needTag = 0;
-                        }
-                    }
-                }
-            }
-
-            if (choices == null) {
-                // fallback on the older descriptor-only based lookup.
-
-                // in order to properly handle the special case of the name attribute in
-                // the action tag, we need the grandparent of the action node, to know
-                // what type of actions we need.
-                // e.g. activity -> intent-filter -> action[@name]
-                String greatGrandParentName = null;
-                Node grandParent = currentNode.getParentNode();
-                if (grandParent != null) {
-                    Node greatGrandParent = grandParent.getParentNode();
-                    if (greatGrandParent != null) {
-                        greatGrandParentName = greatGrandParent.getLocalName();
-                    }
-                }
-
-                AndroidTargetData data = mEditor.getTargetData();
-                if (data != null) {
-                    choices = data.getAttributeValues(parent, attrInfo.name, greatGrandParentName);
-                }
-            }
-        } else {
-            // Editing an attribute's name... Get attributes valid for the parent node.
-            if (currentUiNode != null) {
-                choices = currentUiNode.getAttributeDescriptors();
-            } else {
-                ElementDescriptor parent_desc = getDescriptor(parent);
-                choices = parent_desc.getAttributes();
-            }
-        }
-        return choices;
-    }
-
-    /**
-     * Gets the choices when the user is editing an XML text node.
-     * <p/>
-     * This means the user is editing outside of any XML element or attribute.
-     * Simply return the list of XML elements that can be present there, based on the
-     * parent of the current node.
-     *
-     * @return An ElementDescriptor[] or null.
-     */
-    private Object[] getChoicesForTextNode(Node currentNode) {
-        Object[] choices = null;
-        String parent;
-        Node parent_node = currentNode.getParentNode();
-        if (parent_node.getNodeType() == Node.ELEMENT_NODE) {
-            // We're editing a text node which parent is an element node. Limit
-            // content assist to elements valid for the parent.
-            parent = parent_node.getNodeName();
-            ElementDescriptor desc = getDescriptor(parent);
-            if (desc != null) {
-                choices = desc.getChildren();
-            }
-        } else if (parent_node.getNodeType() == Node.DOCUMENT_NODE) {
-            // We're editing a text node at the first level (i.e. root node).
-            // Limit content assist to the only valid root elements.
-            choices = getRootDescriptor().getChildren();
-        }
-        return choices;
-    }
-
-    /**
-     * Given a list of choices found, generates the proposals to be displayed to the user.
-     * <p/>
-     * Choices is an object array. Items of the array can be:
-     * - ElementDescriptor: a possible element descriptor which XML name should be completed.
-     * - AttributeDescriptor: a possible attribute descriptor which XML name should be completed.
-     * - String: string values to display as-is to the user. Typically those are possible
-     *           values for a given attribute.
-     *
-     * @return The ICompletionProposal[] to display to the user.
-     */
-    private ICompletionProposal[] computeProposals(int offset, Node currentNode,
-            Object[] choices, String wordPrefix, char need_tag,
-            boolean is_attribute, int selectionLength) {
-        ArrayList<CompletionProposal> proposals = new ArrayList<CompletionProposal>();
-        HashMap<String, String> nsUriMap = new HashMap<String, String>();
-
-        for (Object choice : choices) {
-            String keyword = null;
-            String nsPrefix = null;
-            Image icon = null;
-            String tooltip = null;
-            if (choice instanceof ElementDescriptor) {
-                keyword = ((ElementDescriptor)choice).getXmlName();
-                icon    = ((ElementDescriptor)choice).getIcon();
-                tooltip = DescriptorsUtils.formatTooltip(((ElementDescriptor)choice).getTooltip());
-            } else if (choice instanceof TextValueDescriptor) {
-                continue; // Value nodes are not part of the completion choices
-            } else if (choice instanceof SeparatorAttributeDescriptor) {
-                continue; // not real attribute descriptors
-            } else if (choice instanceof AttributeDescriptor) {
-                keyword = ((AttributeDescriptor)choice).getXmlLocalName();
-                icon    = ((AttributeDescriptor)choice).getIcon();
-                if (choice instanceof TextAttributeDescriptor) {
-                    tooltip = ((TextAttributeDescriptor) choice).getTooltip();
-                }
-
-                // Get the namespace URI for the attribute. Note that some attributes
-                // do not have a namespace and thus return null here.
-                String nsUri = ((AttributeDescriptor)choice).getNamespaceUri();
-                if (nsUri != null) {
-                    nsPrefix = nsUriMap.get(nsUri);
-                    if (nsPrefix == null) {
-                        nsPrefix = lookupNamespacePrefix(currentNode, nsUri);
-                        nsUriMap.put(nsUri, nsPrefix);
-                    }
-                }
-                if (nsPrefix != null) {
-                    nsPrefix += ":"; //$NON-NLS-1$
-                }
-
-            } else if (choice instanceof String) {
-                keyword = (String) choice;
-            } else {
-                continue; // discard unknown choice
-            }
-
-            String nsKeyword = nsPrefix == null ? keyword : (nsPrefix + keyword);
-
-            if (keyword.startsWith(wordPrefix) ||
-                    (nsPrefix != null && keyword.startsWith(nsPrefix)) ||
-                    (nsPrefix != null && nsKeyword.startsWith(wordPrefix))) {
-                if (nsPrefix != null) {
-                    keyword = nsPrefix + keyword;
-                }
-                String end_tag = ""; //$NON-NLS-1$
-                if (need_tag != 0) {
-                    if (need_tag == '"') {
-                        keyword = need_tag + keyword;
-                        end_tag = String.valueOf(need_tag);
-                    } else if (need_tag == '<') {
-                        if (elementCanHaveChildren(choice)) {
-                            end_tag = String.format("></%1$s>", keyword);  //$NON-NLS-1$
-                            keyword = need_tag + keyword;
-                        } else {
-                            keyword = need_tag + keyword;
-                            end_tag = "/>";  //$NON-NLS-1$
-                        }
-                    }
-                }
-                CompletionProposal proposal = new CompletionProposal(
-                        keyword + end_tag,                  // String replacementString
-                        offset - wordPrefix.length(),           // int replacementOffset
-                        wordPrefix.length() + selectionLength,  // int replacementLength
-                        keyword.length(),                   // int cursorPosition (rel. to rplcmntOffset)
-                        icon,                               // Image image
-                        null,                               // String displayString
-                        null,                               // IContextInformation contextInformation
-                        tooltip                             // String additionalProposalInfo
-                        );
-
-                proposals.add(proposal);
-            }
-        }
-
-        return proposals.toArray(new ICompletionProposal[proposals.size()]);
-    }
-
-    /**
-     * Indicates whether this descriptor describes an element that can potentially
-     * have children (either sub-elements or text value). If an element can have children,
-     * we want to explicitly write an opening and a separate closing tag.
-     * <p/>
-     * Elements can have children if the descriptor has children element descriptors
-     * or if one of the attributes is a TextValueDescriptor.
-     *
-     * @param descriptor An ElementDescriptor or an AttributeDescriptor
-     * @return True if the descriptor is an ElementDescriptor that can have children or a text value
-     */
-    private boolean elementCanHaveChildren(Object descriptor) {
-        if (descriptor instanceof ElementDescriptor) {
-            ElementDescriptor desc = (ElementDescriptor) descriptor;
-            if (desc.hasChildren()) {
-                return true;
-            }
-            for (AttributeDescriptor attr_desc : desc.getAttributes()) {
-                if (attr_desc instanceof TextValueDescriptor) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns the element descriptor matching a given XML node name or null if it can't be
-     * found.
-     * <p/>
-     * This is simplistic; ideally we should consider the parent's chain to make sure we
-     * can differentiate between different hierarchy trees. Right now the first match found
-     * is returned.
-     */
-    private ElementDescriptor getDescriptor(String nodeName) {
-        return getRootDescriptor().findChildrenDescriptor(nodeName, true /* recursive */);
-    }
-
-    public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
-        return null;
-    }
-
-    /**
-     * Returns the characters which when entered by the user should
-     * automatically trigger the presentation of possible completions.
-     *
-     * In our case, we auto-activate on opening tags and attributes namespace.
-     *
-     * @return the auto activation characters for completion proposal or <code>null</code>
-     *      if no auto activation is desired
-     */
-    public char[] getCompletionProposalAutoActivationCharacters() {
-        return new char[]{ '<', ':', '=' };
-    }
-
-    public char[] getContextInformationAutoActivationCharacters() {
-        return null;
-    }
-
-    public IContextInformationValidator getContextInformationValidator() {
-        return null;
-    }
-
-    public String getErrorMessage() {
-        return null;
-    }
-
-    /**
-     * Heuristically extracts the prefix used for determining template relevance
-     * from the viewer's document. The default implementation returns the String from
-     * offset backwards that forms a potential XML element name, attribute name or
-     * attribute value.
-     *
-     * The part were we access the docment was extracted from
-     * org.eclipse.jface.text.templatesTemplateCompletionProcessor and adapted to our needs.
-     *
-     * @param viewer the viewer
-     * @param offset offset into document
-     * @return the prefix to consider
-     */
-    protected String extractElementPrefix(ITextViewer viewer, int offset) {
-        int i = offset;
-        IDocument document = viewer.getDocument();
-        if (i > document.getLength()) return ""; //$NON-NLS-1$
-
-        try {
-            for (; i > 0; --i) {
-                char ch = document.getChar(i - 1);
-
-                // We want all characters that can form a valid:
-                // - element name, e.g. anything that is a valid Java class/variable literal.
-                // - attribute name, including : for the namespace
-                // - attribute value.
-                // Before we were inclusive and that made the code fragile. So now we're
-                // going to be exclusive: take everything till we get one of:
-                // - any form of whitespace
-                // - any xml separator, e.g. < > ' " and =
-                if (Character.isWhitespace(ch) ||
-                        ch == '<' || ch == '>' || ch == '\'' || ch == '"' || ch == '=') {
-                    break;
-                }
-            }
-
-            return document.get(i, offset - i);
-        } catch (BadLocationException e) {
-            return ""; //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Extracts the character at the given offset.
-     * Returns 0 if the offset is invalid.
-     */
-    protected char extractChar(ITextViewer viewer, int offset) {
-        IDocument document = viewer.getDocument();
-        if (offset > document.getLength()) return 0;
-
-        try {
-            return document.getChar(offset);
-        } catch (BadLocationException e) {
-            return 0;
-        }
-    }
-
-    /**
-     * Information about the current edit of an attribute as reported by parseAttributeInfo.
-     */
-    private class AttribInfo {
-        /** True if the cursor is located in an attribute's value, false if in an attribute name */
-        public boolean isInValue = false;
-        /** The attribute name. Null when not set. */
-        public String name = null;
-        /** The attribute value. Null when not set. The value *may* start with a quote
-         *  (' or "), in which case we know we don't need to quote the string for the user */
-        public String value = null;
-        /** String typed by the user so far (i.e. right before requesting code completion),
-         *  which will be corrected if we find a possible completion for an attribute value.
-         *  See the long comment in getChoicesForAttribute(). */
-        public String correctedPrefix = null;
-        /** Non-zero if an attribute value need a start/end tag (i.e. quotes or brackets) */
-        public char needTag = 0;
-    }
-
-
-    /**
-     * Try to guess if the cursor is editing an element's name or an attribute following an
-     * element. If it's an attribute, try to find if an attribute name is being defined or
-     * its value.
-     * <br/>
-     * This is currently *only* called when we know the cursor is after a complete element
-     * tag name, so it should never return null.
-     * <br/>
-     * Reference for XML syntax: http://www.w3.org/TR/2006/REC-xml-20060816/#sec-starttags
-     * <br/>
-     * @return An AttribInfo describing which attribute is being edited or null if the cursor is
-     *         not editing an attribute (in which case it must be an element's name).
-     */
-    private AttribInfo parseAttributeInfo(ITextViewer viewer, int offset) {
-        AttribInfo info = new AttribInfo();
-
-        IDocument document = viewer.getDocument();
-        int n = document.getLength();
-        if (offset <= n) {
-            try {
-                n = offset;
-                for (;offset > 0; --offset) {
-                    char ch = document.getChar(offset - 1);
-                    if (ch == '<') break;
-                }
-
-                // text will contain the full string of the current element,
-                // i.e. whatever is after the "<" to the current cursor
-                String text = document.get(offset, n - offset);
-
-                // Normalize whitespace to single spaces
-                text = sWhitespace.matcher(text).replaceAll(" "); //$NON-NLS-1$
-
-                // Remove the leading element name. By spec, it must be after the < without
-                // any whitespace. If there's nothing left, no attribute has been defined yet.
-                // Be sure to keep any whitespace after the initial word if any, as it matters.
-                text = sFirstElementWord.matcher(text).replaceFirst("");  //$NON-NLS-1$
-
-                // There MUST be space after the element name. If not, the cursor is still
-                // defining the element name.
-                if (!text.startsWith(" ")) { //$NON-NLS-1$
-                    return null;
-                }
-
-                // Remove full attributes:
-                // Syntax:
-                //    name = "..." quoted string with all but < and "
-                // or:
-                //    name = '...' quoted string with all but < and '
-                String temp;
-                do {
-                    temp = text;
-                    text = sFirstAttribute.matcher(temp).replaceFirst("");  //$NON-NLS-1$
-                } while(!temp.equals(text));
-
-                // Now we're left with 3 cases:
-                // - nothing: either there is no attribute definition or the cursor located after
-                //   a completed attribute definition.
-                // - a string with no =: the user is writing an attribute name. This case can be
-                //   merged with the previous one.
-                // - string with an = sign, optionally followed by a quote (' or "): the user is
-                //   writing the value of the attribute.
-                int pos_equal = text.indexOf('=');
-                if (pos_equal == -1) {
-                    info.isInValue = false;
-                    info.name = text.trim();
-                } else {
-                    info.isInValue = true;
-                    info.name = text.substring(0, pos_equal).trim();
-                    info.value = text.substring(pos_equal + 1).trim();
-                }
-                return info;
-            } catch (BadLocationException e) {
-                // pass
-            }
-        }
-
-        return null;
-    }
-
-
-    /**
-     * Returns the XML DOM node corresponding to the given offset of the given document.
-     */
-    protected Node getNode(ITextViewer viewer, int offset) {
-        Node node = null;
-        try {
-            IModelManager mm = StructuredModelManager.getModelManager();
-            if (mm != null) {
-                IStructuredModel model = mm.getExistingModelForRead(viewer.getDocument());
-                if (model != null) {
-                    for(; offset >= 0 && node == null; --offset) {
-                        node = (Node) model.getIndexedRegion(offset);
-                    }
-                }
-            }
-        } catch (Exception e) {
-            // Ignore exceptions.
-        }
-
-        return node;
-    }
-
-    /**
-     * Computes (if needed) and returns the root descriptor.
-     */
-    private ElementDescriptor getRootDescriptor() {
-        if (mRootDescriptor == null) {
-            AndroidTargetData data = mEditor.getTargetData();
-            if (data != null) {
-                IDescriptorProvider descriptorProvider = data.getDescriptorProvider(mDescriptorId);
-
-                if (descriptorProvider != null) {
-                    mRootDescriptor = new ElementDescriptor("",     //$NON-NLS-1$
-                            descriptorProvider.getRootElementDescriptors());
-                }
-            }
-        }
-
-        return mRootDescriptor;
-    }
-
-    /**
-     * Returns the active {@link AndroidEditor} matching this source viewer.
-     */
-    private AndroidEditor getAndroidEditor(ITextViewer viewer) {
-        IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-        if (wwin != null) {
-            IWorkbenchPage page = wwin.getActivePage();
-            if (page != null) {
-                IEditorPart editor = page.getActiveEditor();
-                if (editor instanceof AndroidEditor) {
-                    ISourceViewer ssviewer = ((AndroidEditor) editor).getStructuredSourceViewer();
-                    if (ssviewer == viewer) {
-                        return (AndroidEditor) editor;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidEditor.java
deleted file mode 100644
index 336b46a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidEditor.java
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.editor.IFormPage;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.events.IHyperlinkListener;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
-import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.ui.part.MultiPageEditorPart;
-import org.eclipse.ui.part.WorkbenchPart;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.sse.ui.StructuredTextEditor;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
-import org.w3c.dom.Document;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Multi-page form editor for Android XML files.
- * <p/>
- * It is designed to work with a {@link StructuredTextEditor} that will display an XML file.
- * <br/>
- * Derived classes must implement createFormPages to create the forms before the
- * source editor. This can be a no-op if desired.
- */
-public abstract class AndroidEditor extends FormEditor implements IResourceChangeListener {
-
-    /** Preference name for the current page of this file */
-    private static final String PREF_CURRENT_PAGE = "_current_page";
-
-    /** Id string used to create the Android SDK browser */
-    private static String BROWSER_ID = "android"; // $NON-NLS-1$
-
-    /** Page id of the XML source editor, used for switching tabs programmatically */
-    public final static String TEXT_EDITOR_ID = "editor_part"; //$NON-NLS-1$
-
-    /** Width hint for text fields. Helps the grid layout resize properly on smaller screens */
-    public static final int TEXT_WIDTH_HINT = 50;
-
-    /** Page index of the text editor (always the last page) */
-    private int mTextPageIndex;
-    /** The text editor */
-    private StructuredTextEditor mTextEditor;
-    /** Listener for the XML model from the StructuredEditor */
-    private XmlModelStateListener mXmlModelStateListener;
-    /** Listener to update the root node if the target of the file is changed because of a
-     * SDK location change or a project target change */
-    private ITargetChangeListener mTargetListener;
-
-    /**
-     * Creates a form editor.
-     */
-    public AndroidEditor() {
-        super();
-        ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
-
-        mTargetListener = new ITargetChangeListener() {
-            public void onProjectTargetChange(IProject changedProject) {
-                if (changedProject == getProject()) {
-                    onTargetsLoaded();
-                }
-            }
-
-            public void onTargetsLoaded() {
-                commitPages(false /* onSave */);
-
-                // recreate the ui root node always
-                initUiRootNode(true /*force*/);
-            }
-        };
-        AdtPlugin.getDefault().addTargetListener(mTargetListener);
-    }
-
-    // ---- Abstract Methods ----
-
-    /**
-     * Returns the root node of the UI element hierarchy manipulated by the current
-     * UI node editor.
-     */
-    abstract public UiElementNode getUiRootNode();
-
-    /**
-     * Creates the various form pages.
-     * <p/>
-     * Derived classes must implement this to add their own specific tabs.
-     */
-    abstract protected void createFormPages();
-
-    /**
-     * Creates the initial UI Root Node, including the known mandatory elements.
-     * @param force if true, a new UiManifestNode is recreated even if it already exists.
-     */
-    abstract protected void initUiRootNode(boolean force);
-
-    /**
-     * Subclasses should override this method to process the new XML Model, which XML
-     * root node is given.
-     *
-     * The base implementation is empty.
-     *
-     * @param xml_doc The XML document, if available, or null if none exists.
-     */
-    protected void xmlModelChanged(Document xml_doc) {
-        // pass
-    }
-
-    // ---- Base Class Overrides, Interfaces Implemented ----
-
-    /**
-     * Creates the pages of the multi-page editor.
-     */
-    @Override
-    protected void addPages() {
-        createAndroidPages();
-        selectDefaultPage(null /* defaultPageId */);
-    }
-
-    /**
-     * Creates the page for the Android Editors
-     */
-    protected void createAndroidPages() {
-        createFormPages();
-        createTextEditor();
-
-        createUndoRedoActions();
-    }
-
-    /**
-     * Creates undo redo actions for the editor site (so that it works for any page of this
-     * multi-page editor) by re-using the actions defined by the {@link StructuredTextEditor}
-     * (aka the XML text editor.)
-     */
-    private void createUndoRedoActions() {
-        IActionBars bars = getEditorSite().getActionBars();
-        if (bars != null) {
-            IAction action = mTextEditor.getAction(ActionFactory.UNDO.getId());
-            bars.setGlobalActionHandler(ActionFactory.UNDO.getId(), action);
-
-            action = mTextEditor.getAction(ActionFactory.REDO.getId());
-            bars.setGlobalActionHandler(ActionFactory.REDO.getId(), action);
-
-            bars.updateActionBars();
-        }
-    }
-
-    /**
-     * Selects the default active page.
-     * @param defaultPageId the id of the page to show. If <code>null</code> the editor attempts to
-     * find the default page in the properties of the {@link IResource} object being edited.
-     */
-    protected void selectDefaultPage(String defaultPageId) {
-        if (defaultPageId == null) {
-            if (getEditorInput() instanceof IFileEditorInput) {
-                IFile file = ((IFileEditorInput) getEditorInput()).getFile();
-
-                QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID,
-                        getClass().getSimpleName() + PREF_CURRENT_PAGE);
-                String pageId;
-                try {
-                    pageId = file.getPersistentProperty(qname);
-                    if (pageId != null) {
-                        defaultPageId = pageId;
-                    }
-                } catch (CoreException e) {
-                    // ignored
-                }
-            }
-        }
-
-        if (defaultPageId != null) {
-            try {
-                setActivePage(Integer.parseInt(defaultPageId));
-            } catch (Exception e) {
-                // We can get NumberFormatException from parseInt but also
-                // AssertionError from setActivePage when the index is out of bounds.
-                // Generally speaking we just want to ignore any exception and fall back on the
-                // first page rather than crash the editor load. Logging the error is enough.
-                AdtPlugin.log(e, "Selecting page '%s' in AndroidEditor failed", defaultPageId);
-            }
-        }
-    }
-
-    /**
-     * Removes all the pages from the editor.
-     */
-    protected void removePages() {
-        int count = getPageCount();
-        for (int i = count - 1 ; i >= 0 ; i--) {
-            removePage(i);
-        }
-    }
-
-    /**
-     * Overrides the parent's setActivePage to be able to switch to the xml editor.
-     *
-     * If the special pageId TEXT_EDITOR_ID is given, switches to the mTextPageIndex page.
-     * This is needed because the editor doesn't actually derive from IFormPage and thus
-     * doesn't have the get-by-page-id method. In this case, the method returns null since
-     * IEditorPart does not implement IFormPage.
-     */
-    @Override
-    public IFormPage setActivePage(String pageId) {
-        if (pageId.equals(TEXT_EDITOR_ID)) {
-            super.setActivePage(mTextPageIndex);
-            return null;
-        } else {
-            return super.setActivePage(pageId);
-        }
-    }
-
-
-    /**
-     * Notifies this multi-page editor that the page with the given id has been
-     * activated. This method is called when the user selects a different tab.
-     *
-     * @see MultiPageEditorPart#pageChange(int)
-     */
-    @Override
-    protected void pageChange(int newPageIndex) {
-        super.pageChange(newPageIndex);
-
-        if (getEditorInput() instanceof IFileEditorInput) {
-            IFile file = ((IFileEditorInput) getEditorInput()).getFile();
-
-            QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID,
-                    getClass().getSimpleName() + PREF_CURRENT_PAGE);
-            try {
-                file.setPersistentProperty(qname, Integer.toString(newPageIndex));
-            } catch (CoreException e) {
-                // ignore
-            }
-        }
-    }
-
-    /**
-     * Notifies this listener that some resource changes
-     * are happening, or have already happened.
-     *
-     * Closes all project files on project close.
-     * @see IResourceChangeListener
-     */
-    public void resourceChanged(final IResourceChangeEvent event) {
-        if (event.getType() == IResourceChangeEvent.PRE_CLOSE) {
-            Display.getDefault().asyncExec(new Runnable() {
-                public void run() {
-                    IWorkbenchPage[] pages = getSite().getWorkbenchWindow()
-                            .getPages();
-                    for (int i = 0; i < pages.length; i++) {
-                        if (((FileEditorInput)mTextEditor.getEditorInput())
-                                .getFile().getProject().equals(
-                                        event.getResource())) {
-                            IEditorPart editorPart = pages[i].findEditor(mTextEditor
-                                    .getEditorInput());
-                            pages[i].closeEditor(editorPart, true);
-                        }
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Initializes the editor part with a site and input.
-     * <p/>
-     * Checks that the input is an instance of {@link IFileEditorInput}.
-     *
-     * @see FormEditor
-     */
-    @Override
-    public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
-        if (!(editorInput instanceof IFileEditorInput))
-            throw new PartInitException("Invalid Input: Must be IFileEditorInput");
-        super.init(site, editorInput);
-    }
-
-    /**
-     * Removes attached listeners.
-     *
-     * @see WorkbenchPart
-     */
-    @Override
-    public void dispose() {
-        IStructuredModel xml_model = getModelForRead();
-        if (xml_model != null) {
-            try {
-                if (mXmlModelStateListener != null) {
-                    xml_model.removeModelStateListener(mXmlModelStateListener);
-                }
-
-            } finally {
-                xml_model.releaseFromRead();
-            }
-        }
-        ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
-
-        if (mTargetListener != null) {
-            AdtPlugin.getDefault().removeTargetListener(mTargetListener);
-            mTargetListener = null;
-        }
-
-        super.dispose();
-    }
-
-    /**
-     * Commit all dirty pages then saves the contents of the text editor.
-     * <p/>
-     * This works by committing all data to the XML model and then
-     * asking the Structured XML Editor to save the XML.
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public void doSave(IProgressMonitor monitor) {
-        commitPages(true /* onSave */);
-
-        // The actual "save" operation is done by the Structured XML Editor
-        getEditor(mTextPageIndex).doSave(monitor);
-    }
-
-    /* (non-Javadoc)
-     * Saves the contents of this editor to another object.
-     * <p>
-     * Subclasses must override this method to implement the open-save-close lifecycle
-     * for an editor.  For greater details, see <code>IEditorPart</code>
-     * </p>
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public void doSaveAs() {
-        commitPages(true /* onSave */);
-
-        IEditorPart editor = getEditor(mTextPageIndex);
-        editor.doSaveAs();
-        setPageText(mTextPageIndex, editor.getTitle());
-        setInput(editor.getEditorInput());
-    }
-
-    /**
-     * Commits all dirty pages in the editor. This method should
-     * be called as a first step of a 'save' operation.
-     * <p/>
-     * This is the same implementation as in {@link FormEditor}
-     * except it fixes two bugs: a cast to IFormPage is done
-     * from page.get(i) <em>before</em> being tested with instanceof.
-     * Another bug is that the last page might be a null pointer.
-     * <p/>
-     * The incorrect casting makes the original implementation crash due
-     * to our {@link StructuredTextEditor} not being an {@link IFormPage}
-     * so we have to override and duplicate to fix it.
-     *
-     * @param onSave <code>true</code> if commit is performed as part
-     * of the 'save' operation, <code>false</code> otherwise.
-     * @since 3.3
-     */
-    @Override
-    public void commitPages(boolean onSave) {
-        if (pages != null) {
-            for (int i = 0; i < pages.size(); i++) {
-                Object page = pages.get(i);
-                if (page != null && page instanceof IFormPage) {
-                    IFormPage form_page = (IFormPage) page;
-                    IManagedForm managed_form = form_page.getManagedForm();
-                    if (managed_form != null && managed_form.isDirty()) {
-                        managed_form.commit(onSave);
-                    }
-                }
-            }
-        }
-    }
-
-    /* (non-Javadoc)
-     * Returns whether the "save as" operation is supported by this editor.
-     * <p>
-     * Subclasses must override this method to implement the open-save-close lifecycle
-     * for an editor.  For greater details, see <code>IEditorPart</code>
-     * </p>
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public boolean isSaveAsAllowed() {
-        return false;
-    }
-
-    // ---- Local methods ----
-
-
-    /**
-     * Helper method that creates a new hyper-link Listener.
-     * Used by derived classes which need active links in {@link FormText}.
-     * <p/>
-     * This link listener handles two kinds of URLs:
-     * <ul>
-     * <li> Links starting with "http" are simply sent to a local browser.
-     * <li> Links starting with "file:/" are simply sent to a local browser.
-     * <li> Links starting with "page:" are expected to be an editor page id to switch to.
-     * <li> Other links are ignored.
-     * </ul>
-     *
-     * @return A new hyper-link listener for FormText to use.
-     */
-    public final IHyperlinkListener createHyperlinkListener() {
-        return new HyperlinkAdapter() {
-            /**
-             * Switch to the page corresponding to the link that has just been clicked.
-             * For this purpose, the HREF of the &lt;a&gt; tags above is the page ID to switch to.
-             */
-            @Override
-            public void linkActivated(HyperlinkEvent e) {
-                super.linkActivated(e);
-                String link = e.data.toString();
-                if (link.startsWith("http") ||          //$NON-NLS-1$
-                        link.startsWith("file:/")) {    //$NON-NLS-1$
-                    openLinkInBrowser(link);
-                } else if (link.startsWith("page:")) {  //$NON-NLS-1$
-                    // Switch to an internal page
-                    setActivePage(link.substring(5 /* strlen("page:") */));
-                }
-            }
-        };
-    }
-
-    /**
-     * Open the http link into a browser
-     *
-     * @param link The URL to open in a browser
-     */
-    private void openLinkInBrowser(String link) {
-        try {
-            IWorkbenchBrowserSupport wbs = WorkbenchBrowserSupport.getInstance();
-            wbs.createBrowser(BROWSER_ID).openURL(new URL(link));
-        } catch (PartInitException e1) {
-            // pass
-        } catch (MalformedURLException e1) {
-            // pass
-        }
-    }
-
-    /**
-     * Creates the XML source editor.
-     * <p/>
-     * Memorizes the index page of the source editor (it's always the last page, but the number
-     * of pages before can change.)
-     * <br/>
-     * Retrieves the underlying XML model from the StructuredEditor and attaches a listener to it.
-     * Finally triggers modelChanged() on the model listener -- derived classes can use this
-     * to initialize the model the first time.
-     * <p/>
-     * Called only once <em>after</em> createFormPages.
-     */
-    private void createTextEditor() {
-        try {
-            mTextEditor = new StructuredTextEditor();
-            int index = addPage(mTextEditor, getEditorInput());
-            mTextPageIndex = index;
-            setPageText(index, mTextEditor.getTitle());
-
-            if (!(mTextEditor.getTextViewer().getDocument() instanceof IStructuredDocument)) {
-                Status status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                        "Error opening the Android XML editor. Is the document an XML file?");
-                throw new RuntimeException("Android XML Editor Error", new CoreException(status));
-            }
-
-            IStructuredModel xml_model = getModelForRead();
-            if (xml_model != null) {
-                try {
-                    mXmlModelStateListener = new XmlModelStateListener();
-                    xml_model.addModelStateListener(mXmlModelStateListener);
-                    mXmlModelStateListener.modelChanged(xml_model);
-                } catch (Exception e) {
-                    AdtPlugin.log(e, "Error while loading editor"); //$NON-NLS-1$
-                } finally {
-                    xml_model.releaseFromRead();
-                }
-            }
-        } catch (PartInitException e) {
-            ErrorDialog.openError(getSite().getShell(),
-                    "Android XML Editor Error", null, e.getStatus());
-        }
-    }
-
-    /**
-     * Returns the ISourceViewer associated with the Structured Text editor.
-     */
-    public final ISourceViewer getStructuredSourceViewer() {
-        if (mTextEditor != null) {
-            // We can't access mEditor.getSourceViewer() because it is protected,
-            // however getTextViewer simply returns the SourceViewer casted, so we
-            // can use it instead.
-            return mTextEditor.getTextViewer();
-        }
-        return null;
-    }
-
-    /**
-     * Returns the {@link IStructuredDocument} used by the StructuredTextEditor (aka Source
-     * Editor) or null if not available.
-     */
-    public final IStructuredDocument getStructuredDocument() {
-        if (mTextEditor != null && mTextEditor.getTextViewer() != null) {
-            return (IStructuredDocument) mTextEditor.getTextViewer().getDocument();
-        }
-        return null;
-    }
-
-    /**
-     * Returns a version of the model that has been shared for read.
-     * <p/>
-     * Callers <em>must</em> call model.releaseFromRead() when done, typically
-     * in a try..finally clause.
-     *
-     * Portability note: this uses getModelManager which is part of wst.sse.core; however
-     * the interface returned is part of wst.sse.core.internal.provisional so we can
-     * expect it to change in a distant future if they start cleaning their codebase,
-     * however unlikely that is.
-     *
-     * @return The model for the XML document or null if cannot be obtained from the editor
-     */
-    public final IStructuredModel getModelForRead() {
-        IStructuredDocument document = getStructuredDocument();
-        if (document != null) {
-            IModelManager mm = StructuredModelManager.getModelManager();
-            if (mm != null) {
-                return mm.getModelForRead(document);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns a version of the model that has been shared for edit.
-     * <p/>
-     * Callers <em>must</em> call model.releaseFromEdit() when done, typically
-     * in a try..finally clause.
-     *
-     * @return The model for the XML document or null if cannot be obtained from the editor
-     */
-    public final IStructuredModel getModelForEdit() {
-        IStructuredDocument document = getStructuredDocument();
-        if (document != null) {
-            IModelManager mm = StructuredModelManager.getModelManager();
-            if (mm != null) {
-                return mm.getModelForEdit(document);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Helper class to perform edits on the XML model whilst making sure the
-     * model has been prepared to be changed.
-     * <p/>
-     * It first gets a model for edition using {@link #getModelForEdit()},
-     * then calls {@link IStructuredModel#aboutToChangeModel()},
-     * then performs the requested action
-     * and finally calls {@link IStructuredModel#changedModel()}
-     * and {@link IStructuredModel#releaseFromEdit()}.
-     * <p/>
-     * The method is synchronous. As soon as the {@link IStructuredModel#changedModel()} method
-     * is called, XML model listeners will be triggered.
-     *
-     * @param edit_action Something that will change the XML.
-     */
-    public final void editXmlModel(Runnable edit_action) {
-        IStructuredModel model = getModelForEdit();
-        try {
-            model.aboutToChangeModel();
-            edit_action.run();
-        } finally {
-            // Notify the model we're done modifying it. This must *always* be executed.
-            model.changedModel();
-            model.releaseFromEdit();
-        }
-    }
-
-    /**
-     * Starts an "undo recording" session. This is managed by the underlying undo manager
-     * associated to the structured XML model.
-     * <p/>
-     * There <em>must</em> be a corresponding call to {@link #endUndoRecording()}.
-     * <p/>
-     * beginUndoRecording/endUndoRecording calls can be nested (inner calls are ignored, only one
-     * undo operation is recorded.)
-     *
-     * @param label The label for the undo operation. Can be null but we should really try to put
-     *              something meaningful if possible.
-     * @return True if the undo recording actually started, false if any kind of error occured.
-     *         {@link #endUndoRecording()} should only be called if True is returned.
-     */
-    private final boolean beginUndoRecording(String label) {
-        IStructuredDocument document = getStructuredDocument();
-        if (document != null) {
-            IModelManager mm = StructuredModelManager.getModelManager();
-            if (mm != null) {
-                IStructuredModel model = mm.getModelForEdit(document);
-                if (model != null) {
-                    model.beginRecording(this, label);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Ends an "undo recording" session.
-     * <p/>
-     * This is the counterpart call to {@link #beginUndoRecording(String)} and should only be
-     * used if the initial call returned true.
-     */
-    private final void endUndoRecording() {
-        IStructuredDocument document = getStructuredDocument();
-        if (document != null) {
-            IModelManager mm = StructuredModelManager.getModelManager();
-            if (mm != null) {
-                IStructuredModel model = mm.getModelForEdit(document);
-                if (model != null) {
-                    model.endRecording(this);
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates an "undo recording" session by calling the undoableAction runnable
-     * using {@link #beginUndoRecording(String)} and {@link #endUndoRecording()}.
-     * <p>
-     * You can nest several calls to {@link #wrapUndoRecording(String, Runnable)}, only one
-     * recording session will be created.
-     *
-     * @param label The label for the undo operation. Can be null. Ideally we should really try
-     *              to put something meaningful if possible.
-     */
-    public void wrapUndoRecording(String label, Runnable undoableAction) {
-        boolean recording = false;
-        try {
-            recording = beginUndoRecording(label);
-            undoableAction.run();
-        } finally {
-            if (recording) {
-                endUndoRecording();
-            }
-        }
-    }
-
-    /**
-     * Returns the XML {@link Document} or null if we can't get it
-     */
-    protected final Document getXmlDocument(IStructuredModel model) {
-        if (model == null) {
-            AdtPlugin.log(IStatus.WARNING, "Android Editor: No XML model for root node."); //$NON-NLS-1$
-            return null;
-        }
-
-        if (model instanceof IDOMModel) {
-            IDOMModel dom_model = (IDOMModel) model;
-            return dom_model.getDocument();
-        }
-        return null;
-    }
-
-    /**
-     * Returns the {@link IProject} for the edited file.
-     */
-    public IProject getProject() {
-        if (mTextEditor != null) {
-            IEditorInput input = mTextEditor.getEditorInput();
-            if (input instanceof FileEditorInput) {
-                FileEditorInput fileInput = (FileEditorInput)input;
-                IFile inputFile = fileInput.getFile();
-
-                if (inputFile != null) {
-                    return inputFile.getProject();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the {@link AndroidTargetData} for the edited file.
-     */
-    public AndroidTargetData getTargetData() {
-        IProject project = getProject();
-        if (project != null) {
-            Sdk currentSdk = Sdk.getCurrent();
-            if (currentSdk != null) {
-                IAndroidTarget target = currentSdk.getTarget(project);
-
-                if (target != null) {
-                    return currentSdk.getTargetData(target);
-                }
-            }
-        }
-
-        return null;
-    }
-
-
-    /**
-     * Listen to changes in the underlying XML model in the structured editor.
-     */
-    private class XmlModelStateListener implements IModelStateListener {
-
-        /**
-         * A model is about to be changed. This typically is initiated by one
-         * client of the model, to signal a large change and/or a change to the
-         * model's ID or base Location. A typical use might be if a client might
-         * want to suspend processing until all changes have been made.
-         * <p/>
-         * This AndroidEditor implementation of IModelChangedListener is empty.
-         */
-        public void modelAboutToBeChanged(IStructuredModel model) {
-            // pass
-        }
-
-        /**
-         * Signals that the changes foretold by modelAboutToBeChanged have been
-         * made. A typical use might be to refresh, or to resume processing that
-         * was suspended as a result of modelAboutToBeChanged.
-         * <p/>
-         * This AndroidEditor implementation calls the xmlModelChanged callback.
-         */
-        public void modelChanged(IStructuredModel model) {
-            xmlModelChanged(getXmlDocument(model));
-        }
-
-        /**
-         * Notifies that a model's dirty state has changed, and passes that state
-         * in isDirty. A model becomes dirty when any change is made, and becomes
-         * not-dirty when the model is saved.
-         * <p/>
-         * This AndroidEditor implementation of IModelChangedListener is empty.
-         */
-        public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
-            // pass
-        }
-
-        /**
-         * A modelDeleted means the underlying resource has been deleted. The
-         * model itself is not removed from model management until all have
-         * released it. Note: baseLocation is not (necessarily) changed in this
-         * event, but may not be accurate.
-         * <p/>
-         * This AndroidEditor implementation of IModelChangedListener is empty.
-         */
-        public void modelResourceDeleted(IStructuredModel model) {
-            // pass
-        }
-
-        /**
-         * A model has been renamed or copied (as in saveAs..). In the renamed
-         * case, the two paramenters are the same instance, and only contain the
-         * new info for id and base location.
-         * <p/>
-         * This AndroidEditor implementation of IModelChangedListener is empty.
-         */
-        public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) {
-            // pass
-        }
-
-        /**
-         * This AndroidEditor implementation of IModelChangedListener is empty.
-         */
-        public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
-            // pass
-        }
-
-        /**
-         * This AndroidEditor implementation of IModelChangedListener is empty.
-         */
-        public void modelReinitialized(IStructuredModel structuredModel) {
-            // pass
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java
deleted file mode 100644
index 3b41252..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors;
-
-
-import org.eclipse.jface.text.IAutoEditStrategy;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.ITextHover;
-import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
-import org.eclipse.jface.text.contentassist.IContentAssistant;
-import org.eclipse.jface.text.formatter.IContentFormatter;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.jface.viewers.IInputProvider;
-import org.eclipse.wst.sse.core.text.IStructuredPartitions;
-import org.eclipse.wst.xml.core.text.IXMLPartitions;
-import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML;
-
-import java.util.ArrayList;
-
-/**
- * Base Source Viewer Configuration for Android resources.
- */
-public class AndroidSourceViewerConfig extends StructuredTextViewerConfigurationXML {
-
-    /** Content Assist Processor to use for all handled partitions. */
-    private IContentAssistProcessor mProcessor;
-
-    public AndroidSourceViewerConfig(IContentAssistProcessor processor) {
-        super();
-        mProcessor = processor;
-    }
-    
-    @Override
-    public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
-        return super.getContentAssistant(sourceViewer);
-    }
-
-    /**
-     * Returns the content assist processors that will be used for content
-     * assist in the given source viewer and for the given partition type.
-     * 
-     * @param sourceViewer the source viewer to be configured by this
-     *        configuration
-     * @param partitionType the partition type for which the content assist
-     *        processors are applicable
-     * @return IContentAssistProcessors or null if should not be supported
-     */
-    @Override
-    protected IContentAssistProcessor[] getContentAssistProcessors(
-            ISourceViewer sourceViewer, String partitionType) {
-        ArrayList<IContentAssistProcessor> processors = new ArrayList<IContentAssistProcessor>();
-        if (partitionType == IStructuredPartitions.UNKNOWN_PARTITION ||
-            partitionType == IStructuredPartitions.DEFAULT_PARTITION ||
-            partitionType == IXMLPartitions.XML_DEFAULT) {
-            if (sourceViewer instanceof IInputProvider) {
-                IInputProvider input = (IInputProvider) sourceViewer;
-                Object a = input.getInput();
-                if (a != null)
-                    a.toString();
-            }
-
-            IDocument doc = sourceViewer.getDocument();
-            if (doc != null)
-                doc.toString();
-            
-            processors.add(mProcessor);
-        }
-
-        IContentAssistProcessor[] others = super.getContentAssistProcessors(sourceViewer,
-                partitionType);
-        if (others != null && others.length > 0) {
-            for (IContentAssistProcessor p : others) {
-                processors.add(p);
-            }
-        }
-        
-        if (processors.size() > 0) {
-            return processors.toArray(new IContentAssistProcessor[processors.size()]);
-        } else {
-            return null;
-        }
-    }
-    
-    @Override
-    public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
-        // TODO text hover for android xml
-        return super.getTextHover(sourceViewer, contentType);
-    }
-
-    @Override
-    public IAutoEditStrategy[] getAutoEditStrategies(
-            ISourceViewer sourceViewer, String contentType) {
-        // TODO auto edit strategies for android xml
-        return super.getAutoEditStrategies(sourceViewer, contentType);
-    }
-    
-    @Override
-    public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
-        // TODO content formatter for android xml
-        return super.getContentFormatter(sourceViewer);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/FirstElementParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/FirstElementParser.java
deleted file mode 100644
index e48b321..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/FirstElementParser.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Quickly parses a (potential) XML file to extract its first element (i.e. the root element)
- * and namespace, if any.
- * <p/>
- * This is used to determine if a file is an XML document that the XmlEditor can process.
- * <p/>
- * TODO use this to remove the hardcoded "android" namespace prefix limitation.
- */
-public final class FirstElementParser {
-    
-    private static SAXParserFactory sSaxfactory;
-    
-    /**
-     * Result from the XML parsing. <br/>
-     * Contains the name of the root XML element. <br/>
-     * If an XMLNS URI was specified and found, the XMLNS prefix is recorded. Otherwise it is null.
-     */
-    public static final class Result {
-        private String mElement;
-        private String mXmlnsPrefix;
-        private String mXmlnsUri;
-        
-        public String getElement() {
-            return mElement;
-        }
-        
-        public String getXmlnsPrefix() {
-            return mXmlnsPrefix;
-        }
-        
-        public String getXmlnsUri() {
-            return mXmlnsUri;
-        }
-        
-        void setElement(String element) {
-            mElement = element;
-        }
-        
-        void setXmlnsPrefix(String xmlnsPrefix) {
-            mXmlnsPrefix = xmlnsPrefix;
-        }
-        
-        void setXmlnsUri(String xmlnsUri) {
-            mXmlnsUri = xmlnsUri;
-        }
-    }
-    
-    private static class ResultFoundException extends SAXException { }
-    
-    /**
-     * Parses the given filename.
-     * 
-     * @param osFilename The file to parse.
-     * @param xmlnsUri An optional URL of which we want to know the prefix. 
-     * @return The element details found or null if not found.
-     */
-    public static Result parse(String osFilename, String xmlnsUri) {
-        if (sSaxfactory == null) {
-            // TODO just create a single factory in CommonPlugin and reuse it
-            sSaxfactory = SAXParserFactory.newInstance();
-            sSaxfactory.setNamespaceAware(true);
-        }
-
-        Result result = new Result();
-        if (xmlnsUri != null && xmlnsUri.length() > 0) {
-            result.setXmlnsUri(xmlnsUri);
-        }
-
-        try {
-            SAXParser parser = sSaxfactory.newSAXParser();
-            XmlHandler handler = new XmlHandler(result);
-            parser.parse(new InputSource(new FileReader(osFilename)), handler);
-
-        } catch(ResultFoundException e) {
-            // XML handling was aborted because the required element was found.
-            // Simply return the result.
-            return result;
-        } catch (ParserConfigurationException e) {
-        } catch (SAXException e) {
-        } catch (FileNotFoundException e) {
-        } catch (IOException e) {
-        }
-
-        return null;
-    }
-
-    /**
-     * Private constructor. Use the static parse() method instead.
-     */
-    private FirstElementParser() {
-        // pass
-    }
-    
-    /**
-     * A specialized SAX handler that captures the arguments of the very first element
-     * (i.e. the root element)
-     */
-    private static class XmlHandler extends DefaultHandler {
-        private final Result mResult;
-
-        public XmlHandler(Result result) {
-            mResult = result;
-        }
-        
-        /**
-         * Processes a namespace prefix mapping.
-         * I.e. for xmlns:android="some-uri", this received prefix="android" and uri="some-uri".
-         * <p/>
-         * The prefix is recorded in the result structure if the URI is the one searched for.
-         * <p/>
-         * This event happens <em>before</em> the corresponding startElement event.
-         */
-        @Override
-        public void startPrefixMapping(String prefix, String uri) {
-            if (uri.equals(mResult.getXmlnsUri())) {
-                mResult.setXmlnsPrefix(prefix);
-            }
-        }
-
-        /**
-         * Processes a new element start.
-         * <p/>
-         * This simply records the element name and abort processing by throwing an exception.
-         */
-        @Override
-        public void startElement(String uri, String localName, String name, Attributes attributes)
-            throws SAXException {
-            mResult.setElement(localName);
-            throw new ResultFoundException();
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/IconFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/IconFactory.java
deleted file mode 100644
index c57734b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/IconFactory.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * 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.android.ide.eclipse.adt.internal.editors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Display;
-
-import java.util.HashMap;
-
-/**
- * Factory to generate icons for Android Editors.
- * <p/>
- * Icons are kept here and reused.
- */
-public class IconFactory {
-
-    public static final int COLOR_RED     = SWT.COLOR_DARK_RED;
-    public static final int COLOR_GREEN   = SWT.COLOR_DARK_GREEN;
-    public static final int COLOR_BLUE    = SWT.COLOR_DARK_BLUE;
-    public static final int COLOR_DEFAULT = SWT.COLOR_BLACK;
-
-    public static final int SHAPE_CIRCLE  = 'C';
-    public static final int SHAPE_RECT    = 'R';
-    public static final int SHAPE_DEFAULT = SHAPE_CIRCLE;
-    
-    private static IconFactory sInstance;
-
-    private HashMap<String, Image> mIconMap = new HashMap<String, Image>();
-    private HashMap<String, ImageDescriptor> mImageDescMap = new HashMap<String, ImageDescriptor>();
-    
-    private IconFactory() {
-    }
-    
-    public static synchronized IconFactory getInstance() {
-        if (sInstance == null) {
-            sInstance = new IconFactory();
-        }
-        return sInstance;
-    }
-    
-    public void Dispose() {
-        // Dispose icons
-        for (Image icon : mIconMap.values()) {
-            // The map can contain null values
-            if (icon != null) {
-                icon.dispose();
-            }
-        }
-        mIconMap.clear();
-    }
-
-    /**
-     * Returns an Image for a given icon name.
-     * <p/>
-     * Callers should not dispose it.
-     * 
-     * @param osName The leaf name, without the extension, of an existing icon in the
-     *        editor's "icons" directory. If it doesn't exists, a default icon will be
-     *        generated automatically based on the name.
-     */
-    public Image getIcon(String osName) {
-        return getIcon(osName, COLOR_DEFAULT, SHAPE_DEFAULT);
-    }
-
-    /**
-     * Returns an Image for a given icon name.
-     * <p/>
-     * Callers should not dispose it.
-     * 
-     * @param osName The leaf name, without the extension, of an existing icon in the
-     *        editor's "icons" directory. If it doesn't exists, a default icon will be
-     *        generated automatically based on the name.
-     * @param color The color of the text in the automatically generated icons,
-     *        one of COLOR_DEFAULT, COLOR_RED, COLOR_BLUE or COLOR_RED.
-     * @param shape The shape of the icon in the automatically generated icons,
-     *        one of SHAPE_DEFAULT, SHAPE_CIRCLE or SHAPE_RECT.
-     */
-    public Image getIcon(String osName, int color, int shape) {
-        String key = Character.toString((char) shape) + Integer.toString(color) + osName;
-        Image icon = mIconMap.get(key);
-        if (icon == null && !mIconMap.containsKey(key)) {
-            ImageDescriptor id = getImageDescriptor(osName, color, shape);
-            if (id != null) {
-                icon = id.createImage();
-            }
-            // Note that we store null references in the icon map, to avoid looking them
-            // up every time. If it didn't exist once, it will not exist later.
-            mIconMap.put(key, icon);
-        }
-        return icon;
-    }
-
-    /**
-     * Returns an ImageDescriptor for a given icon name.
-     * <p/>
-     * Callers should not dispose it.
-     * 
-     * @param osName The leaf name, without the extension, of an existing icon in the
-     *        editor's "icons" directory. If it doesn't exists, a default icon will be
-     *        generated automatically based on the name.
-     */
-    public ImageDescriptor getImageDescriptor(String osName) {
-        return getImageDescriptor(osName, COLOR_DEFAULT, SHAPE_DEFAULT);
-    }
-    
-    /**
-     * Returns an ImageDescriptor for a given icon name.
-     * <p/>
-     * Callers should not dispose it.
-     * 
-     * @param osName The leaf name, without the extension, of an existing icon in the
-     *        editor's "icons" directory. If it doesn't exists, a default icon will be
-     *        generated automatically based on the name.
-     * @param color The color of the text in the automatically generated icons.
-     *        one of COLOR_DEFAULT, COLOR_RED, COLOR_BLUE or COLOR_RED.
-     * @param shape The shape of the icon in the automatically generated icons,
-     *        one of SHAPE_DEFAULT, SHAPE_CIRCLE or SHAPE_RECT.
-     */
-    public ImageDescriptor getImageDescriptor(String osName, int color, int shape) {
-        String key = Character.toString((char) shape) + Integer.toString(color) + osName;
-        ImageDescriptor id = mImageDescMap.get(key);
-        if (id == null && !mImageDescMap.containsKey(key)) {
-            id = AdtPlugin.imageDescriptorFromPlugin(
-                    AdtPlugin.PLUGIN_ID,
-                    String.format("/icons/%1$s.png", osName)); //$NON-NLS-1$
-
-            if (id == null) {
-                id = new LetterImageDescriptor(osName.charAt(0), color, shape);
-            }
-            
-            // Note that we store null references in the icon map, to avoid looking them
-            // up every time. If it didn't exist once, it will not exist later.
-            mImageDescMap.put(key, id);
-        }
-        return id;
-    }
-
-    /**
-     * A simple image description that generates a 16x16 image which consists
-     * of a colored letter inside a black & white circle.
-     */
-    private static class LetterImageDescriptor extends ImageDescriptor {
-
-        private final char mLetter;
-        private final int mColor;
-        private final int mShape;
-
-        public LetterImageDescriptor(char letter, int color, int shape) {
-            mLetter = letter;
-            mColor = color;
-            mShape = shape;
-        }
-        
-        @Override
-        public ImageData getImageData() {
-            
-            final int SX = 15;
-            final int SY = 15;
-            final int RX = 4;
-            final int RY = 4;
-            
-            Display display = Display.getCurrent();
-            if (display == null) {
-                return null;
-            }
-
-            Image image = new Image(display, SX, SY);
-            
-            image.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
-            
-            GC gc = new GC(image);
-            gc.setAdvanced(true);
-            gc.setAntialias(SWT.ON);
-            gc.setTextAntialias(SWT.ON);
-
-            gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
-            if (mShape == SHAPE_CIRCLE) {
-                gc.fillOval(0, 0, SX - 1, SY - 1);
-            } else if (mShape == SHAPE_RECT) {
-                gc.fillRoundRectangle(0, 0, SX - 1, SY - 1, RX, RY);
-            }
-            
-            gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
-            gc.setLineWidth(1);
-            if (mShape == SHAPE_CIRCLE) {
-                gc.drawOval(0, 0, SX - 1, SY - 1);
-            } else if (mShape == SHAPE_RECT) {
-                gc.drawRoundRectangle(0, 0, SX - 1, SY - 1, RX, RY);
-            }
-
-            // Get a bold version of the default system font, if possible.
-            Font font = display.getSystemFont();
-            FontData[] fds = font.getFontData();
-            fds[0].setStyle(SWT.BOLD);
-            // use 3/4th of the circle diameter for the font size (in pixels)
-            // and convert it to "font points" (font points in SWT are hardcoded in an
-            // arbitrary 72 dpi and then converted in real pixels using whatever is
-            // indicated by getDPI -- at least that's how it works under Win32).
-            fds[0].setHeight((int) ((SY + 1) * 3./4. * 72./display.getDPI().y));
-            // Note: win32 implementation always uses fds[0] so we change just that one.
-            // getFontData indicates that the array of fd is really an unusual thing for X11.
-            font = new Font(display, fds);
-            gc.setFont(font);
-            gc.setForeground(display.getSystemColor(mColor));
-
-            // Text measurement varies so slightly depending on the platform
-            int ofx = 0;
-            int ofy = 0;
-            if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) {
-                ofx = +1;
-                ofy = -1;
-            }
-            
-            String s = Character.toString(mLetter).toUpperCase();
-            Point p = gc.textExtent(s);
-            int tx = (SX + ofx - p.x) / 2;
-            int ty = (SY + ofy - p.y) / 2;
-            gc.drawText(s, tx, ty, true /* isTransparent */);
-
-            font.dispose();
-            gc.dispose();
-            
-            ImageData data = image.getImageData();
-            image.dispose();
-            return data;
-        }
-        
-    }
-    
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java
deleted file mode 100644
index db8a2f1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.swt.graphics.Image;
-
-/**
- * {@link AttributeDescriptor} describes an XML attribute with its XML attribute name.
- * <p/>
- * An attribute descriptor also knows which UI node should be instantiated to represent
- * this particular attribute (e.g. text field, icon chooser, class selector, etc.)
- * Some attributes may be hidden and have no user interface at all.
- * <p/>
- * This is an abstract class. Derived classes must implement data description and return
- * the correct UiAttributeNode-derived class.
- */
-public abstract class AttributeDescriptor {
-    private String mXmlLocalName;
-    private ElementDescriptor mParent;
-    private final String mNsUri;
-    private boolean mDeprecated;
-    
-    /**
-     * Creates a new {@link AttributeDescriptor}
-     * 
-     * @param xmlLocalName The XML name of the attribute (case sensitive)
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     */
-    public AttributeDescriptor(String xmlLocalName, String nsUri) {
-        mXmlLocalName = xmlLocalName;
-        mNsUri = nsUri;
-    }
-
-    /**
-     * Returns the XML local name of the attribute (case sensitive)
-     */
-    public final String getXmlLocalName() {
-        return mXmlLocalName;
-    }
-    
-    public final String getNamespaceUri() {
-        return mNsUri;
-    }
-    
-    final void setParent(ElementDescriptor parent) {
-        mParent = parent;
-    }
-    
-    public final ElementDescriptor getParent() {
-        return mParent;
-    }
-
-    public void setDeprecated(boolean isDeprecated) {
-        mDeprecated = isDeprecated;
-    }
-    
-    public boolean isDeprecated() {
-        return mDeprecated;
-    }
-
-    /** 
-     * Returns an optional icon for the attribute.
-     * <p/>
-     * By default this tries to return an icon based on the XML name of the attribute.
-     * If this fails, it tries to return the default Android logo as defined in the
-     * plugin. If all fails, it returns null.
-     * 
-     * @return An icon for this element or null.
-     */
-    public Image getIcon() {
-        IconFactory factory = IconFactory.getInstance();
-        Image icon;
-        icon = factory.getIcon(getXmlLocalName(), IconFactory.COLOR_RED, IconFactory.SHAPE_CIRCLE);
-        return icon != null ? icon : AdtPlugin.getAndroidLogo();
-    }
-    
-    /**
-     * @param uiParent The {@link UiElementNode} parent of this UI attribute.
-     * @return A new {@link UiAttributeNode} linked to this descriptor or null if this
-     *         attribute has no user interface.
-     */
-    public abstract UiAttributeNode createUiNode(UiElementNode uiParent);
-}    
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptorLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptorLabelProvider.java
deleted file mode 100644
index da03441..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptorLabelProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAbstractTextAttributeNode;
-
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * Label provider for {@link UiAbstractTextAttributeNode}.
- */
-public class AttributeDescriptorLabelProvider implements ILabelProvider {
-    
-    private final static AttributeDescriptorLabelProvider sThis =
-        new AttributeDescriptorLabelProvider();
-    
-    public static ILabelProvider getProvider() {
-        return sThis;
-    }
-
-    public Image getImage(Object element) {
-        if (element instanceof UiAbstractTextAttributeNode) {
-            UiAbstractTextAttributeNode node = (UiAbstractTextAttributeNode) element;
-            if (node.getDescriptor().isDeprecated()) {
-                String v = node.getCurrentValue();
-                if (v != null && v.length() > 0) {
-                    IconFactory factory = IconFactory.getInstance();
-                    return factory.getIcon("warning"); //$NON-NLS-1$
-                }                
-            }
-        }
-
-        return null;
-    }
-
-    public String getText(Object element) {
-        if (element instanceof UiAbstractTextAttributeNode) {
-            return ((UiAbstractTextAttributeNode)element).getCurrentValue();
-        }
-
-        return null;
-    }
-
-    public void addListener(ILabelProviderListener listener) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void dispose() {
-        // TODO Auto-generated method stub
-
-    }
-
-    public boolean isLabelProperty(Object element, String property) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public void removeListener(ILabelProviderListener listener) {
-        // TODO Auto-generated method stub
-
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/BooleanAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/BooleanAttributeDescriptor.java
deleted file mode 100644
index 14dd432..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/BooleanAttributeDescriptor.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
-
-/**
- * Describes a text attribute that can only contain boolean values.
- * It is displayed by a {@link UiListAttributeNode}.
- */
-public class BooleanAttributeDescriptor extends ListAttributeDescriptor {
-
-    public BooleanAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip,
-                new String[] { "true", "false" } );
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtils.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtils.java
deleted file mode 100644
index f7c71b7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtils.java
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutConstants;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo.Format;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-/**
- * Utility methods related to descriptors handling.
- */
-public final class DescriptorsUtils {
-
-    private static final String DEFAULT_WIDGET_PREFIX = "widget";
-
-    private static final int JAVADOC_BREAK_LENGTH = 60;
-
-    /**
-     * The path in the online documentation for the manifest description.
-     * <p/>
-     * This is NOT a complete URL. To be used, it needs to be appended
-     * to {@link AndroidConstants#CODESITE_BASE_URL} or to the local SDK
-     * documentation.
-     */
-    public static final String MANIFEST_SDK_URL = "/reference/android/R.styleable.html#";  //$NON-NLS-1$
-
-    public static final String IMAGE_KEY = "image"; //$NON-NLS-1$
-
-    private static final String CODE  = "$code";  //$NON-NLS-1$
-    private static final String LINK  = "$link";  //$NON-NLS-1$
-    private static final String ELEM  = "$elem";  //$NON-NLS-1$
-    private static final String BREAK = "$break"; //$NON-NLS-1$
-
-    /**
-     * The {@link ITextAttributeCreator} interface is used by the appendAttribute() method
-     * to provide a way for caller to override the kind of {@link TextAttributeDescriptor}
-     * created for a give XML attribute name.
-     */
-    public interface ITextAttributeCreator {
-        /**
-         * Creates a new {@link TextAttributeDescriptor} instance for the given XML name,
-         * UI name and tooltip.
-         *
-         * @param xmlName The XML attribute name.
-         * @param uiName The UI attribute name.
-         * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-         *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-         * @param tooltip An optional tooltip.
-         * @return A new {@link TextAttributeDescriptor} (or derived) instance.
-         */
-        public TextAttributeDescriptor create(String xmlName, String uiName, String nsUri,
-                String tooltip);
-    }
-
-    /**
-     * Add all {@link AttributeInfo} to the the array of {@link AttributeDescriptor}.
-     *
-     * @param attributes The list of {@link AttributeDescriptor} to append to
-     * @param elementXmlName Optional XML local name of the element to which attributes are
-     *              being added. When not null, this is used to filter overrides.
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param infos The array of {@link AttributeInfo} to read and append to attributes
-     * @param requiredAttributes An optional set of attributes to mark as "required" (i.e. append
-     *        a "*" to their UI name as a hint for the user.) If not null, must contains
-     *        entries in the form "elem-name/attr-name". Elem-name can be "*".
-     * @param overrides A map [attribute name => TextAttributeDescriptor creator]. A creator
-     *        can either by a Class<? extends TextAttributeDescriptor> or an instance of
-     *        {@link ITextAttributeCreator} that instantiates the right TextAttributeDescriptor.
-     */
-    public static void appendAttributes(ArrayList<AttributeDescriptor> attributes,
-            String elementXmlName,
-            String nsUri, AttributeInfo[] infos,
-            Set<String> requiredAttributes,
-            Map<String, Object> overrides) {
-        for (AttributeInfo info : infos) {
-            boolean required = false;
-            if (requiredAttributes != null) {
-                String attr_name = info.getName();
-                if (requiredAttributes.contains("*/" + attr_name) ||
-                        requiredAttributes.contains(elementXmlName + "/" + attr_name)) {
-                    required = true;
-                }
-            }
-            appendAttribute(attributes, elementXmlName, nsUri, info, required, overrides);
-        }
-    }
-
-    /**
-     * Add an {@link AttributeInfo} to the the array of {@link AttributeDescriptor}.
-     *
-     * @param attributes The list of {@link AttributeDescriptor} to append to
-     * @param elementXmlName Optional XML local name of the element to which attributes are
-     *              being added. When not null, this is used to filter overrides.
-     * @param info The {@link AttributeInfo} to append to attributes
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param required True if the attribute is to be marked as "required" (i.e. append
-     *        a "*" to its UI name as a hint for the user.)
-     * @param overrides A map [attribute name => TextAttributeDescriptor creator]. A creator
-     *        can either by a Class<? extends TextAttributeDescriptor> or an instance of
-     *        {@link ITextAttributeCreator} that instantiates the right TextAttributeDescriptor.
-     */
-    public static void appendAttribute(ArrayList<AttributeDescriptor> attributes,
-            String elementXmlName,
-            String nsUri,
-            AttributeInfo info, boolean required,
-            Map<String, Object> overrides) {
-        AttributeDescriptor attr = null;
-
-        String xmlLocalName = info.getName();
-        String uiName = prettyAttributeUiName(info.getName()); // ui_name
-        if (required) {
-            uiName += "*"; //$NON-NLS-1$
-        }
-
-        String tooltip = null;
-        String rawTooltip = info.getJavaDoc();
-        if (rawTooltip == null) {
-            rawTooltip = "";
-        }
-
-        String deprecated = info.getDeprecatedDoc();
-        if (deprecated != null) {
-            if (rawTooltip.length() > 0) {
-                rawTooltip += "@@"; //$NON-NLS-1$ insert a break
-            }
-            rawTooltip += "* Deprecated";
-            if (deprecated.length() != 0) {
-                rawTooltip += ": " + deprecated;                            //$NON-NLS-1$
-            }
-            if (deprecated.length() == 0 || !deprecated.endsWith(".")) {    //$NON-NLS-1$
-                rawTooltip += ".";                                          //$NON-NLS-1$
-            }
-        }
-
-        // Add the known types to the tooltip
-        Format[] formats_list = info.getFormats();
-        int flen = formats_list.length;
-        if (flen > 0) {
-            // Fill the formats in a set for faster access
-            HashSet<Format> formats_set = new HashSet<Format>();
-
-            StringBuilder sb = new StringBuilder();
-            if (rawTooltip != null && rawTooltip.length() > 0) {
-                sb.append(rawTooltip);
-                sb.append(" ");     //$NON-NLS-1$
-            }
-            if (sb.length() > 0) {
-                sb.append("@@");    //$NON-NLS-1$  @@ inserts a break before the types
-            }
-            sb.append("[");         //$NON-NLS-1$
-            for (int i = 0; i < flen; i++) {
-                Format f = formats_list[i];
-                formats_set.add(f);
-
-                sb.append(f.toString().toLowerCase());
-                if (i < flen - 1) {
-                    sb.append(", "); //$NON-NLS-1$
-                }
-            }
-            // The extra space at the end makes the tooltip more readable on Windows.
-            sb.append("]"); //$NON-NLS-1$
-
-            if (required) {
-                sb.append(".@@* ");          //$NON-NLS-1$ @@ inserts a break.
-                sb.append("Required.");
-            }
-
-            // The extra space at the end makes the tooltip more readable on Windows.
-            sb.append(" "); //$NON-NLS-1$
-
-            rawTooltip = sb.toString();
-            tooltip = formatTooltip(rawTooltip);
-
-            // Create a specialized attribute if we can
-            if (overrides != null) {
-                for (Entry<String, Object> entry: overrides.entrySet()) {
-                    String key = entry.getKey();
-                    String elements[] = key.split("/");          //$NON-NLS-1$
-                    String overrideAttrLocalName = null;
-                    if (elements.length < 1) {
-                        continue;
-                    } else if (elements.length == 1) {
-                        overrideAttrLocalName = elements[0];
-                        elements = null;
-                    } else {
-                        overrideAttrLocalName = elements[elements.length - 1];
-                        elements = elements[0].split(",");       //$NON-NLS-1$
-                    }
-
-                    if (overrideAttrLocalName == null ||
-                            !overrideAttrLocalName.equals(xmlLocalName)) {
-                        continue;
-                    }
-
-                    boolean ok_element = elements.length < 1;
-                    if (!ok_element) {
-                        for (String element : elements) {
-                            if (element.equals("*")              //$NON-NLS-1$
-                                    || element.equals(elementXmlName)) {
-                                ok_element = true;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (!ok_element) {
-                        continue;
-                    }
-
-                    Object override = entry.getValue();
-                    if (override instanceof Class) {
-                        try {
-                            // The override is instance of the class to create, which must
-                            // have a constructor compatible with TextAttributeDescriptor.
-                            @SuppressWarnings("unchecked") //$NON-NLS-1$
-                            Class<? extends TextAttributeDescriptor> clazz =
-                                (Class<? extends TextAttributeDescriptor>) override;
-                            Constructor<? extends TextAttributeDescriptor> cons;
-                                cons = clazz.getConstructor(new Class<?>[] {
-                                        String.class, String.class, String.class, String.class } );
-                            attr = cons.newInstance(
-                                    new Object[] { xmlLocalName, uiName, nsUri, tooltip });
-                        } catch (SecurityException e) {
-                            // ignore
-                        } catch (NoSuchMethodException e) {
-                            // ignore
-                        } catch (IllegalArgumentException e) {
-                            // ignore
-                        } catch (InstantiationException e) {
-                            // ignore
-                        } catch (IllegalAccessException e) {
-                            // ignore
-                        } catch (InvocationTargetException e) {
-                            // ignore
-                        }
-                    } else if (override instanceof ITextAttributeCreator) {
-                        attr = ((ITextAttributeCreator) override).create(
-                                xmlLocalName, uiName, nsUri, tooltip);
-                    }
-                }
-            } // if overrides
-
-            // Create a specialized descriptor if we can, based on type
-            if (attr == null) {
-                if (formats_set.contains(Format.REFERENCE)) {
-                    // This is either a multi-type reference or a generic reference.
-                    attr = new ReferenceAttributeDescriptor(xmlLocalName, uiName, nsUri, tooltip);
-                } else if (formats_set.contains(Format.ENUM)) {
-                    attr = new ListAttributeDescriptor(xmlLocalName, uiName, nsUri, tooltip,
-                            info.getEnumValues());
-                } else if (formats_set.contains(Format.FLAG)) {
-                    attr = new FlagAttributeDescriptor(xmlLocalName, uiName, nsUri, tooltip,
-                            info.getFlagValues());
-                } else if (formats_set.contains(Format.BOOLEAN)) {
-                    attr = new BooleanAttributeDescriptor(xmlLocalName, uiName, nsUri, tooltip);
-                } else if (formats_set.contains(Format.STRING)) {
-                    attr = new ReferenceAttributeDescriptor(ResourceType.STRING,
-                            xmlLocalName, uiName, nsUri,
-                            tooltip);
-                }
-            }
-        }
-
-        // By default a simple text field is used
-        if (attr == null) {
-            if (tooltip == null) {
-                tooltip = formatTooltip(rawTooltip);
-            }
-            attr = new TextAttributeDescriptor(xmlLocalName, uiName, nsUri, tooltip);
-        }
-        attr.setDeprecated(info.getDeprecatedDoc() != null);
-        attributes.add(attr);
-    }
-
-    /**
-     * Indicates the the given {@link AttributeInfo} already exists in the ArrayList of
-     * {@link AttributeDescriptor}. This test for the presence of a descriptor with the same
-     * XML name.
-     *
-     * @param attributes The list of {@link AttributeDescriptor} to compare to.
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param info The {@link AttributeInfo} to know whether it is included in the above list.
-     * @return True if this {@link AttributeInfo} is already present in
-     *         the {@link AttributeDescriptor} list.
-     */
-    public static boolean containsAttribute(ArrayList<AttributeDescriptor> attributes,
-            String nsUri,
-            AttributeInfo info) {
-        String xmlLocalName = info.getName();
-        for (AttributeDescriptor desc : attributes) {
-            if (desc.getXmlLocalName().equals(xmlLocalName)) {
-                if (nsUri == desc.getNamespaceUri() ||
-                        (nsUri != null && nsUri.equals(desc.getNamespaceUri()))) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Create a pretty attribute UI name from an XML name.
-     * <p/>
-     * The original xml name starts with a lower case and is camel-case,
-     * e.g. "maxWidthForView". The pretty name starts with an upper case
-     * and has space separators, e.g. "Max width for view".
-     */
-    public static String prettyAttributeUiName(String name) {
-        if (name.length() < 1) {
-            return name;
-        }
-        StringBuffer buf = new StringBuffer();
-
-        char c = name.charAt(0);
-        // Use upper case initial letter
-        buf.append((char)(c >= 'a' && c <= 'z' ? c + 'A' - 'a' : c));
-        int len = name.length();
-        for (int i = 1; i < len; i++) {
-            c = name.charAt(i);
-            if (c >= 'A' && c <= 'Z') {
-                // Break camel case into separate words
-                buf.append(' ');
-                // Use a lower case initial letter for the next word, except if the
-                // word is solely X, Y or Z.
-                if (c >= 'X' && c <= 'Z' &&
-                        (i == len-1 ||
-                            (i < len-1 && name.charAt(i+1) >= 'A' && name.charAt(i+1) <= 'Z'))) {
-                    buf.append(c);
-                } else {
-                    buf.append((char)(c - 'A' + 'a'));
-                }
-            } else if (c == '_') {
-                buf.append(' ');
-            } else {
-                buf.append(c);
-            }
-        }
-
-        name = buf.toString();
-
-        // Replace these acronyms by upper-case versions
-        // - (?<=^| ) means "if preceded by a space or beginning of string"
-        // - (?=$| )  means "if followed by a space or end of string"
-        name = name.replaceAll("(?<=^| )sdk(?=$| )", "SDK");
-        name = name.replaceAll("(?<=^| )uri(?=$| )", "URI");
-
-        return name;
-    }
-
-    /**
-     * Capitalizes the string, i.e. transforms the initial [a-z] into [A-Z].
-     * Returns the string unmodified if the first character is not [a-z].
-     *
-     * @param str The string to capitalize.
-     * @return The capitalized string
-     */
-    public static String capitalize(String str) {
-        if (str == null || str.length() < 1 || str.charAt(0) < 'a' || str.charAt(0) > 'z') {
-            return str;
-        }
-
-        StringBuilder sb = new StringBuilder();
-        sb.append((char)(str.charAt(0) + 'A' - 'a'));
-        sb.append(str.substring(1));
-        return sb.toString();
-    }
-
-    /**
-     * Formats the javadoc tooltip to be usable in a tooltip.
-     */
-    public static String formatTooltip(String javadoc) {
-        ArrayList<String> spans = scanJavadoc(javadoc);
-
-        StringBuilder sb = new StringBuilder();
-        boolean needBreak = false;
-
-        for (int n = spans.size(), i = 0; i < n; ++i) {
-            String s = spans.get(i);
-            if (CODE.equals(s)) {
-                s = spans.get(++i);
-                if (s != null) {
-                    sb.append('"').append(s).append('"');
-                }
-            } else if (LINK.equals(s)) {
-                String base   = spans.get(++i);
-                String anchor = spans.get(++i);
-                String text   = spans.get(++i);
-
-                if (base != null) {
-                    base = base.trim();
-                }
-                if (anchor != null) {
-                    anchor = anchor.trim();
-                }
-                if (text != null) {
-                    text = text.trim();
-                }
-
-                // If there's no text, use the anchor if there's one
-                if (text == null || text.length() == 0) {
-                    text = anchor;
-                }
-
-                if (base != null && base.length() > 0) {
-                    if (text == null || text.length() == 0) {
-                        // If we still have no text, use the base as text
-                        text = base;
-                    }
-                }
-
-                if (text != null) {
-                    sb.append(text);
-                }
-
-            } else if (ELEM.equals(s)) {
-                s = spans.get(++i);
-                if (s != null) {
-                    sb.append(s);
-                }
-            } else if (BREAK.equals(s)) {
-                needBreak = true;
-            } else if (s != null) {
-                if (needBreak && s.trim().length() > 0) {
-                    sb.append('\r');
-                }
-                sb.append(s);
-                needBreak = false;
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Formats the javadoc tooltip to be usable in a FormText.
-     * <p/>
-     * If the descriptor can provide an icon, the caller should provide
-     * elementsDescriptor.getIcon() as "image" to FormText, e.g.:
-     * <code>formText.setImage(IMAGE_KEY, elementsDescriptor.getIcon());</code>
-     *
-     * @param javadoc The javadoc to format. Cannot be null.
-     * @param elementDescriptor The element descriptor parent of the javadoc. Cannot be null.
-     * @param androidDocBaseUrl The base URL for the documentation. Cannot be null. Should be
-     *   <code>FrameworkResourceManager.getInstance().getDocumentationBaseUrl()</code>
-     */
-    public static String formatFormText(String javadoc,
-            ElementDescriptor elementDescriptor,
-            String androidDocBaseUrl) {
-        ArrayList<String> spans = scanJavadoc(javadoc);
-
-        String fullSdkUrl = androidDocBaseUrl + MANIFEST_SDK_URL;
-        String sdkUrl = elementDescriptor.getSdkUrl();
-        if (sdkUrl != null && sdkUrl.startsWith(MANIFEST_SDK_URL)) {
-            fullSdkUrl = androidDocBaseUrl + sdkUrl;
-        }
-
-        StringBuilder sb = new StringBuilder();
-
-        Image icon = elementDescriptor.getIcon();
-        if (icon != null) {
-            sb.append("<form><li style=\"image\" value=\"" +        //$NON-NLS-1$
-                    IMAGE_KEY + "\">");                             //$NON-NLS-1$
-        } else {
-            sb.append("<form><p>");                                 //$NON-NLS-1$
-        }
-
-        for (int n = spans.size(), i = 0; i < n; ++i) {
-            String s = spans.get(i);
-            if (CODE.equals(s)) {
-                s = spans.get(++i);
-                if (elementDescriptor.getXmlName().equals(s) && fullSdkUrl != null) {
-                    sb.append("<a href=\"");                        //$NON-NLS-1$
-                    sb.append(fullSdkUrl);
-                    sb.append("\">");                               //$NON-NLS-1$
-                    sb.append(s);
-                    sb.append("</a>");                              //$NON-NLS-1$
-                } else if (s != null) {
-                    sb.append('"').append(s).append('"');
-                }
-            } else if (LINK.equals(s)) {
-                String base   = spans.get(++i);
-                String anchor = spans.get(++i);
-                String text   = spans.get(++i);
-
-                if (base != null) {
-                    base = base.trim();
-                }
-                if (anchor != null) {
-                    anchor = anchor.trim();
-                }
-                if (text != null) {
-                    text = text.trim();
-                }
-
-                // If there's no text, use the anchor if there's one
-                if (text == null || text.length() == 0) {
-                    text = anchor;
-                }
-
-                // TODO specialize with a base URL for views, menus & other resources
-                // Base is empty for a local page anchor, in which case we'll replace it
-                // by the element SDK URL if it exists.
-                if ((base == null || base.length() == 0) && fullSdkUrl != null) {
-                    base = fullSdkUrl;
-                }
-
-                String url = null;
-                if (base != null && base.length() > 0) {
-                    if (base.startsWith("http")) {                  //$NON-NLS-1$
-                        // If base looks an URL, use it, with the optional anchor
-                        url = base;
-                        if (anchor != null && anchor.length() > 0) {
-                            // If the base URL already has an anchor, it needs to be
-                            // removed first. If there's no anchor, we need to add "#"
-                            int pos = url.lastIndexOf('#');
-                            if (pos < 0) {
-                                url += "#";                         //$NON-NLS-1$
-                            } else if (pos < url.length() - 1) {
-                                url = url.substring(0, pos + 1);
-                            }
-
-                            url += anchor;
-                        }
-                    } else if (text == null || text.length() == 0) {
-                        // If we still have no text, use the base as text
-                        text = base;
-                    }
-                }
-
-                if (url != null && text != null) {
-                    sb.append("<a href=\"");                        //$NON-NLS-1$
-                    sb.append(url);
-                    sb.append("\">");                               //$NON-NLS-1$
-                    sb.append(text);
-                    sb.append("</a>");                              //$NON-NLS-1$
-                } else if (text != null) {
-                    sb.append("<b>").append(text).append("</b>");   //$NON-NLS-1$ //$NON-NLS-2$
-                }
-
-            } else if (ELEM.equals(s)) {
-                s = spans.get(++i);
-                if (sdkUrl != null && s != null) {
-                    sb.append("<a href=\"");                        //$NON-NLS-1$
-                    sb.append(sdkUrl);
-                    sb.append("\">");                               //$NON-NLS-1$
-                    sb.append(s);
-                    sb.append("</a>");                              //$NON-NLS-1$
-                } else if (s != null) {
-                    sb.append("<b>").append(s).append("</b>");      //$NON-NLS-1$ //$NON-NLS-2$
-                }
-            } else if (BREAK.equals(s)) {
-                // ignore line breaks in pseudo-HTML rendering
-            } else if (s != null) {
-                sb.append(s);
-            }
-        }
-
-        if (icon != null) {
-            sb.append("</li></form>");                              //$NON-NLS-1$
-        } else {
-            sb.append("</p></form>");                               //$NON-NLS-1$
-        }
-        return sb.toString();
-    }
-
-    private static ArrayList<String> scanJavadoc(String javadoc) {
-        ArrayList<String> spans = new ArrayList<String>();
-
-        // Standardize all whitespace in the javadoc to single spaces.
-        if (javadoc != null) {
-            javadoc = javadoc.replaceAll("[ \t\f\r\n]+", " "); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        // Detects {@link <base>#<name> <text>} where all 3 are optional
-        Pattern p_link = Pattern.compile("\\{@link\\s+([^#\\}\\s]*)(?:#([^\\s\\}]*))?(?:\\s*([^\\}]*))?\\}(.*)"); //$NON-NLS-1$
-        // Detects <code>blah</code>
-        Pattern p_code = Pattern.compile("<code>(.+?)</code>(.*)");                 //$NON-NLS-1$
-        // Detects @blah@, used in hard-coded tooltip descriptors
-        Pattern p_elem = Pattern.compile("@([\\w -]+)@(.*)");                       //$NON-NLS-1$
-        // Detects a buffer that starts by @@ (request for a break)
-        Pattern p_break = Pattern.compile("@@(.*)");                                //$NON-NLS-1$
-        // Detects a buffer that starts by @ < or { (one that was not matched above)
-        Pattern p_open = Pattern.compile("([@<\\{])(.*)");                          //$NON-NLS-1$
-        // Detects everything till the next potential separator, i.e. @ < or {
-        Pattern p_text = Pattern.compile("([^@<\\{]+)(.*)");                        //$NON-NLS-1$
-
-        int currentLength = 0;
-        String text = null;
-
-        while(javadoc != null && javadoc.length() > 0) {
-            Matcher m;
-            String s = null;
-            if ((m = p_code.matcher(javadoc)).matches()) {
-                spans.add(CODE);
-                spans.add(text = cleanupJavadocHtml(m.group(1))); // <code> text
-                javadoc = m.group(2);
-                if (text != null) {
-                    currentLength += text.length();
-                }
-            } else if ((m = p_link.matcher(javadoc)).matches()) {
-                spans.add(LINK);
-                spans.add(m.group(1)); // @link base
-                spans.add(m.group(2)); // @link anchor
-                spans.add(text = cleanupJavadocHtml(m.group(3))); // @link text
-                javadoc = m.group(4);
-                if (text != null) {
-                    currentLength += text.length();
-                }
-            } else if ((m = p_elem.matcher(javadoc)).matches()) {
-                spans.add(ELEM);
-                spans.add(text = cleanupJavadocHtml(m.group(1))); // @text@
-                javadoc = m.group(2);
-                if (text != null) {
-                    currentLength += text.length() - 2;
-                }
-            } else if ((m = p_break.matcher(javadoc)).matches()) {
-                spans.add(BREAK);
-                currentLength = 0;
-                javadoc = m.group(1);
-            } else if ((m = p_open.matcher(javadoc)).matches()) {
-                s = m.group(1);
-                javadoc = m.group(2);
-            } else if ((m = p_text.matcher(javadoc)).matches()) {
-                s = m.group(1);
-                javadoc = m.group(2);
-            } else {
-                // This is not supposed to happen. In case of, just use everything.
-                s = javadoc;
-                javadoc = null;
-            }
-            if (s != null && s.length() > 0) {
-                s = cleanupJavadocHtml(s);
-
-                if (currentLength >= JAVADOC_BREAK_LENGTH) {
-                    spans.add(BREAK);
-                    currentLength = 0;
-                }
-                while (currentLength + s.length() > JAVADOC_BREAK_LENGTH) {
-                    int pos = s.indexOf(' ', JAVADOC_BREAK_LENGTH - currentLength);
-                    if (pos <= 0) {
-                        break;
-                    }
-                    spans.add(s.substring(0, pos + 1));
-                    spans.add(BREAK);
-                    currentLength = 0;
-                    s = s.substring(pos + 1);
-                }
-
-                spans.add(s);
-                currentLength += s.length();
-            }
-        }
-
-        return spans;
-    }
-
-    /**
-     * Remove anything that looks like HTML from a javadoc snippet, as it is supported
-     * neither by FormText nor a standard text tooltip.
-     */
-    private static String cleanupJavadocHtml(String s) {
-        if (s != null) {
-            s = s.replaceAll("&lt;", "\"");     //$NON-NLS-1$ $NON-NLS-2$
-            s = s.replaceAll("&gt;", "\"");     //$NON-NLS-1$ $NON-NLS-2$
-            s = s.replaceAll("<[^>]+>", "");    //$NON-NLS-1$ $NON-NLS-2$
-        }
-        return s;
-    }
-
-    /**
-     * Sets the default layout attributes for the a new UiElementNode.
-     * <p/>
-     * Note that ideally the node should already be part of a hierarchy so that its
-     * parent layout and previous sibling can be determined, if any.
-     * <p/>
-     * This does not override attributes which are not empty.
-     */
-    public static void setDefaultLayoutAttributes(UiElementNode ui_node, boolean updateLayout) {
-        // if this ui_node is a layout and we're adding it to a document, use fill_parent for
-        // both W/H. Otherwise default to wrap_layout.
-        boolean fill = ui_node.getDescriptor().hasChildren() &&
-                       ui_node.getUiParent() instanceof UiDocumentNode;
-        ui_node.setAttributeValue(LayoutConstants.ATTR_LAYOUT_WIDTH,
-                fill ? LayoutConstants.VALUE_FILL_PARENT : LayoutConstants.VALUE_WRAP_CONTENT,
-                false /* override */);
-        ui_node.setAttributeValue(LayoutConstants.ATTR_LAYOUT_HEIGHT,
-                fill ? LayoutConstants.VALUE_FILL_PARENT : LayoutConstants.VALUE_WRAP_CONTENT,
-                false /* override */);
-
-        String widget_id = getFreeWidgetId(ui_node);
-        if (widget_id != null) {
-            ui_node.setAttributeValue(LayoutConstants.ATTR_ID, widget_id, false /* override */);
-        }
-
-        ui_node.setAttributeValue(LayoutConstants.ATTR_TEXT, widget_id, false /*override*/);
-
-        if (updateLayout) {
-            UiElementNode ui_parent = ui_node.getUiParent();
-            if (ui_parent != null &&
-                    ui_parent.getDescriptor().getXmlLocalName().equals(
-                            LayoutConstants.RELATIVE_LAYOUT)) {
-                UiElementNode ui_previous = ui_node.getUiPreviousSibling();
-                if (ui_previous != null) {
-                    String id = ui_previous.getAttributeValue(LayoutConstants.ATTR_ID);
-                    if (id != null && id.length() > 0) {
-                        id = id.replace("@+", "@");                     //$NON-NLS-1$ //$NON-NLS-2$
-                        ui_node.setAttributeValue(LayoutConstants.ATTR_LAYOUT_BELOW, id,
-                                false /* override */);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Given a UI root node, returns the first available id that matches the
-     * pattern "prefix%02d".
-     * <p/>TabWidget is a special case and the method will always return "@android:id/tabs".
-     *
-     * @param uiNode The UI node that gives the prefix to match.
-     * @return A suitable generated id in the attribute form needed by the XML id tag
-     * (e.g. "@+id/something")
-     */
-    public static String getFreeWidgetId(UiElementNode uiNode) {
-        String name = uiNode.getDescriptor().getXmlLocalName();
-        if ("TabWidget".equals(name)) {                        //$NON-NLS-1$
-            return "@android:id/tabs";                         //$NON-NLS-1$
-        }
-
-        return "@+id/" + getFreeWidgetId(uiNode.getUiRoot(),   //$NON-NLS-1$
-                new Object[] { name, null, null, null });
-    }
-
-    /**
-     * Given a UI root node, returns the first available id that matches the
-     * pattern "prefix%02d".
-     *
-     * For recursion purposes, a "context" is given. Since Java doesn't have in-out parameters
-     * in methods and we're not going to do a dedicated type, we just use an object array which
-     * must contain one initial item and several are built on the fly just for internal storage:
-     * <ul>
-     * <li> prefix(String): The prefix of the generated id, i.e. "widget". Cannot be null.
-     * <li> index(Integer): The minimum index of the generated id. Must start with null.
-     * <li> generated(String): The generated widget currently being searched. Must start with null.
-     * <li> map(Set<String>): A set of the ids collected so far when walking through the widget
-     *                        hierarchy. Must start with null.
-     * </ul>
-     *
-     * @param uiRoot The Ui root node where to start searching recursively. For the initial call
-     *               you want to pass the document root.
-     * @param params An in-out context of parameters used during recursion, as explained above.
-     * @return A suitable generated id
-     */
-    @SuppressWarnings("unchecked")
-    private static String getFreeWidgetId(UiElementNode uiRoot,
-            Object[] params) {
-
-        Set<String> map = (Set<String>)params[3];
-        if (map == null) {
-            params[3] = map = new HashSet<String>();
-        }
-
-        int num = params[1] == null ? 0 : ((Integer)params[1]).intValue();
-
-        String generated = (String) params[2];
-        String prefix = (String) params[0];
-        if (generated == null) {
-            int pos = prefix.indexOf('.');
-            if (pos >= 0) {
-                prefix = prefix.substring(pos + 1);
-            }
-            pos = prefix.indexOf('$');
-            if (pos >= 0) {
-                prefix = prefix.substring(pos + 1);
-            }
-            prefix = prefix.replaceAll("[^a-zA-Z]", "");                //$NON-NLS-1$ $NON-NLS-2$
-            if (prefix.length() == 0) {
-                prefix = DEFAULT_WIDGET_PREFIX;
-            }
-
-            do {
-                num++;
-                generated = String.format("%1$s%2$02d", prefix, num);   //$NON-NLS-1$
-            } while (map.contains(generated));
-
-            params[0] = prefix;
-            params[1] = num;
-            params[2] = generated;
-        }
-
-        String id = uiRoot.getAttributeValue(LayoutConstants.ATTR_ID);
-        if (id != null) {
-            id = id.replace("@+id/", "");                               //$NON-NLS-1$ $NON-NLS-2$
-            id = id.replace("@id/", "");                                //$NON-NLS-1$ $NON-NLS-2$
-            if (map.add(id) && map.contains(generated)) {
-
-                do {
-                    num++;
-                    generated = String.format("%1$s%2$02d", prefix, num);   //$NON-NLS-1$
-                } while (map.contains(generated));
-
-                params[1] = num;
-                params[2] = generated;
-            }
-        }
-
-        for (UiElementNode uiChild : uiRoot.getUiChildren()) {
-            getFreeWidgetId(uiChild, params);
-        }
-
-        // Note: return params[2] (not "generated") since it could have changed during recursion.
-        return (String) params[2];
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DocumentDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DocumentDescriptor.java
deleted file mode 100644
index 1509d94..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DocumentDescriptor.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * {@link DocumentDescriptor} describes the properties expected for an XML document node.
- * 
- * Compared to ElementDescriptor, {@link DocumentDescriptor} does not have XML name nor UI name,
- * tooltip, SDK url and attributes list.
- * <p/>
- * It has a children list which represent all the possible roots of the document.
- * <p/>
- * The document nodes are "mandatory", meaning the UI node is never deleted and it may lack
- * an actual XML node attached.
- */
-public class DocumentDescriptor extends ElementDescriptor {
-
-    /**
-     * Constructs a new {@link DocumentDescriptor} based on its XML name and children list.
-     * The UI name is build by capitalizing the XML name.
-     * The UI nodes will be non-mandatory.
-     * <p/>
-     * The XML name is never shown in the UI directly. It is however used when an icon
-     * needs to be found for the node.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param children The list of allowed children. Can be null or empty.
-     */
-    public DocumentDescriptor(String xml_name, ElementDescriptor[] children) {
-        super(xml_name, children, true /* mandatory */);
-    }
-
-    /**
-     * @return A new {@link UiElementNode} linked to this descriptor.
-     */
-    @Override
-    public UiElementNode createUiNode() {
-        return new UiDocumentNode(this);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ElementDescriptor.java
deleted file mode 100644
index 9135241..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ElementDescriptor.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * {@link ElementDescriptor} describes the properties expected for a given XML element node.
- * 
- * {@link ElementDescriptor} have an XML name, UI name, a tooltip, an SDK url,
- * an attributes list and a children list.
- * 
- * An UI node can be "mandatory", meaning the UI node is never deleted and it may lack
- * an actual XML node attached. A non-mandatory UI node MUST have an XML node attached
- * and it will cease to exist when the XML node ceases to exist.
- */
-public class ElementDescriptor {
-    /** The XML element node name. Case sensitive. */
-    private String mXmlName;
-    /** The XML element name for the user interface, typically capitalized. */
-    private String mUiName;
-    /** The list of allowed attributes. */
-    private AttributeDescriptor[] mAttributes;
-    /** The list of allowed children */
-    private ElementDescriptor[] mChildren;
-    /* An optional tooltip. Can be empty. */
-    private String mTooltip;
-    /** An optional SKD URL. Can be empty. */
-    private String mSdkUrl;
-    /** Whether this UI node must always exist (even for empty models). */
-    private boolean mMandatory;
-
-    /**
-     * Constructs a new {@link ElementDescriptor} based on its XML name, UI name,
-     * tooltip, SDK url, attributes list, children list and mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param ui_name The XML element name for the user interface, typically capitalized.
-     * @param tooltip An optional tooltip. Can be null or empty.
-     * @param sdk_url An optional SKD URL. Can be null or empty.
-     * @param attributes The list of allowed attributes. Can be null or empty.
-     * @param children The list of allowed children. Can be null or empty.
-     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
-     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
-     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
-     *  ceases to exist.
-     */
-    public ElementDescriptor(String xml_name, String ui_name, String tooltip, String sdk_url,
-            AttributeDescriptor[] attributes,
-            ElementDescriptor[] children,
-            boolean mandatory) {
-        mMandatory = mandatory;
-        mXmlName = xml_name;
-        mUiName = ui_name;
-        mTooltip = (tooltip != null && tooltip.length() > 0) ? tooltip : null;
-        mSdkUrl = (sdk_url != null && sdk_url.length() > 0) ? sdk_url : null;
-        setAttributes(attributes != null ? attributes : new AttributeDescriptor[]{});
-        mChildren = children != null ? children : new ElementDescriptor[]{};
-    }
-
-    /**
-     * Constructs a new {@link ElementDescriptor} based on its XML name and children list.
-     * The UI name is build by capitalizing the XML name.
-     * The UI nodes will be non-mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param children The list of allowed children. Can be null or empty.
-     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
-     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
-     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
-     *  ceases to exist.
-     */
-    public ElementDescriptor(String xml_name, ElementDescriptor[] children, boolean mandatory) {
-        this(xml_name, prettyName(xml_name), null, null, null, children, mandatory);
-    }
-
-    /**
-     * Constructs a new {@link ElementDescriptor} based on its XML name and children list.
-     * The UI name is build by capitalizing the XML name.
-     * The UI nodes will be non-mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param children The list of allowed children. Can be null or empty.
-     */
-    public ElementDescriptor(String xml_name, ElementDescriptor[] children) {
-        this(xml_name, prettyName(xml_name), null, null, null, children, false);
-    }
-
-    /**
-     * Constructs a new {@link ElementDescriptor} based on its XML name.
-     * The UI name is build by capitalizing the XML name.
-     * The UI nodes will be non-mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     */
-    public ElementDescriptor(String xml_name) {
-        this(xml_name, prettyName(xml_name), null, null, null, null, false);
-    }
-
-    /** Returns whether this node must always exist (even for empty models) */
-    public boolean isMandatory() {
-        return mMandatory;
-    }
-    
-    /**
-     * Returns the XML element node local name (case sensitive)
-     */
-    public final String getXmlLocalName() {
-        int pos = mXmlName.indexOf(':'); 
-        if (pos != -1) {
-            return mXmlName.substring(pos+1);
-        }
-        return mXmlName;
-    }
-
-    /** Returns the XML element node name. Case sensitive. */
-    public String getXmlName() {
-        return mXmlName;
-    }
-    
-    /**
-     * Returns the namespace of the attribute.
-     */
-    public final String getNamespace() {
-        // For now we hard-code the prefix as being "android"
-        if (mXmlName.startsWith("android:")) { //$NON-NLs-1$
-            return SdkConstants.NS_RESOURCES;
-        }
-        
-        return ""; //$NON-NLs-1$
-    }
-
-
-    /** Returns the XML element name for the user interface, typically capitalized. */
-    public String getUiName() {
-        return mUiName;
-    }
-
-    /** 
-     * Returns an optional icon for the element.
-     * <p/>
-     * By default this tries to return an icon based on the XML name of the element.
-     * If this fails, it tries to return the default Android logo as defined in the
-     * plugin. If all fails, it returns null.
-     * 
-     * @return An icon for this element or null.
-     */
-    public Image getIcon() {
-        IconFactory factory = IconFactory.getInstance();
-        int color = hasChildren() ? IconFactory.COLOR_BLUE : IconFactory.COLOR_GREEN;
-        int shape = hasChildren() ? IconFactory.SHAPE_RECT : IconFactory.SHAPE_CIRCLE;
-        Image icon = factory.getIcon(mXmlName, color, shape);
-        return icon != null ? icon : AdtPlugin.getAndroidLogo();
-    }
-
-    /** 
-     * Returns an optional ImageDescriptor for the element.
-     * <p/>
-     * By default this tries to return an image based on the XML name of the element.
-     * If this fails, it tries to return the default Android logo as defined in the
-     * plugin. If all fails, it returns null.
-     * 
-     * @return An ImageDescriptor for this element or null.
-     */
-    public ImageDescriptor getImageDescriptor() {
-        IconFactory factory = IconFactory.getInstance();
-        int color = hasChildren() ? IconFactory.COLOR_BLUE : IconFactory.COLOR_GREEN;
-        int shape = hasChildren() ? IconFactory.SHAPE_RECT : IconFactory.SHAPE_CIRCLE;
-        ImageDescriptor id = factory.getImageDescriptor(mXmlName, color, shape);
-        return id != null ? id : AdtPlugin.getAndroidLogoDesc();
-    }
-
-    /* Returns the list of allowed attributes. */
-    public AttributeDescriptor[] getAttributes() {
-        return mAttributes;
-    }
-    
-    /* Sets the list of allowed attributes. */
-    public void setAttributes(AttributeDescriptor[] attributes) {
-        mAttributes = attributes;
-        for (AttributeDescriptor attribute : attributes) {
-            attribute.setParent(this);
-        }
-    }
-
-    /** Returns the list of allowed children */
-    public ElementDescriptor[] getChildren() {
-        return mChildren;
-    }
-
-    /** @return True if this descriptor has children available */
-    public boolean hasChildren() {
-        return mChildren.length > 0;
-    }
-
-    /** Sets the list of allowed children. */
-    public void setChildren(ElementDescriptor[] newChildren) {
-        mChildren = newChildren;
-    }
-
-    /** Sets the list of allowed children.
-     * <p/>
-     * This is just a convenience method that converts a Collection into an array and
-     * calls {@link #setChildren(ElementDescriptor[])}.
-     * <p/>
-     * This means a <em>copy</em> of the collection is made. The collection is not
-     * stored by the recipient and can thus be altered by the caller.
-     */
-    public void setChildren(Collection<ElementDescriptor> newChildren) {
-        setChildren(newChildren.toArray(new ElementDescriptor[newChildren.size()]));
-    }
-
-    /**
-     * Returns an optional tooltip. Will be null if not present.
-     * <p/>
-     * The tooltip is based on the Javadoc of the element and already processed via
-     * {@link DescriptorsUtils#formatTooltip(String)} to be displayed right away as
-     * a UI tooltip.
-     */
-    public String getTooltip() {
-        return mTooltip;
-    }
-
-    /** Returns an optional SKD URL. Will be null if not present. */
-    public String getSdkUrl() {
-        return mSdkUrl;
-    }
-
-    /** Sets the optional tooltip. Can be null or empty. */
-    public void setTooltip(String tooltip) {
-        mTooltip = tooltip;
-    }
-    
-    /** Sets the optional SDK URL. Can be null or empty. */
-    public void setSdkUrl(String sdkUrl) {
-        mSdkUrl = sdkUrl;
-    }
-
-    /**
-     * @return A new {@link UiElementNode} linked to this descriptor.
-     */
-    public UiElementNode createUiNode() {
-        return new UiElementNode(this);
-    }
-    
-    /**
-     * Returns the first children of this descriptor that describes the given XML element name. 
-     * <p/>
-     * In recursive mode, searches the direct children first before descending in the hierarchy.
-     * 
-     * @return The ElementDescriptor matching the requested XML node element name or null.
-     */
-    public ElementDescriptor findChildrenDescriptor(String element_name, boolean recursive) {
-        return findChildrenDescriptorInternal(element_name, recursive, null);
-    }
-
-    private ElementDescriptor findChildrenDescriptorInternal(String element_name,
-            boolean recursive,
-            Set<ElementDescriptor> visited) {
-        if (recursive && visited == null) {
-            visited = new HashSet<ElementDescriptor>();
-        }
-
-        for (ElementDescriptor e : getChildren()) {
-            if (e.getXmlName().equals(element_name)) {
-                return e;
-            }
-        }
-
-        if (visited != null) {
-            visited.add(this);
-        }
-
-        if (recursive) {
-            for (ElementDescriptor e : getChildren()) {
-                if (visited != null) {
-                    if (!visited.add(e)) {  // Set.add() returns false if element is already present
-                        continue;
-                    }
-                }
-                ElementDescriptor f = e.findChildrenDescriptorInternal(element_name,
-                        recursive, visited);
-                if (f != null) {
-                    return f;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Utility helper than pretty-formats an XML Name for the UI.
-     * This is used by the simplified constructor that takes only an XML element name.
-     * 
-     * @param xml_name The XML name to convert.
-     * @return The XML name with dashes replaced by spaces and capitalized.
-     */
-    private static String prettyName(String xml_name) {
-        char c[] = xml_name.toCharArray();
-        if (c.length > 0) {
-            c[0] = Character.toUpperCase(c[0]);
-        }
-        return new String(c).replace("-", " ");  //$NON-NLS-1$  //$NON-NLS-2$
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/EnumAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/EnumAttributeDescriptor.java
deleted file mode 100644
index 4974e6e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/EnumAttributeDescriptor.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
-
-/**
- * Describes a text attribute that can only contains some predefined values.
- * It is displayed by a {@link UiListAttributeNode}.
- */
-public class EnumAttributeDescriptor extends ListAttributeDescriptor {
-
-    public EnumAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-    
-    /**
-     * @return A new {@link UiListAttributeNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiListAttributeNode(this, uiParent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/FlagAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/FlagAttributeDescriptor.java
deleted file mode 100644
index 15a90c7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/FlagAttributeDescriptor.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.ui.FlagValueCellEditor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiFlagAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
-
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * Describes a text attribute that can only contains some predefined values.
- * It is displayed by a {@link UiListAttributeNode}.
- * 
- * Note: in Android resources, a "flag" is a list of fixed values where one or
- * more values can be selected using an "or", e.g. "align='left|top'".
- * By contrast, an "enum" is a list of fixed values of which only one can be
- * selected at a given time, e.g. "gravity='right'".
- * <p/>
- * This class handles the "flag" case.
- * The "enum" case is done using {@link ListAttributeDescriptor}.
- */
-public class FlagAttributeDescriptor extends TextAttributeDescriptor {
-
-    private String[] mNames;
-
-    /**
-     * Creates a new {@link FlagAttributeDescriptor} which automatically gets its
-     * values from the FrameworkResourceManager.
-     */
-    public FlagAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-
-    /**
-    * Creates a new {@link FlagAttributeDescriptor} which uses the provided values.
-    */
-    public FlagAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip, String[] names) {
-       super(xmlLocalName, uiName, nsUri, tooltip);
-       mNames = names;
-    }
-
-    /**
-     * @return The initial names of the flags. Can be null, in which case the Framework
-     *         resource parser should be checked.
-     */
-    public String[] getNames() {
-        return mNames;
-    }
-    
-    /**
-     * @return A new {@link UiListAttributeNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiFlagAttributeNode(this, uiParent);
-    }
-    
-    // ------- IPropertyDescriptor Methods
-
-    @Override
-    public CellEditor createPropertyEditor(Composite parent) {
-        return new FlagValueCellEditor(parent);
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IDescriptorProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IDescriptorProvider.java
deleted file mode 100644
index 860ed39..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IDescriptorProvider.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-public interface IDescriptorProvider {
-
-    ElementDescriptor[] getRootElementDescriptors();
-    
-    ElementDescriptor getDescriptor();
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ListAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ListAttributeDescriptor.java
deleted file mode 100644
index bb22e45..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ListAttributeDescriptor.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.ui.ListValueCellEditor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
-
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * Describes a text attribute that can contains some predefined values.
- * It is displayed by a {@link UiListAttributeNode}.
- */
-public class ListAttributeDescriptor extends TextAttributeDescriptor {
-
-    private String[] mValues = null;
-    
-    /**
-     * Creates a new {@link ListAttributeDescriptor} which automatically gets its
-     * values from the FrameworkResourceManager.
-     */
-    public ListAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-
-     /**
-     * Creates a new {@link ListAttributeDescriptor} which uses the provided values.
-     */
-    public ListAttributeDescriptor(String xmlLocalName, String uiName, String nsUri, 
-            String tooltip, String[] values) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-        mValues = values;
-    }
-   
-    public String[] getValues() {
-        return mValues;
-    }
-
-    /**
-     * @return A new {@link UiListAttributeNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiListAttributeNode(this, uiParent);
-    }
-    
-    // ------- IPropertyDescriptor Methods
-
-    @Override
-    public CellEditor createPropertyEditor(Composite parent) {
-        return new ListValueCellEditor(parent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ReferenceAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ReferenceAttributeDescriptor.java
deleted file mode 100644
index fc0ed83..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ReferenceAttributeDescriptor.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.ui.ResourceValueCellEditor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * Describes an XML attribute displayed containing a value or a reference to a resource.
- * It is displayed by a {@link UiResourceAttributeNode}.
- */
-public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor {
-
-    /** The {@link ResourceType} that this reference attribute can accept. It can be null,
-     * in which case any reference type can be used. */
-    private ResourceType mResourceType;
-
-    /**
-     * Creates a reference attributes that can contain any type of resources.
-     * @param xmlLocalName The XML name of the attribute (case sensitive)
-     * @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param tooltip A non-empty tooltip string or null
-     */
-    public ReferenceAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-
-    /**
-     * Creates a reference attributes that can contain a reference to a specific
-     * {@link ResourceType}.
-     * @param resourceType The specific {@link ResourceType} that this reference attribute supports.
-     * It can be <code>null</code>, in which case, all resource types are supported.
-     * @param xmlLocalName The XML name of the attribute (case sensitive)
-     * @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param tooltip A non-empty tooltip string or null
-     */
-    public ReferenceAttributeDescriptor(ResourceType resourceType,
-            String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-        mResourceType = resourceType;
-    }
-
-
-    /** Returns the {@link ResourceType} that this reference attribute can accept.
-     * It can be null, in which case any reference type can be used. */
-    public ResourceType getResourceType() {
-        return mResourceType;
-    }
-
-    /**
-     * @return A new {@link UiResourceAttributeNode} linked to this reference descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiResourceAttributeNode(mResourceType, this, uiParent);
-    }
-
-    // ------- IPropertyDescriptor Methods
-
-    @Override
-    public CellEditor createPropertyEditor(Composite parent) {
-        return new ResourceValueCellEditor(parent);
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/SeparatorAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/SeparatorAttributeDescriptor.java
deleted file mode 100644
index 080877b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/SeparatorAttributeDescriptor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiSeparatorAttributeNode;
-
-/**
- * {@link SeparatorAttributeDescriptor} does not represent any real attribute.
- * <p/>
- * It is used to separate groups of attributes visually.
- */
-public class SeparatorAttributeDescriptor extends AttributeDescriptor {
-    
-    /**
-     * Creates a new {@link SeparatorAttributeDescriptor}
-     */
-    public SeparatorAttributeDescriptor(String label) {
-        super(label /* xmlLocalName */, null /* nsUri */);
-    }
-
-    /**
-     * @return A new {@link UiAttributeNode} linked to this descriptor or null if this
-     *         attribute has no user interface.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiSeparatorAttributeNode(this, uiParent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextAttributeDescriptor.java
deleted file mode 100644
index 37eca88..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextAttributeDescriptor.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.ui.TextValueCellEditor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.views.properties.IPropertyDescriptor;
-
-
-/**
- * Describes a textual XML attribute.
- * <p/>
- * Such an attribute has a tooltip and would typically be displayed by
- * {@link UiTextAttributeNode} using a label widget and text field.
- * <p/>
- * This is the "default" kind of attribute. If in doubt, use this.
- */
-public class TextAttributeDescriptor extends AttributeDescriptor implements IPropertyDescriptor {
-    private String mUiName;
-    private String mTooltip;
-    
-    /**
-     * Creates a new {@link TextAttributeDescriptor}
-     * 
-     * @param xmlLocalName The XML name of the attribute (case sensitive)
-     * @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param tooltip A non-empty tooltip string or null
-     */
-    public TextAttributeDescriptor(String xmlLocalName, String uiName,
-            String nsUri, String tooltip) {
-        super(xmlLocalName, nsUri);
-        mUiName = uiName;
-        mTooltip = (tooltip != null && tooltip.length() > 0) ? tooltip : null;
-    }
-
-    /**
-     * @return The UI name of the attribute. Cannot be an empty string and cannot be null.
-     */
-    public final String getUiName() {
-        return mUiName;
-    }
-
-    /**
-     * The tooltip string is either null or a non-empty string.
-     * <p/>
-     * The tooltip is based on the Javadoc of the attribute and already processed via
-     * {@link DescriptorsUtils#formatTooltip(String)} to be displayed right away as
-     * a UI tooltip.
-     * <p/>
-     * An empty string is converted to null, to match the behavior of setToolTipText() in
-     * {@link Control}.
-     * 
-     * @return A non-empty tooltip string or null
-     */
-    public final String getTooltip() {
-        return mTooltip;
-    }
-    
-    /**
-     * @return A new {@link UiTextAttributeNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiTextAttributeNode(this, uiParent);
-    }
-    
-    // ------- IPropertyDescriptor Methods
-
-    public CellEditor createPropertyEditor(Composite parent) {
-        return new TextValueCellEditor(parent);
-    }
-
-    public String getCategory() {
-        if (isDeprecated()) {
-            return "Deprecated";
-        }
-
-        ElementDescriptor parent = getParent();
-        if (parent != null) {
-            return parent.getUiName();
-        }
-
-        return null;
-    }
-
-    public String getDescription() {
-        return mTooltip;
-    }
-
-    public String getDisplayName() {
-        return mUiName;
-    }
-
-    public String[] getFilterFlags() {
-        return null;
-    }
-
-    public Object getHelpContextIds() {
-        return null;
-    }
-
-    public Object getId() {
-        return this;
-    }
-
-    public ILabelProvider getLabelProvider() {
-        return AttributeDescriptorLabelProvider.getProvider();
-    }
-
-    public boolean isCompatibleWith(IPropertyDescriptor anotherProperty) {
-        return anotherProperty == this;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextValueDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextValueDescriptor.java
deleted file mode 100644
index 381827d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextValueDescriptor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextValueNode;
-
-
-/**
- * Describes the value of an XML element.
- * <p/>
- * The value is a simple text string, displayed by an {@link UiTextValueNode}.
- */
-public class TextValueDescriptor extends TextAttributeDescriptor {
-    
-    /**
-     * Creates a new {@link TextValueDescriptor}
-     * 
-     * @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
-     * @param tooltip A non-empty tooltip string or null
-     */
-    public TextValueDescriptor(String uiName, String tooltip) {
-        super("#text" /* xmlLocalName */, uiName, null /* nsUri */, tooltip);
-    }
-
-    /**
-     * @return A new {@link UiTextValueNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiTextValueNode(this, uiParent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/XmlnsAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/XmlnsAttributeDescriptor.java
deleted file mode 100644
index 8f6efaf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/XmlnsAttributeDescriptor.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-
-/**
- * Describes an XMLNS attribute that is hidden.
- * <p/>
- * Such an attribute has no user interface and no corresponding {@link UiAttributeNode}.
- * It also has a single constant default value.
- * <p/>
- * When loading an XML, we'll ignore this attribute.
- * However when writing a new XML, we should always write this attribute.
- * <p/>
- * Currently this is used for the xmlns:android attribute in the manifest element.
- */
-public final class XmlnsAttributeDescriptor extends AttributeDescriptor {
-
-    /**
-     * URI of the reserved "xmlns"  prefix, as described in
-     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#normalizeDocumentAlgo
-     */
-    public final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; //$NON-NLS-1$ 
-    
-    private String mValue;
-
-    
-    public XmlnsAttributeDescriptor(String defaultPrefix, String value) {
-        super(defaultPrefix, XMLNS_URI);
-        mValue = value;
-    }
-
-    /**
-     * Returns the value of this specialized attribute descriptor, which is the URI associated
-     * to the declared namespace prefix.
-     */
-    public String getValue() {
-        return mValue;
-    }
-
-    /**
-     * Returns the "xmlns" prefix that is always used by this node for its namespace URI.
-     * This is defined by the XML specification.
-     */
-    public String getXmlNsPrefix() {
-        return "xmlns"; //$NON-NLS-1$
-    }
-    
-    /**
-     * Returns the fully-qualified attribute name, namely "xmlns:xxx" where xxx is
-     * the defaultPrefix passed in the constructor.
-     */
-    public String getXmlNsName() {
-        return getXmlNsPrefix() + ":" + getXmlLocalName(); //$NON-NLS-1$
-    }
-    
-    /**
-     * @return Always returns null. {@link XmlnsAttributeDescriptor} has no user interface.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/BasePullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/BasePullParser.java
deleted file mode 100644
index a44f1f3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/BasePullParser.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.layoutlib.api.IXmlPullParser;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * Base implementation of an {@link IXmlPullParser} for cases where the parser is not sitting
- * on top of an actual XML file.
- * <p/>It's designed to work on layout files, and will most likely not work on other resource
- * files.
- */
-public abstract class BasePullParser implements IXmlPullParser {
-    
-    protected int mParsingState = START_DOCUMENT;
-    
-    public BasePullParser() {
-    }
-    
-    // --- new methods to override ---
-    
-    public abstract void onNextFromStartDocument();
-    public abstract void onNextFromStartTag();
-    public abstract void onNextFromEndTag();
-    
-    // --- basic implementation of IXmlPullParser ---
-    
-    public void setFeature(String name, boolean state) throws XmlPullParserException {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
-            return;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
-            return;
-        }
-        throw new XmlPullParserException("Unsupported feature: " + name);
-    }
-
-    public boolean getFeature(String name) {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
-            return true;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
-            return true;
-        }
-        return false;
-    }
-
-    public void setProperty(String name, Object value) throws XmlPullParserException {
-        throw new XmlPullParserException("setProperty() not supported");
-    }
-
-    public Object getProperty(String name) {
-        return null;
-    }
-
-    public void setInput(Reader in) throws XmlPullParserException {
-        throw new XmlPullParserException("setInput() not supported");
-    }
-
-    public void setInput(InputStream inputStream, String inputEncoding)
-            throws XmlPullParserException {
-        throw new XmlPullParserException("setInput() not supported");
-    }
-
-    public void defineEntityReplacementText(String entityName, String replacementText)
-            throws XmlPullParserException {
-        throw new XmlPullParserException("defineEntityReplacementText() not supported");
-    }
-
-    public String getNamespacePrefix(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespacePrefix() not supported");
-    }
-
-    public String getInputEncoding() {
-        return null;
-    }
-
-    public String getNamespace(String prefix) {
-        throw new RuntimeException("getNamespace() not supported");
-    }
-
-    public int getNamespaceCount(int depth) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceCount() not supported");
-    }
-
-    public String getNamespaceUri(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceUri() not supported");
-    }
-
-    public int getColumnNumber() {
-        return -1;
-    }
-
-    public int getLineNumber() {
-        return -1;
-    }
-
-    public String getAttributeType(int arg0) {
-        return "CDATA";
-    }
-
-    public int getEventType() {
-        return mParsingState;
-    }
-
-    public String getText() {
-        return null;
-    }
-
-    public char[] getTextCharacters(int[] arg0) {
-        return null;
-    }
-
-    public boolean isAttributeDefault(int arg0) {
-        return false;
-    }
-
-    public boolean isWhitespace() {
-        return false;
-    }
-    
-    public int next() throws XmlPullParserException {
-        switch (mParsingState) {
-            case END_DOCUMENT:
-                throw new XmlPullParserException("Nothing after the end");
-            case START_DOCUMENT:
-                onNextFromStartDocument();
-                break;
-            case START_TAG:
-                onNextFromStartTag();
-                break;
-            case END_TAG:
-                onNextFromEndTag();
-                break;
-            case TEXT:
-                // not used
-                break;
-            case CDSECT:
-                // not used
-                break;
-            case ENTITY_REF:
-                // not used
-                break;
-            case IGNORABLE_WHITESPACE:
-                // not used
-                break;
-            case PROCESSING_INSTRUCTION:
-                // not used
-                break;
-            case COMMENT:
-                // not used
-                break;
-            case DOCDECL:
-                // not used
-                break;
-        }
-        
-        return mParsingState;
-    }
-
-    public int nextTag() throws XmlPullParserException {
-        int eventType = next();
-        if (eventType != START_TAG && eventType != END_TAG) {
-            throw new XmlPullParserException("expected start or end tag", this, null);
-        }
-        return eventType;
-    }
-
-    public String nextText() throws XmlPullParserException {
-        if (getEventType() != START_TAG) {
-            throw new XmlPullParserException("parser must be on START_TAG to read next text", this,
-                    null);
-        }
-        int eventType = next();
-        if (eventType == TEXT) {
-            String result = getText();
-            eventType = next();
-            if (eventType != END_TAG) {
-                throw new XmlPullParserException(
-                        "event TEXT it must be immediately followed by END_TAG", this, null);
-            }
-            return result;
-        } else if (eventType == END_TAG) {
-            return "";
-        } else {
-            throw new XmlPullParserException("parser must be on START_TAG or TEXT to read text",
-                    this, null);
-        }
-    }
-
-    public int nextToken() throws XmlPullParserException {
-        return next();
-    }
-
-    public void require(int type, String namespace, String name) throws XmlPullParserException {
-        if (type != getEventType() || (namespace != null && !namespace.equals(getNamespace()))
-                || (name != null && !name.equals(getName())))
-            throw new XmlPullParserException("expected " + TYPES[type] + getPositionDescription());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalEditorPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalEditorPart.java
deleted file mode 100755
index 302d3db..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalEditorPart.java
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.LayoutCreatorDialog;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.layoutlib.api.ILayoutBridge;
-import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.api.ILayoutResult;
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IXmlPullParser;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.gef.ui.parts.SelectionSynchronizer;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.ide.IDE;
-import org.eclipse.ui.part.EditorPart;
-import org.eclipse.ui.part.FileEditorInput;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.Map;
-
-/**
- * Graphical layout editor part, version 2.
- *
- * @since GLE2
- *
- * TODO List:
- * - display error icon
- * - finish palette (see palette's todo list)
- * - finish canvas (see canva's todo list)
- * - completly rethink the property panel
- * - link to the existing outline editor (prolly reuse/adapt for simplier model and will need
- *   to adapt the selection synchronizer.)
- */
-public class GraphicalEditorPart extends EditorPart implements IGraphicalLayoutEditor {
-
-    /*
-     * Useful notes:
-     * To understand Drag'n'drop:
-     *   http://www.eclipse.org/articles/Article-Workbench-DND/drag_drop.html
-     */
-
-    /** Reference to the layout editor */
-    private final LayoutEditor mLayoutEditor;
-
-    /** reference to the file being edited. */
-    private IFile mEditedFile;
-
-    /** The current clipboard. Must be disposed later. */
-    private Clipboard mClipboard;
-
-    /** The configuration composite at the top of the layout editor. */
-    private ConfigurationComposite mConfigComposite;
-
-    /** The sash that splits the palette from the canvas. */
-    private SashForm mSashPalette;
-    private SashForm mSashError;
-
-    /** The palette displayed on the left of the sash. */
-    private PaletteComposite mPalette;
-
-    /** The layout canvas displayed o the right of the sash. */
-    private LayoutCanvas mLayoutCanvas;
-
-    private StyledText mErrorLabel;
-
-    /** The {@link FolderConfiguration} being edited. */
-    private FolderConfiguration mEditedConfig;
-
-    private Map<String, Map<String, IResourceValue>> mConfiguredFrameworkRes;
-    private Map<String, Map<String, IResourceValue>> mConfiguredProjectRes;
-    private ProjectCallback mProjectCallback;
-    private ILayoutLog mLogger;
-
-    private boolean mNeedsXmlReload = false;
-    private boolean mNeedsRecompute = false;
-
-    private TargetListener mTargetListener;
-
-    private ConfigListener mConfigListener;
-
-    private ReloadListener mReloadListener;
-
-
-    public GraphicalEditorPart(LayoutEditor layoutEditor) {
-        mLayoutEditor = layoutEditor;
-        setPartName("Graphical Layout");
-    }
-
-    // ------------------------------------
-    // Methods overridden from base classes
-    //------------------------------------
-
-    /**
-     * Initializes the editor part with a site and input.
-     * {@inheritDoc}
-     */
-    @Override
-    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
-        setSite(site);
-        useNewEditorInput(input);
-
-        if (mTargetListener == null) {
-            mTargetListener = new TargetListener();
-            AdtPlugin.getDefault().addTargetListener(mTargetListener);
-        }
-
-        if (mReloadListener == null) {
-            mReloadListener = new ReloadListener();
-            LayoutReloadMonitor.getMonitor().addListener(mEditedFile.getProject(), mReloadListener);
-        }
-    }
-
-    /**
-     * Reloads this editor, by getting the new model from the {@link LayoutEditor}.
-     */
-    public void reloadEditor() {
-        IEditorInput input = mLayoutEditor.getEditorInput();
-
-        try {
-            useNewEditorInput(input);
-        } catch (PartInitException e) {
-            // really this shouldn't happen! Log it in case it happens.
-            mEditedFile = null;
-            AdtPlugin.log(e, "Input is not of type FileEditorInput: %1$s",          //$NON-NLS-1$
-                    input == null ? "null" : input.toString());                     //$NON-NLS-1$
-        }
-    }
-
-    private void useNewEditorInput(IEditorInput input) throws PartInitException {
-        // The contract of init() mentions we need to fail if we can't understand the input.
-        if (!(input instanceof FileEditorInput)) {
-            throw new PartInitException("Input is not of type FileEditorInput: " +  //$NON-NLS-1$
-                    input == null ? "null" : input.toString());                     //$NON-NLS-1$
-        }
-
-        FileEditorInput fileInput = (FileEditorInput)input;
-        mEditedFile = fileInput.getFile();
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-
-        Display d = parent.getDisplay();
-        mClipboard = new Clipboard(d);
-
-        GridLayout gl = new GridLayout(1, false);
-        parent.setLayout(gl);
-        gl.marginHeight = gl.marginWidth = 0;
-
-        // create the top part for the configuration control
-        mConfigListener = new ConfigListener();
-        mConfigComposite = new ConfigurationComposite(mConfigListener, parent, SWT.BORDER);
-        mConfigComposite.updateUIFromResources();
-
-        mSashPalette = new SashForm(parent, SWT.HORIZONTAL);
-        mSashPalette.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        mPalette = new PaletteComposite(mSashPalette);
-
-        mSashError = new SashForm(mSashPalette, SWT.VERTICAL | SWT.BORDER);
-        mSashError.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        mLayoutCanvas = new LayoutCanvas(mSashError, SWT.NONE);
-        mErrorLabel = new StyledText(mSashError, SWT.READ_ONLY);
-        mErrorLabel.setEditable(false);
-        mErrorLabel.setBackground(d.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-        mErrorLabel.setForeground(d.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
-
-        mSashPalette.setWeights(new int[] { 20, 80 });
-        mSashError.setWeights(new int[] { 80, 20 });
-        mSashError.setMaximizedControl(mLayoutCanvas);
-
-        // Initialize the state
-        reloadPalette();
-    }
-
-    /**
-     * Switches the stack to display the error label and hide the canvas.
-     * @param errorFormat The new error to display if not null.
-     * @param parameters String.format parameters for the error format.
-     */
-    private void displayError(String errorFormat, Object...parameters) {
-        if (errorFormat != null) {
-            mErrorLabel.setText(String.format(errorFormat, parameters));
-        }
-        mSashError.setMaximizedControl(null);
-    }
-
-    /** Displays the canvas and hides the error label. */
-    private void hideError() {
-        mSashError.setMaximizedControl(mLayoutCanvas);
-    }
-
-    @Override
-    public void dispose() {
-        if (mTargetListener != null) {
-            AdtPlugin.getDefault().removeTargetListener(mTargetListener);
-            mTargetListener = null;
-        }
-
-        if (mReloadListener != null) {
-            LayoutReloadMonitor.getMonitor().removeListener(mReloadListener);
-            mReloadListener = null;
-        }
-
-        if (mClipboard != null) {
-            mClipboard.dispose();
-            mClipboard = null;
-        }
-
-        super.dispose();
-    }
-
-    /**
-     * Listens to changes from the Configuration UI banner and triggers layout rendering when
-     * changed. Also provide the Configuration UI with the list of resources/layout to display.
-     */
-    private class ConfigListener implements IConfigListener {
-
-        /**
-         * Looks for a file matching the new {@link FolderConfiguration} and attempts to open it.
-         * <p/>If there is no match, notify the user.
-         */
-        public void onConfigurationChange() {
-            mConfiguredFrameworkRes = mConfiguredProjectRes = null;
-
-            if (mEditedFile == null || mEditedConfig == null) {
-                return;
-            }
-
-            // get the resources of the file's project.
-            ProjectResources resources = ResourceManager.getInstance().getProjectResources(
-                    mEditedFile.getProject());
-
-            // from the resources, look for a matching file
-            ResourceFile match = null;
-            if (resources != null) {
-                match = resources.getMatchingFile(mEditedFile.getName(),
-                                                  ResourceFolderType.LAYOUT,
-                                                  mConfigComposite.getCurrentConfig());
-            }
-
-            if (match != null) {
-                if (match.getFile().equals(mEditedFile) == false) {
-                    try {
-                        IDE.openEditor(
-                                getSite().getWorkbenchWindow().getActivePage(),
-                                match.getFile().getIFile());
-
-                        // we're done!
-                        return;
-                    } catch (PartInitException e) {
-                        // FIXME: do something!
-                    }
-                }
-
-                // at this point, we have not opened a new file.
-
-                // update the configuration icons with the new edited config.
-                setConfiguration(mEditedConfig, false /*force*/);
-
-                // enable the create button if the current and edited config are not equals
-                mConfigComposite.setEnabledCreate(
-                        mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false);
-
-                // Even though the layout doesn't change, the config changed, and referenced
-                // resources need to be updated.
-                recomputeLayout();
-            } else {
-                // enable the Create button
-                mConfigComposite.setEnabledCreate(true);
-
-                // display the error.
-                FolderConfiguration currentConfig = mConfigComposite.getCurrentConfig();
-                displayError(
-                        "No resources match the configuration\n \n\t%1$s\n \nChange the configuration or create:\n \n\tres/%2$s/%3$s\n \nYou can also click the 'Create' button above.",
-                        currentConfig.toDisplayString(),
-                        currentConfig.getFolderName(ResourceFolderType.LAYOUT,
-                                Sdk.getCurrent().getTarget(mEditedFile.getProject())),
-                        mEditedFile.getName());
-            }
-        }
-
-        public void onThemeChange() {
-            recomputeLayout();
-        }
-
-        public void OnClippingChange() {
-            recomputeLayout();
-        }
-
-        public void onCreate() {
-            LayoutCreatorDialog dialog = new LayoutCreatorDialog(mConfigComposite.getShell(),
-                    mEditedFile.getName(),
-                    Sdk.getCurrent().getTarget(mEditedFile.getProject()),
-                    mConfigComposite.getCurrentConfig());
-            if (dialog.open() == Dialog.OK) {
-                final FolderConfiguration config = new FolderConfiguration();
-                dialog.getConfiguration(config);
-
-                createAlternateLayout(config);
-            }
-        }
-
-        public Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources() {
-            if (mConfiguredFrameworkRes == null && mConfigComposite != null) {
-                ProjectResources frameworkRes = getFrameworkResources();
-
-                if (frameworkRes == null) {
-                    AdtPlugin.log(IStatus.ERROR, "Failed to get ProjectResource for the framework");
-                } else {
-                    // get the framework resource values based on the current config
-                    mConfiguredFrameworkRes = frameworkRes.getConfiguredResources(
-                            mConfigComposite.getCurrentConfig());
-                }
-            }
-
-            return mConfiguredFrameworkRes;
-        }
-
-        public Map<String, Map<String, IResourceValue>> getConfiguredProjectResources() {
-            if (mConfiguredProjectRes == null && mConfigComposite != null) {
-                ProjectResources project = getProjectResources();
-
-                // make sure they are loaded
-                project.loadAll();
-
-                // get the project resource values based on the current config
-                mConfiguredProjectRes = project.getConfiguredResources(
-                        mConfigComposite.getCurrentConfig());
-            }
-
-            return mConfiguredProjectRes;
-        }
-
-        /**
-         * Returns a {@link ProjectResources} for the framework resources.
-         * @return the framework resources or null if not found.
-         */
-        public ProjectResources getFrameworkResources() {
-            if (mEditedFile != null) {
-                Sdk currentSdk = Sdk.getCurrent();
-                if (currentSdk != null) {
-                    IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject());
-
-                    if (target != null) {
-                        AndroidTargetData data = currentSdk.getTargetData(target);
-
-                        if (data != null) {
-                            return data.getFrameworkResources();
-                        }
-                    }
-                }
-            }
-
-            return null;
-        }
-
-        public ProjectResources getProjectResources() {
-            if (mEditedFile != null) {
-                ResourceManager manager = ResourceManager.getInstance();
-                return manager.getProjectResources(mEditedFile.getProject());
-            }
-
-            return null;
-        }
-
-        /**
-         * Creates a new layout file from the specified {@link FolderConfiguration}.
-         */
-        private void createAlternateLayout(final FolderConfiguration config) {
-            new Job("Create Alternate Resource") {
-                @Override
-                protected IStatus run(IProgressMonitor monitor) {
-                    // get the folder name
-                    String folderName = config.getFolderName(ResourceFolderType.LAYOUT,
-                            Sdk.getCurrent().getTarget(mEditedFile.getProject()));
-                    try {
-
-                        // look to see if it exists.
-                        // get the res folder
-                        IFolder res = (IFolder)mEditedFile.getParent().getParent();
-                        String path = res.getLocation().toOSString();
-
-                        File newLayoutFolder = new File(path + File.separator + folderName);
-                        if (newLayoutFolder.isFile()) {
-                            // this should not happen since aapt would have complained
-                            // before, but if one disable the automatic build, this could
-                            // happen.
-                            String message = String.format("File 'res/%1$s' is in the way!",
-                                    folderName);
-
-                            AdtPlugin.displayError("Layout Creation", message);
-
-                            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, message);
-                        } else if (newLayoutFolder.exists() == false) {
-                            // create it.
-                            newLayoutFolder.mkdir();
-                        }
-
-                        // now create the file
-                        File newLayoutFile = new File(newLayoutFolder.getAbsolutePath() +
-                                    File.separator + mEditedFile.getName());
-
-                        newLayoutFile.createNewFile();
-
-                        InputStream input = mEditedFile.getContents();
-
-                        FileOutputStream fos = new FileOutputStream(newLayoutFile);
-
-                        byte[] data = new byte[512];
-                        int count;
-                        while ((count = input.read(data)) != -1) {
-                            fos.write(data, 0, count);
-                        }
-
-                        input.close();
-                        fos.close();
-
-                        // refreshes the res folder to show up the new
-                        // layout folder (if needed) and the file.
-                        // We use a progress monitor to catch the end of the refresh
-                        // to trigger the edit of the new file.
-                        res.refreshLocal(IResource.DEPTH_INFINITE, new IProgressMonitor() {
-                            public void done() {
-                                mConfigComposite.getDisplay().asyncExec(new Runnable() {
-                                    public void run() {
-                                        onConfigurationChange();
-                                    }
-                                });
-                            }
-
-                            public void beginTask(String name, int totalWork) {
-                                // pass
-                            }
-
-                            public void internalWorked(double work) {
-                                // pass
-                            }
-
-                            public boolean isCanceled() {
-                                // pass
-                                return false;
-                            }
-
-                            public void setCanceled(boolean value) {
-                                // pass
-                            }
-
-                            public void setTaskName(String name) {
-                                // pass
-                            }
-
-                            public void subTask(String name) {
-                                // pass
-                            }
-
-                            public void worked(int work) {
-                                // pass
-                            }
-                        });
-                    } catch (IOException e2) {
-                        String message = String.format(
-                                "Failed to create File 'res/%1$s/%2$s' : %3$s",
-                                folderName, mEditedFile.getName(), e2.getMessage());
-
-                        AdtPlugin.displayError("Layout Creation", message);
-
-                        return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                                message, e2);
-                    } catch (CoreException e2) {
-                        String message = String.format(
-                                "Failed to create File 'res/%1$s/%2$s' : %3$s",
-                                folderName, mEditedFile.getName(), e2.getMessage());
-
-                        AdtPlugin.displayError("Layout Creation", message);
-
-                        return e2.getStatus();
-                    }
-
-                    return Status.OK_STATUS;
-
-                }
-            }.schedule();
-        }
-    }
-
-    /**
-     * Listens to target changed in the current project, to trigger a new layout rendering.
-     */
-    private class TargetListener implements ITargetChangeListener {
-
-        public void onProjectTargetChange(IProject changedProject) {
-            if (changedProject == getLayoutEditor().getProject()) {
-                onTargetsLoaded();
-            }
-        }
-
-        public void onTargetsLoaded() {
-            // because the SDK changed we must reset the configured framework resource.
-            mConfiguredFrameworkRes = null;
-
-            mConfigComposite.updateUIFromResources();
-
-            // updateUiFromFramework will reset language/region combo, so we must call
-            // setConfiguration after, or the settext on language/region will be lost.
-            if (mEditedConfig != null) {
-                setConfiguration(mEditedConfig, false /*force*/);
-            }
-
-            // make sure we remove the custom view loader, since its parent class loader is the
-            // bridge class loader.
-            mProjectCallback = null;
-
-            recomputeLayout();
-        }
-    }
-
-    /**
-     * Update the UI controls state with a given {@link FolderConfiguration}.
-     * <p/>If <var>force</var> is set to <code>true</code> the UI will be changed to exactly reflect
-     * <var>config</var>, otherwise, if a qualifier is not present in <var>config</var>,
-     * the UI control is not modified. However if the value in the control is not the default value,
-     * a warning icon is shown.
-     * @param config The {@link FolderConfiguration} to set.
-     * @param force Whether the UI should be changed to exactly match the received configuration.
-     */
-    void setConfiguration(FolderConfiguration config, boolean force) {
-        mEditedConfig = config;
-        mConfiguredFrameworkRes = mConfiguredProjectRes = null;
-
-        mConfigComposite.setConfiguration(config, force);
-
-    }
-
-    // ----------------
-
-    /**
-     * Save operation in the Graphical Editor Part.
-     * <p/>
-     * In our workflow, the model is owned by the Structured XML Editor.
-     * The graphical layout editor just displays it -- thus we don't really
-     * save anything here.
-     * <p/>
-     * This must NOT call the parent editor part. At the contrary, the parent editor
-     * part will call this *after* having done the actual save operation.
-     * <p/>
-     * The only action this editor must do is mark the undo command stack as
-     * being no longer dirty.
-     */
-    @Override
-    public void doSave(IProgressMonitor monitor) {
-        // TODO implement a command stack
-//        getCommandStack().markSaveLocation();
-//        firePropertyChange(PROP_DIRTY);
-    }
-
-    /**
-     * Save operation in the Graphical Editor Part.
-     * <p/>
-     * In our workflow, the model is owned by the Structured XML Editor.
-     * The graphical layout editor just displays it -- thus we don't really
-     * save anything here.
-     */
-    @Override
-    public void doSaveAs() {
-        // pass
-    }
-
-    /**
-     * In our workflow, the model is owned by the Structured XML Editor.
-     * The graphical layout editor just displays it -- thus we don't really
-     * save anything here.
-     */
-    @Override
-    public boolean isDirty() {
-        return false;
-    }
-
-    /**
-     * In our workflow, the model is owned by the Structured XML Editor.
-     * The graphical layout editor just displays it -- thus we don't really
-     * save anything here.
-     */
-    @Override
-    public boolean isSaveAsAllowed() {
-        return false;
-    }
-
-    @Override
-    public void setFocus() {
-        // TODO Auto-generated method stub
-
-    }
-
-    /**
-     * Responds to a page change that made the Graphical editor page the activated page.
-     */
-    public void activated() {
-        if (mNeedsRecompute || mNeedsXmlReload) {
-            recomputeLayout();
-        }
-    }
-
-    /**
-     * Responds to a page change that made the Graphical editor page the deactivated page
-     */
-    public void deactivated() {
-        // nothing to be done here for now.
-    }
-
-    /**
-     * Sets the UI for the edition of a new file.
-     * @param configuration the configuration of the new file.
-     */
-    public void editNewFile(FolderConfiguration configuration) {
-        // update the configuration UI
-        setConfiguration(configuration, true /*force*/);
-
-        // enable the create button if the current and edited config are not equals
-        mConfigComposite.setEnabledCreate(
-                mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false);
-
-        reloadConfigurationUi(false /*notifyListener*/);
-    }
-
-    public Clipboard getClipboard() {
-        return mClipboard;
-    }
-
-    public LayoutEditor getLayoutEditor() {
-        return mLayoutEditor;
-    }
-
-    public UiDocumentNode getModel() {
-        return mLayoutEditor.getUiRootNode();
-    }
-
-    public SelectionSynchronizer getSelectionSynchronizer() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /**
-     * Callback for XML model changed. Only update/recompute the layout if the editor is visible
-     */
-    public void onXmlModelChanged() {
-        if (mLayoutEditor.isGraphicalEditorActive()) {
-            doXmlReload(true /* force */);
-            recomputeLayout();
-        } else {
-            mNeedsXmlReload = true;
-        }
-    }
-
-    /**
-     * Actually performs the XML reload
-     * @see #onXmlModelChanged()
-     */
-    private void doXmlReload(boolean force) {
-        if (force || mNeedsXmlReload) {
-
-            // TODO : update the mLayoutCanvas, preserving the current selection if possible.
-
-//            GraphicalViewer viewer = getGraphicalViewer();
-//
-//            // try to preserve the selection before changing the content
-//            SelectionManager selMan = viewer.getSelectionManager();
-//            ISelection selection = selMan.getSelection();
-//
-//            try {
-//                viewer.setContents(getModel());
-//            } finally {
-//                selMan.setSelection(selection);
-//            }
-
-            mNeedsXmlReload = false;
-        }
-    }
-
-    public void recomputeLayout() {
-        doXmlReload(false /* force */);
-        try {
-            // check that the resource exists. If the file is opened but the project is closed
-            // or deleted for some reason (changed from outside of eclipse), then this will
-            // return false;
-            if (mEditedFile.exists() == false) {
-                displayError("Resource '%1$s' does not exist.",
-                             mEditedFile.getFullPath().toString());
-                return;
-            }
-
-            IProject iProject = mEditedFile.getProject();
-
-            if (mEditedFile.isSynchronized(IResource.DEPTH_ZERO) == false) {
-                String message = String.format("%1$s is out of sync. Please refresh.",
-                        mEditedFile.getName());
-
-                displayError(message);
-
-                // also print it in the error console.
-                AdtPlugin.printErrorToConsole(iProject.getName(), message);
-                return;
-            }
-
-            Sdk currentSdk = Sdk.getCurrent();
-            if (currentSdk != null) {
-                IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject());
-                if (target == null) {
-                    displayError("The project target is not set.");
-                    return;
-                }
-
-                AndroidTargetData data = currentSdk.getTargetData(target);
-                if (data == null) {
-                    // It can happen that the workspace refreshes while the SDK is loading its
-                    // data, which could trigger a redraw of the opened layout if some resources
-                    // changed while Eclipse is closed.
-                    // In this case data could be null, but this is not an error.
-                    // We can just silently return, as all the opened editors are automatically
-                    // refreshed once the SDK finishes loading.
-                    if (AdtPlugin.getDefault().getSdkLoadStatus() != LoadStatus.LOADING) {
-                        displayError("The project target (%s) was not properly loaded.",
-                                     target.getName());
-                    }
-                    return;
-                }
-
-                // check there is actually a model (maybe the file is empty).
-                UiDocumentNode model = getModel();
-
-                if (model.getUiChildren().size() == 0) {
-                    displayError("No Xml content. Go to the Outline view and add nodes.");
-                    return;
-                }
-
-                LayoutBridge bridge = data.getLayoutBridge();
-
-                if (bridge.bridge != null) { // bridge can never be null.
-                    ResourceManager resManager = ResourceManager.getInstance();
-
-                    ProjectResources projectRes = resManager.getProjectResources(iProject);
-                    if (projectRes == null) {
-                        displayError("Missing project resources.");
-                        return;
-                    }
-
-                    // get the resources of the file's project.
-                    Map<String, Map<String, IResourceValue>> configuredProjectRes =
-                        mConfigListener.getConfiguredProjectResources();
-
-                    // get the framework resources
-                    Map<String, Map<String, IResourceValue>> frameworkResources =
-                        mConfigListener.getConfiguredFrameworkResources();
-
-                    if (configuredProjectRes != null && frameworkResources != null) {
-                        if (mProjectCallback == null) {
-                            mProjectCallback = new ProjectCallback(
-                                    bridge.classLoader, projectRes, iProject);
-                        }
-
-                        if (mLogger == null) {
-                            mLogger = new ILayoutLog() {
-                                public void error(String message) {
-                                    AdtPlugin.printErrorToConsole(mEditedFile.getName(), message);
-                                }
-
-                                public void error(Throwable error) {
-                                    String message = error.getMessage();
-                                    if (message == null) {
-                                        message = error.getClass().getName();
-                                    }
-
-                                    PrintStream ps = new PrintStream(AdtPlugin.getErrorStream());
-                                    error.printStackTrace(ps);
-                                }
-
-                                public void warning(String message) {
-                                    AdtPlugin.printToConsole(mEditedFile.getName(), message);
-                                }
-                            };
-                        }
-
-                        // get the selected theme
-                        String theme = mConfigComposite.getTheme();
-                        if (theme != null) {
-
-                            // Compute the layout
-                            UiElementPullParser parser = new UiElementPullParser(getModel());
-                            Rectangle rect = getBounds();
-                            boolean isProjectTheme = mConfigComposite.isProjectTheme();
-
-                            int density = mConfigComposite.getDensity().getDpiValue();
-                            float xdpi = mConfigComposite.getXDpi();
-                            float ydpi = mConfigComposite.getYDpi();
-
-                            ILayoutResult result = computeLayout(bridge, parser,
-                                    iProject /* projectKey */,
-                                    rect.width, rect.height, !mConfigComposite.getClipping(),
-                                    density, xdpi, ydpi,
-                                    theme, isProjectTheme,
-                                    configuredProjectRes, frameworkResources, mProjectCallback,
-                                    mLogger);
-
-                            mLayoutCanvas.setResult(result);
-
-                            // update the UiElementNode with the layout info.
-                            if (result.getSuccess() == ILayoutResult.SUCCESS) {
-                                hideError();
-                            } else {
-                                displayError(result.getErrorMessage());
-                            }
-
-                            model.refreshUi();
-                        }
-                    }
-                } else {
-                    // SDK is loaded but not the layout library!
-
-                    // check whether the bridge managed to load, or not
-                    if (bridge.status == LoadStatus.LOADING) {
-                        displayError("Eclipse is loading framework information and the layout library from the SDK folder.\n%1$s will refresh automatically once the process is finished.",
-                                     mEditedFile.getName());
-                    } else {
-                        displayError("Eclipse failed to load the framework information and the layout library!");
-                    }
-                }
-            } else {
-                displayError("Eclipse is loading the SDK.\n%1$s will refresh automatically once the process is finished.",
-                             mEditedFile.getName());
-            }
-        } finally {
-            // no matter the result, we are done doing the recompute based on the latest
-            // resource/code change.
-            mNeedsRecompute = false;
-        }
-    }
-
-    /**
-     * Computes a layout by calling the correct computeLayout method of ILayoutBridge based on
-     * the implementation API level.
-     *
-     * Implementation detail: the bridge's computeLayout() method already returns a newly
-     * allocated ILayourResult.
-     */
-    @SuppressWarnings("deprecation")
-    private static ILayoutResult computeLayout(LayoutBridge bridge,
-            IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, boolean renderFullSize,
-            int density, float xdpi, float ydpi,
-            String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback projectCallback, ILayoutLog logger) {
-
-        if (bridge.apiLevel >= ILayoutBridge.API_CURRENT) {
-            // newest API with support for "render full height"
-            // TODO: link boolean to UI.
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, renderFullSize,
-                    density, xdpi, ydpi,
-                    themeName, isProjectTheme,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        } else if (bridge.apiLevel == 3) {
-            // newer api with density support.
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, density, xdpi, ydpi,
-                    themeName, isProjectTheme,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        } else if (bridge.apiLevel == 2) {
-            // api with boolean for separation of project/framework theme
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, themeName, isProjectTheme,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        } else {
-            // oldest api with no density/dpi, and project theme boolean mixed
-            // into the theme name.
-
-            // change the string if it's a custom theme to make sure we can
-            // differentiate them
-            if (isProjectTheme) {
-                themeName = "*" + themeName; //$NON-NLS-1$
-            }
-
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, themeName,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        }
-    }
-
-    public Rectangle getBounds() {
-        return mConfigComposite.getScreenBounds();
-    }
-
-    public void reloadPalette() {
-        if (mPalette != null) {
-            mPalette.reloadPalette(mLayoutEditor.getTargetData());
-        }
-    }
-
-    public void reloadConfigurationUi(boolean notifyListener) {
-        // enable the clipping button if it's supported.
-        Sdk currentSdk = Sdk.getCurrent();
-        if (currentSdk != null) {
-            IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject());
-            AndroidTargetData data = currentSdk.getTargetData(target);
-            if (data != null) {
-                LayoutBridge bridge = data.getLayoutBridge();
-                mConfigComposite.reloadDevices(notifyListener);
-                mConfigComposite.setClippingSupport(bridge.apiLevel >= 4);
-            }
-        }
-    }
-
-    /**
-     * Used by LayoutEditor.UiEditorActions.selectUiNode to select a new UI Node
-     * created by {@link ElementCreateCommand#execute()}.
-     *
-     * @param uiNodeModel The {@link UiElementNode} to select.
-     */
-    public void selectModel(UiElementNode uiNodeModel) {
-
-        // TODO this method was useful for GLE1. We may not need it anymore now.
-
-//        GraphicalViewer viewer = getGraphicalViewer();
-//
-//        // Give focus to the graphical viewer (in case the outline has it)
-//        viewer.getControl().forceFocus();
-//
-//        Object editPart = viewer.getEditPartRegistry().get(uiNodeModel);
-//
-//        if (editPart instanceof EditPart) {
-//            viewer.select((EditPart)editPart);
-//        }
-    }
-
-    private class ReloadListener implements ILayoutReloadListener {
-        /*
-         * (non-Javadoc)
-         * @see com.android.ide.eclipse.editors.layout.LayoutReloadMonitor.ILayoutReloadListener#reloadLayout(boolean, boolean, boolean)
-         *
-         * Called when the file changes triggered a redraw of the layout
-         */
-        public void reloadLayout(boolean codeChange, boolean rChange, boolean resChange) {
-            boolean recompute = rChange;
-
-            if (resChange) {
-                recompute = true;
-
-                // TODO: differentiate between single and multi resource file changed, and whether the resource change affects the cache.
-
-                // force a reparse in case a value XML file changed.
-                mConfiguredProjectRes = null;
-
-                // clear the cache in the bridge in case a bitmap/9-patch changed.
-                IAndroidTarget target = Sdk.getCurrent().getTarget(mEditedFile.getProject());
-                if (target != null) {
-
-                    AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
-                    if (data != null) {
-                        LayoutBridge bridge = data.getLayoutBridge();
-
-                        if (bridge.bridge != null) {
-                            bridge.bridge.clearCaches(mEditedFile.getProject());
-                        }
-                    }
-                }
-
-                mLayoutCanvas.getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        mConfigComposite.updateUIFromResources();
-                    }
-                });
-            }
-
-            if (codeChange) {
-                // only recompute if the custom view loader was used to load some code.
-                if (mProjectCallback != null && mProjectCallback.isUsed()) {
-                    mProjectCallback = null;
-                    recompute = true;
-                }
-            }
-
-            if (recompute) {
-                mLayoutCanvas.getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        if (mLayoutEditor.isGraphicalEditorActive()) {
-                            recomputeLayout();
-                        } else {
-                            mNeedsRecompute = true;
-                        }
-                    }
-                });
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java
deleted file mode 100644
index 1d9054c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java
+++ /dev/null
@@ -1,1352 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor.UiEditorActions;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.LayoutCreatorDialog;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiElementEditPart;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiElementsEditPartFactory;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.CopyCutAction;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.PasteAction;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.layoutlib.api.ILayoutBridge;
-import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.api.ILayoutResult;
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IXmlPullParser;
-import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.gef.DefaultEditDomain;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.EditPartViewer;
-import org.eclipse.gef.GraphicalViewer;
-import org.eclipse.gef.SelectionManager;
-import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
-import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
-import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
-import org.eclipse.gef.palette.PaletteRoot;
-import org.eclipse.gef.requests.CreationFactory;
-import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
-import org.eclipse.gef.ui.parts.SelectionSynchronizer;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.ide.IDE;
-import org.eclipse.ui.part.FileEditorInput;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferInt;
-import java.awt.image.Raster;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Graphical layout editor, based on GEF.
- * <p/>
- * To understand GEF: http://www.ibm.com/developerworks/opensource/library/os-gef/
- * <p/>
- * To understand Drag'n'drop: http://www.eclipse.org/articles/Article-Workbench-DND/drag_drop.html
- *
- * @since GLE1
- */
-public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
-        implements IGraphicalLayoutEditor, IConfigListener, ILayoutReloadListener {
-
-
-    /** Reference to the layout editor */
-    private final LayoutEditor mLayoutEditor;
-
-    /** reference to the file being edited. */
-    private IFile mEditedFile;
-
-    private Clipboard mClipboard;
-    private Composite mParent;
-    private ConfigurationComposite mConfigComposite;
-
-    private PaletteRoot mPaletteRoot;
-
-    /** The {@link FolderConfiguration} being edited. */
-    private FolderConfiguration mEditedConfig;
-
-    private Map<String, Map<String, IResourceValue>> mConfiguredFrameworkRes;
-    private Map<String, Map<String, IResourceValue>> mConfiguredProjectRes;
-    private ProjectCallback mProjectCallback;
-    private ILayoutLog mLogger;
-
-    private boolean mNeedsXmlReload = false;
-    private boolean mNeedsRecompute = false;
-
-    /** Listener to update the root node if the target of the file is changed because of a
-     * SDK location change or a project target change */
-    private ITargetChangeListener mTargetListener = new ITargetChangeListener() {
-        public void onProjectTargetChange(IProject changedProject) {
-            if (changedProject == getLayoutEditor().getProject()) {
-                onTargetsLoaded();
-            }
-        }
-
-        public void onTargetsLoaded() {
-            // because the SDK changed we must reset the configured framework resource.
-            mConfiguredFrameworkRes = null;
-
-            mConfigComposite.updateUIFromResources();
-
-            // updateUiFromFramework will reset language/region combo, so we must call
-            // setConfiguration after, or the settext on language/region will be lost.
-            if (mEditedConfig != null) {
-                setConfiguration(mEditedConfig, false /*force*/);
-            }
-
-            // make sure we remove the custom view loader, since its parent class loader is the
-            // bridge class loader.
-            mProjectCallback = null;
-
-            recomputeLayout();
-        }
-    };
-
-    private final Runnable mConditionalRecomputeRunnable = new Runnable() {
-        public void run() {
-            if (mLayoutEditor.isGraphicalEditorActive()) {
-                recomputeLayout();
-            } else {
-                mNeedsRecompute = true;
-            }
-        }
-    };
-
-    private final Runnable mUiUpdateFromResourcesRunnable = new Runnable() {
-        public void run() {
-            mConfigComposite.updateUIFromResources();
-        }
-    };
-
-
-    public GraphicalLayoutEditor(LayoutEditor layoutEditor) {
-        mLayoutEditor = layoutEditor;
-        setEditDomain(new DefaultEditDomain(this));
-        setPartName("Layout");
-
-        AdtPlugin.getDefault().addTargetListener(mTargetListener);
-    }
-
-    // ------------------------------------
-    // Methods overridden from base classes
-    //------------------------------------
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mParent = parent;
-        GridLayout gl;
-
-        mClipboard = new Clipboard(parent.getDisplay());
-
-        parent.setLayout(gl = new GridLayout(1, false));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        // create the top part for the configuration control
-        mConfigComposite = new ConfigurationComposite(this, parent, SWT.NONE);
-
-        // create a new composite that will contain the standard editor controls.
-        Composite editorParent = new Composite(parent, SWT.NONE);
-        editorParent.setLayoutData(new GridData(GridData.FILL_BOTH));
-        editorParent.setLayout(new FillLayout());
-        super.createPartControl(editorParent);
-    }
-
-    @Override
-    public void dispose() {
-        if (mTargetListener != null) {
-            AdtPlugin.getDefault().removeTargetListener(mTargetListener);
-            mTargetListener = null;
-        }
-
-        LayoutReloadMonitor.getMonitor().removeListener(mEditedFile.getProject(), this);
-
-        if (mClipboard != null) {
-            mClipboard.dispose();
-            mClipboard = null;
-        }
-
-        super.dispose();
-    }
-
-    /**
-     * Returns the selection synchronizer object.
-     * The synchronizer can be used to sync the selection of 2 or more EditPartViewers.
-     * <p/>
-     * This is changed from protected to public so that the outline can use it.
-     *
-     * @return the synchronizer
-     */
-    @Override
-    public SelectionSynchronizer getSelectionSynchronizer() {
-        return super.getSelectionSynchronizer();
-    }
-
-    /**
-     * Returns the edit domain.
-     * <p/>
-     * This is changed from protected to public so that the outline can use it.
-     *
-     * @return the edit domain
-     */
-    @Override
-    public DefaultEditDomain getEditDomain() {
-        return super.getEditDomain();
-    }
-
-    /* (non-Javadoc)
-     * Creates the palette root.
-     */
-    @Override
-    protected PaletteRoot getPaletteRoot() {
-        mPaletteRoot = PaletteFactory.createPaletteRoot(mPaletteRoot,
-                mLayoutEditor.getTargetData());
-        return mPaletteRoot;
-    }
-
-    public Clipboard getClipboard() {
-        return mClipboard;
-    }
-
-    /**
-     * Save operation in the Graphical Layout Editor.
-     * <p/>
-     * In our workflow, the model is owned by the Structured XML Editor.
-     * The graphical layout editor just displays it -- thus we don't really
-     * save anything here.
-     * <p/>
-     * This must NOT call the parent editor part. At the contrary, the parent editor
-     * part will call this *after* having done the actual save operation.
-     * <p/>
-     * The only action this editor must do is mark the undo command stack as
-     * being no longer dirty.
-     */
-    @Override
-    public void doSave(IProgressMonitor monitor) {
-        getCommandStack().markSaveLocation();
-        firePropertyChange(PROP_DIRTY);
-    }
-
-    @Override
-    protected void configurePaletteViewer() {
-        super.configurePaletteViewer();
-
-        // Create a drag source listener on an edit part that is a viewer.
-        // What this does is use DND with a TemplateTransfer type which is actually
-        // the PaletteTemplateEntry held in the PaletteRoot.
-        TemplateTransferDragSourceListener dragSource =
-            new TemplateTransferDragSourceListener(getPaletteViewer());
-
-        // Create a drag source on the palette viewer.
-        // See the drag target associated with the GraphicalViewer in configureGraphicalViewer.
-        getPaletteViewer().addDragSourceListener(dragSource);
-    }
-
-    /* (non-javadoc)
-     * Configure the graphical viewer before it receives its contents.
-     */
-    @Override
-    protected void configureGraphicalViewer() {
-        super.configureGraphicalViewer();
-
-        GraphicalViewer viewer = getGraphicalViewer();
-        viewer.setEditPartFactory(new UiElementsEditPartFactory(mParent.getDisplay()));
-        viewer.setRootEditPart(new ScalableFreeformRootEditPart());
-
-        // Disable the following -- we don't drag *from* the GraphicalViewer yet:
-        // viewer.addDragSourceListener(new TemplateTransferDragSourceListener(viewer));
-
-        viewer.addDropTargetListener(new DropListener(viewer));
-    }
-
-    class DropListener extends TemplateTransferDropTargetListener {
-        public DropListener(EditPartViewer viewer) {
-            super(viewer);
-        }
-
-        // TODO explain
-        @Override
-        protected CreationFactory getFactory(final Object template) {
-            return new CreationFactory() {
-                public Object getNewObject() {
-                    // We don't know the newly created EditPart since "creating" new
-                    // elements is done by ElementCreateCommand.execute() directly by
-                    // manipulating the XML elements..
-                    return null;
-                }
-
-                public Object getObjectType() {
-                    return template;
-                }
-
-            };
-        }
-    }
-
-    /* (non-javadoc)
-     * Set the contents of the GraphicalViewer after it has been created.
-     */
-    @Override
-    protected void initializeGraphicalViewer() {
-        GraphicalViewer viewer = getGraphicalViewer();
-        viewer.setContents(getModel());
-
-        IEditorInput input = getEditorInput();
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput)input;
-            mEditedFile = fileInput.getFile();
-
-            mConfigComposite.updateUIFromResources();
-
-            LayoutReloadMonitor.getMonitor().addListener(mEditedFile.getProject(), this);
-        } else {
-            // really this shouldn't happen! Log it in case it happens
-            mEditedFile = null;
-            AdtPlugin.log(IStatus.ERROR, "Input is not of type FileEditorInput: %1$s",
-                    input.toString());
-        }
-    }
-
-    /* (non-javadoc)
-     * Sets the graphicalViewer for this EditorPart.
-     * @param viewer the graphical viewer
-     */
-    @Override
-    protected void setGraphicalViewer(GraphicalViewer viewer) {
-        super.setGraphicalViewer(viewer);
-
-        // TODO: viewer.setKeyHandler()
-        viewer.setContextMenu(createContextMenu(viewer));
-    }
-
-    /**
-     * Used by LayoutEditor.UiEditorActions.selectUiNode to select a new UI Node
-     * created by {@link ElementCreateCommand#execute()}.
-     *
-     * @param uiNodeModel The {@link UiElementNode} to select.
-     */
-    public void selectModel(UiElementNode uiNodeModel) {
-        GraphicalViewer viewer = getGraphicalViewer();
-
-        // Give focus to the graphical viewer (in case the outline has it)
-        viewer.getControl().forceFocus();
-
-        Object editPart = viewer.getEditPartRegistry().get(uiNodeModel);
-
-        if (editPart instanceof EditPart) {
-            viewer.select((EditPart)editPart);
-        }
-    }
-
-
-    //--------------
-    // Local methods
-    //--------------
-
-    public LayoutEditor getLayoutEditor() {
-        return mLayoutEditor;
-    }
-
-    private MenuManager createContextMenu(GraphicalViewer viewer) {
-        MenuManager menuManager = new MenuManager();
-        menuManager.setRemoveAllWhenShown(true);
-        menuManager.addMenuListener(new ActionMenuListener(viewer));
-
-        return menuManager;
-    }
-
-    private class ActionMenuListener implements IMenuListener {
-        private final GraphicalViewer mViewer;
-
-        public ActionMenuListener(GraphicalViewer viewer) {
-            mViewer = viewer;
-        }
-
-        /**
-         * The menu is about to be shown. The menu manager has already been
-         * requested to remove any existing menu item. This method gets the
-         * tree selection and if it is of the appropriate type it re-creates
-         * the necessary actions.
-         */
-       public void menuAboutToShow(IMenuManager manager) {
-           ArrayList<UiElementNode> selected = new ArrayList<UiElementNode>();
-
-           // filter selected items and only keep those we can handle
-           for (Object obj : mViewer.getSelectedEditParts()) {
-               if (obj instanceof UiElementEditPart) {
-                   UiElementEditPart part = (UiElementEditPart) obj;
-                   UiElementNode uiNode = part.getUiNode();
-                   if (uiNode != null) {
-                       selected.add(uiNode);
-                   }
-               }
-           }
-
-           if (selected.size() > 0) {
-               doCreateMenuAction(manager, mViewer, selected);
-           }
-        }
-    }
-
-    private void doCreateMenuAction(IMenuManager manager,
-            final GraphicalViewer viewer,
-            final ArrayList<UiElementNode> selected) {
-        if (selected != null) {
-            boolean hasXml = false;
-            for (UiElementNode uiNode : selected) {
-                if (uiNode.getXmlNode() != null) {
-                    hasXml = true;
-                    break;
-                }
-            }
-
-            if (hasXml) {
-                manager.add(new CopyCutAction(mLayoutEditor, getClipboard(),
-                        null, selected, true /* cut */));
-                manager.add(new CopyCutAction(mLayoutEditor, getClipboard(),
-                        null, selected, false /* cut */));
-
-                // Can't paste with more than one element selected (the selection is the target)
-                if (selected.size() <= 1) {
-                    // Paste is not valid if it would add a second element on a terminal element
-                    // which parent is a document -- an XML document can only have one child. This
-                    // means paste is valid if the current UI node can have children or if the
-                    // parent is not a document.
-                    UiElementNode ui_root = selected.get(0).getUiRoot();
-                    if (ui_root.getDescriptor().hasChildren() ||
-                            !(ui_root.getUiParent() instanceof UiDocumentNode)) {
-                        manager.add(new PasteAction(mLayoutEditor, getClipboard(),
-                                                    selected.get(0)));
-                    }
-                }
-                manager.add(new Separator());
-            }
-        }
-
-        // Append "add" and "remove" actions. They do the same thing as the add/remove
-        // buttons on the side.
-        IconFactory factory = IconFactory.getInstance();
-
-        final UiEditorActions uiActions = mLayoutEditor.getUiEditorActions();
-
-        // "Add" makes sense only if there's 0 or 1 item selected since the
-        // one selected item becomes the target.
-        if (selected == null || selected.size() <= 1) {
-            manager.add(new Action("Add...", factory.getImageDescriptor("add")) { //$NON-NLS-2$
-                @Override
-                public void run() {
-                    UiElementNode node = selected != null && selected.size() > 0 ? selected.get(0)
-                                                                                 : null;
-                    uiActions.doAdd(node, viewer.getControl().getShell());
-                }
-            });
-        }
-
-        if (selected != null) {
-            manager.add(new Action("Remove", factory.getImageDescriptor("delete")) { //$NON-NLS-2$
-                @Override
-                public void run() {
-                    uiActions.doRemove(selected, viewer.getControl().getShell());
-                }
-            });
-
-            manager.add(new Separator());
-
-            manager.add(new Action("Up", factory.getImageDescriptor("up")) { //$NON-NLS-2$
-                @Override
-                public void run() {
-                    uiActions.doUp(selected);
-                }
-            });
-            manager.add(new Action("Down", factory.getImageDescriptor("down")) { //$NON-NLS-2$
-                @Override
-                public void run() {
-                    uiActions.doDown(selected);
-                }
-            });
-        }
-
-    }
-
-    /**
-     * Sets the UI for the edition of a new file.
-     * @param configuration the configuration of the new file.
-     */
-    public void editNewFile(FolderConfiguration configuration) {
-        // update the configuration UI
-        setConfiguration(configuration, true /*force*/);
-
-        // enable the create button if the current and edited config are not equals
-        mConfigComposite.setEnabledCreate(
-                mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false);
-
-        reloadConfigurationUi(false /*notifyListener*/);
-    }
-
-    public Rectangle getBounds() {
-        return mConfigComposite.getScreenBounds();
-    }
-
-    /**
-     * Renders an Android View described by a {@link ViewElementDescriptor}.
-     * <p/>This uses the <code>wrap_content</code> mode for both <code>layout_width</code> and
-     * <code>layout_height</code>, and use the class name for the <code>text</code> attribute.
-     * @param descriptor the descriptor for the class to render.
-     * @return an ImageData containing the rendering or <code>null</code> if rendering failed.
-     */
-    public ImageData renderWidget(ViewElementDescriptor descriptor) {
-        if (mEditedFile == null) {
-            return null;
-        }
-
-        IAndroidTarget target = Sdk.getCurrent().getTarget(mEditedFile.getProject());
-        if (target == null) {
-            return null;
-        }
-
-        AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
-        if (data == null) {
-            return null;
-        }
-
-        LayoutBridge bridge = data.getLayoutBridge();
-
-        if (bridge.bridge != null) { // bridge can never be null.
-            ResourceManager resManager = ResourceManager.getInstance();
-
-            ProjectCallback projectCallback = null;
-            Map<String, Map<String, IResourceValue>> configuredProjectResources = null;
-            if (mEditedFile != null) {
-                ProjectResources projectRes = resManager.getProjectResources(
-                        mEditedFile.getProject());
-                projectCallback = new ProjectCallback(bridge.classLoader,
-                        projectRes, mEditedFile.getProject());
-
-                // get the configured resources for the project
-                // get the resources of the file's project.
-                if (mConfiguredProjectRes == null && projectRes != null) {
-                    // make sure they are loaded
-                    projectRes.loadAll();
-
-                    // get the project resource values based on the current config
-                    mConfiguredProjectRes = projectRes.getConfiguredResources(
-                            mConfigComposite.getCurrentConfig());
-                }
-
-                configuredProjectResources = mConfiguredProjectRes;
-            } else {
-                // we absolutely need a Map of configured project resources.
-                configuredProjectResources = new HashMap<String, Map<String, IResourceValue>>();
-            }
-
-            // get the framework resources
-            Map<String, Map<String, IResourceValue>> frameworkResources =
-                    getConfiguredFrameworkResources();
-
-            if (configuredProjectResources != null && frameworkResources != null) {
-                // get the selected theme
-                String theme = mConfigComposite.getTheme();
-                if (theme != null) {
-                    // Render a single object as described by the ViewElementDescriptor.
-                    WidgetPullParser parser = new WidgetPullParser(descriptor);
-                    ILayoutResult result = computeLayout(bridge, parser,
-                            null /* projectKey */,
-                            1 /* width */, 1 /* height */, true /* renderFullSize */,
-                            160 /*density*/, 160.f /*xdpi*/, 160.f /*ydpi*/, theme,
-                            mConfigComposite.isProjectTheme(),
-                            configuredProjectResources, frameworkResources, projectCallback,
-                            null /* logger */);
-
-                    // update the UiElementNode with the layout info.
-                    if (result.getSuccess() == ILayoutResult.SUCCESS) {
-                        BufferedImage largeImage = result.getImage();
-
-                        // we need to resize it to the actual widget size, and convert it into
-                        // an SWT image object.
-                        int width = result.getRootView().getRight();
-                        int height = result.getRootView().getBottom();
-                        Raster raster = largeImage.getData(new java.awt.Rectangle(width, height));
-                        int[] imageDataBuffer = ((DataBufferInt)raster.getDataBuffer()).getData();
-
-                        ImageData imageData = new ImageData(width, height, 32,
-                                new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF));
-
-                        imageData.setPixels(0, 0, imageDataBuffer.length, imageDataBuffer, 0);
-
-                        return imageData;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Reloads this editor, by getting the new model from the {@link LayoutEditor}.
-     */
-    public void reloadEditor() {
-        GraphicalViewer viewer = getGraphicalViewer();
-        viewer.setContents(getModel());
-
-        IEditorInput input = mLayoutEditor.getEditorInput();
-        setInput(input);
-
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput)input;
-            mEditedFile = fileInput.getFile();
-        } else {
-            // really this shouldn't happen! Log it in case it happens
-            mEditedFile = null;
-            AdtPlugin.log(IStatus.ERROR, "Input is not of type FileEditorInput: %1$s",
-                    input.toString());
-        }
-    }
-
-    /**
-     * Callback for XML model changed. Only update/recompute the layout if the editor is visible
-     */
-    public void onXmlModelChanged() {
-        if (mLayoutEditor.isGraphicalEditorActive()) {
-            doXmlReload(true /* force */);
-            recomputeLayout();
-        } else {
-            mNeedsXmlReload = true;
-        }
-    }
-
-    /**
-     * Actually performs the XML reload
-     * @see #onXmlModelChanged()
-     */
-    private void doXmlReload(boolean force) {
-        if (force || mNeedsXmlReload) {
-            GraphicalViewer viewer = getGraphicalViewer();
-
-            // try to preserve the selection before changing the content
-            SelectionManager selMan = viewer.getSelectionManager();
-            ISelection selection = selMan.getSelection();
-
-            try {
-                viewer.setContents(getModel());
-            } finally {
-                selMan.setSelection(selection);
-            }
-
-            mNeedsXmlReload = false;
-        }
-    }
-
-    /**
-     * Update the UI controls state with a given {@link FolderConfiguration}.
-     * <p/>If <var>force</var> is set to <code>true</code> the UI will be changed to exactly reflect
-     * <var>config</var>, otherwise, if a qualifier is not present in <var>config</var>,
-     * the UI control is not modified. However if the value in the control is not the default value,
-     * a warning icon is shown.
-     * @param config The {@link FolderConfiguration} to set.
-     * @param force Whether the UI should be changed to exactly match the received configuration.
-     */
-    void setConfiguration(FolderConfiguration config, boolean force) {
-        mEditedConfig = config;
-        mConfiguredFrameworkRes = mConfiguredProjectRes = null;
-
-        mConfigComposite.setConfiguration(config, force);
-
-    }
-
-
-    public UiDocumentNode getModel() {
-        return mLayoutEditor.getUiRootNode();
-    }
-
-    public void reloadPalette() {
-        PaletteFactory.createPaletteRoot(mPaletteRoot, mLayoutEditor.getTargetData());
-    }
-
-    public void reloadConfigurationUi(boolean notifyListener) {
-        // enable the clipping button if it's supported.
-        Sdk currentSdk = Sdk.getCurrent();
-        if (currentSdk != null) {
-            IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject());
-            AndroidTargetData data = currentSdk.getTargetData(target);
-            if (data != null) {
-                LayoutBridge bridge = data.getLayoutBridge();
-                mConfigComposite.reloadDevices(notifyListener);
-                mConfigComposite.setClippingSupport(bridge.apiLevel >= 4);
-            }
-        }
-    }
-
-    /**
-     * Looks for a file matching the new {@link FolderConfiguration} and attempts to open it.
-     * <p/>If there is no match, notify the user.
-     */
-    public void onConfigurationChange() {
-        mConfiguredFrameworkRes = mConfiguredProjectRes = null;
-
-        if (mEditedFile == null || mEditedConfig == null) {
-            return;
-        }
-
-        // get the resources of the file's project.
-        ProjectResources resources = ResourceManager.getInstance().getProjectResources(
-                mEditedFile.getProject());
-
-        // from the resources, look for a matching file
-        ResourceFile match = null;
-        if (resources != null) {
-            match = resources.getMatchingFile(mEditedFile.getName(),
-                                              ResourceFolderType.LAYOUT,
-                                              mConfigComposite.getCurrentConfig());
-        }
-
-        if (match != null) {
-            if (match.getFile().equals(mEditedFile) == false) {
-                try {
-                    IDE.openEditor(
-                            getSite().getWorkbenchWindow().getActivePage(),
-                            match.getFile().getIFile());
-
-                    // we're done!
-                    return;
-                } catch (PartInitException e) {
-                    // FIXME: do something!
-                }
-            }
-
-            // at this point, we have not opened a new file.
-
-            // update the configuration icons with the new edited config.
-            setConfiguration(mEditedConfig, false /*force*/);
-
-            // enable the create button if the current and edited config are not equals
-            mConfigComposite.setEnabledCreate(
-                    mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false);
-
-            // Even though the layout doesn't change, the config changed, and referenced
-            // resources need to be updated.
-            recomputeLayout();
-        } else {
-            // enable the Create button
-            mConfigComposite.setEnabledCreate(true);
-
-            // display the error.
-            FolderConfiguration currentConfig = mConfigComposite.getCurrentConfig();
-            String message = String.format(
-                    "No resources match the configuration\n \n\t%1$s\n \nChange the configuration or create:\n \n\tres/%2$s/%3$s\n \nYou can also click the 'Create' button above.",
-                    currentConfig.toDisplayString(),
-                    currentConfig.getFolderName(ResourceFolderType.LAYOUT,
-                            Sdk.getCurrent().getTarget(mEditedFile.getProject())),
-                    mEditedFile.getName());
-            showErrorInEditor(message);
-        }
-    }
-
-    public void onThemeChange() {
-        recomputeLayout();
-    }
-
-    public void OnClippingChange() {
-        recomputeLayout();
-    }
-
-
-    public void onCreate() {
-        LayoutCreatorDialog dialog = new LayoutCreatorDialog(mParent.getShell(),
-                mEditedFile.getName(),
-                Sdk.getCurrent().getTarget(mEditedFile.getProject()),
-                mConfigComposite.getCurrentConfig());
-        if (dialog.open() == Dialog.OK) {
-            final FolderConfiguration config = new FolderConfiguration();
-            dialog.getConfiguration(config);
-
-            createAlternateLayout(config);
-        }
-    }
-
-    /**
-     * Recomputes the layout with the help of layoutlib.
-     */
-    public void recomputeLayout() {
-        doXmlReload(false /* force */);
-        try {
-            // check that the resource exists. If the file is opened but the project is closed
-            // or deleted for some reason (changed from outside of eclipse), then this will
-            // return false;
-            if (mEditedFile.exists() == false) {
-                String message = String.format("Resource '%1$s' does not exist.",
-                        mEditedFile.getFullPath().toString());
-
-                showErrorInEditor(message);
-
-                return;
-            }
-
-            IProject iProject = mEditedFile.getProject();
-
-            if (mEditedFile.isSynchronized(IResource.DEPTH_ZERO) == false) {
-                String message = String.format("%1$s is out of sync. Please refresh.",
-                        mEditedFile.getName());
-
-                showErrorInEditor(message);
-
-                // also print it in the error console.
-                AdtPlugin.printErrorToConsole(iProject.getName(), message);
-                return;
-            }
-
-            Sdk currentSdk = Sdk.getCurrent();
-            if (currentSdk != null) {
-                IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject());
-                if (target == null) {
-                    showErrorInEditor("The project target is not set.");
-                    return;
-                }
-
-                AndroidTargetData data = currentSdk.getTargetData(target);
-                if (data == null) {
-                    // It can happen that the workspace refreshes while the SDK is loading its
-                    // data, which could trigger a redraw of the opened layout if some resources
-                    // changed while Eclipse is closed.
-                    // In this case data could be null, but this is not an error.
-                    // We can just silently return, as all the opened editors are automatically
-                    // refreshed once the SDK finishes loading.
-                    if (AdtPlugin.getDefault().getSdkLoadStatus() != LoadStatus.LOADING) {
-                        showErrorInEditor(String.format(
-                                "The project target (%s) was not properly loaded.",
-                                target.getName()));
-                    }
-                    return;
-                }
-
-                // check there is actually a model (maybe the file is empty).
-                UiDocumentNode model = getModel();
-
-                if (model.getUiChildren().size() == 0) {
-                    showErrorInEditor("No Xml content. Go to the Outline view and add nodes.");
-                    return;
-                }
-
-                LayoutBridge bridge = data.getLayoutBridge();
-
-                if (bridge.bridge != null) { // bridge can never be null.
-                    ResourceManager resManager = ResourceManager.getInstance();
-
-                    ProjectResources projectRes = resManager.getProjectResources(iProject);
-                    if (projectRes == null) {
-                        return;
-                    }
-
-                    // get the resources of the file's project.
-                    Map<String, Map<String, IResourceValue>> configuredProjectRes =
-                        getConfiguredProjectResources();
-
-                    // get the framework resources
-                    Map<String, Map<String, IResourceValue>> frameworkResources =
-                        getConfiguredFrameworkResources();
-
-                    if (configuredProjectRes != null && frameworkResources != null) {
-                        if (mProjectCallback == null) {
-                            mProjectCallback = new ProjectCallback(
-                                    bridge.classLoader, projectRes, iProject);
-                        }
-
-                        if (mLogger == null) {
-                            mLogger = new ILayoutLog() {
-                                public void error(String message) {
-                                    AdtPlugin.printErrorToConsole(mEditedFile.getName(), message);
-                                }
-
-                                public void error(Throwable error) {
-                                    String message = error.getMessage();
-                                    if (message == null) {
-                                        message = error.getClass().getName();
-                                    }
-
-                                    PrintStream ps = new PrintStream(AdtPlugin.getErrorStream());
-                                    error.printStackTrace(ps);
-                                }
-
-                                public void warning(String message) {
-                                    AdtPlugin.printToConsole(mEditedFile.getName(), message);
-                                }
-                            };
-                        }
-
-                        // get the selected theme
-                        String theme = mConfigComposite.getTheme();
-                        if (theme != null) {
-
-                            // Compute the layout
-                            UiElementPullParser parser = new UiElementPullParser(getModel());
-                            Rectangle rect = getBounds();
-                            boolean isProjectTheme = mConfigComposite.isProjectTheme();
-
-                            int density = mConfigComposite.getDensity().getDpiValue();
-                            float xdpi = mConfigComposite.getXDpi();
-                            float ydpi = mConfigComposite.getYDpi();
-
-                            ILayoutResult result = computeLayout(bridge, parser,
-                                    iProject /* projectKey */,
-                                    rect.width, rect.height, !mConfigComposite.getClipping(),
-                                    density, xdpi, ydpi,
-                                    theme, isProjectTheme,
-                                    configuredProjectRes, frameworkResources, mProjectCallback,
-                                    mLogger);
-
-                            // update the UiElementNode with the layout info.
-                            if (result.getSuccess() == ILayoutResult.SUCCESS) {
-                                model.setEditData(result.getImage());
-
-                                updateNodeWithBounds(result.getRootView());
-                            } else {
-                                String message = result.getErrorMessage();
-
-                                // Reset the edit data for all the nodes.
-                                resetNodeBounds(model);
-
-                                if (message != null) {
-                                    // set the error in the top element.
-                                    model.setEditData(message);
-                                }
-                            }
-
-                            model.refreshUi();
-                        }
-                    }
-                } else {
-                    // SDK is loaded but not the layout library!
-                    String message = null;
-                    // check whether the bridge managed to load, or not
-                    if (bridge.status == LoadStatus.LOADING) {
-                        message = String.format(
-                                "Eclipse is loading framework information and the Layout library from the SDK folder.\n%1$s will refresh automatically once the process is finished.",
-                                mEditedFile.getName());
-                    } else {
-                        message = String.format("Eclipse failed to load the framework information and the Layout library!");
-                    }
-                    showErrorInEditor(message);
-                }
-            } else {
-                String message = String.format(
-                        "Eclipse is loading the SDK.\n%1$s will refresh automatically once the process is finished.",
-                        mEditedFile.getName());
-
-                showErrorInEditor(message);
-            }
-        } finally {
-            // no matter the result, we are done doing the recompute based on the latest
-            // resource/code change.
-            mNeedsRecompute = false;
-        }
-    }
-
-    private void showErrorInEditor(String message) {
-        // get the model to display the error directly in the editor
-        UiDocumentNode model = getModel();
-
-        // Reset the edit data for all the nodes.
-        resetNodeBounds(model);
-
-        if (message != null) {
-            // set the error in the top element.
-            model.setEditData(message);
-        }
-
-        model.refreshUi();
-    }
-
-    private void resetNodeBounds(UiElementNode node) {
-        node.setEditData(null);
-
-        List<UiElementNode> children = node.getUiChildren();
-        for (UiElementNode child : children) {
-            resetNodeBounds(child);
-        }
-    }
-
-    private void updateNodeWithBounds(ILayoutViewInfo r) {
-        if (r != null) {
-            // update the node itself, as the viewKey is the XML node in this implementation.
-            Object viewKey = r.getViewKey();
-            if (viewKey instanceof UiElementNode) {
-                Rectangle bounds = new Rectangle(r.getLeft(), r.getTop(),
-                        r.getRight()-r.getLeft(), r.getBottom() - r.getTop());
-
-                ((UiElementNode)viewKey).setEditData(bounds);
-            }
-
-            // and then its children.
-            ILayoutViewInfo[] children = r.getChildren();
-            if (children != null) {
-                for (ILayoutViewInfo child : children) {
-                    updateNodeWithBounds(child);
-                }
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.layout.LayoutReloadMonitor.ILayoutReloadListener#reloadLayout(boolean, boolean, boolean)
-     *
-     * Called when the file changes triggered a redraw of the layout
-     */
-    public void reloadLayout(boolean codeChange, boolean rChange, boolean resChange) {
-        boolean recompute = rChange;
-
-        if (resChange) {
-            recompute = true;
-
-            // TODO: differentiate between single and multi resource file changed, and whether the resource change affects the cache.
-
-            // force a reparse in case a value XML file changed.
-            mConfiguredProjectRes = null;
-
-            // clear the cache in the bridge in case a bitmap/9-patch changed.
-            IAndroidTarget target = Sdk.getCurrent().getTarget(mEditedFile.getProject());
-            if (target != null) {
-
-                AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
-                if (data != null) {
-                    LayoutBridge bridge = data.getLayoutBridge();
-
-                    if (bridge.bridge != null) {
-                        bridge.bridge.clearCaches(mEditedFile.getProject());
-                    }
-                }
-            }
-
-            mParent.getDisplay().asyncExec(mUiUpdateFromResourcesRunnable);
-        }
-
-        if (codeChange) {
-            // only recompute if the custom view loader was used to load some code.
-            if (mProjectCallback != null && mProjectCallback.isUsed()) {
-                mProjectCallback = null;
-                recompute = true;
-            }
-        }
-
-        if (recompute) {
-            mParent.getDisplay().asyncExec(mConditionalRecomputeRunnable);
-        }
-    }
-
-    /**
-     * Responds to a page change that made the Graphical editor page the activated page.
-     */
-    public void activated() {
-        if (mNeedsRecompute || mNeedsXmlReload) {
-            recomputeLayout();
-        }
-    }
-
-    /**
-     * Responds to a page change that made the Graphical editor page the deactivated page
-     */
-    public void deactivated() {
-        // nothing to be done here for now.
-    }
-
-    public Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources() {
-        if (mConfiguredFrameworkRes == null) {
-            ProjectResources frameworkRes = getFrameworkResources();
-
-            if (frameworkRes == null) {
-                AdtPlugin.log(IStatus.ERROR, "Failed to get ProjectResource for the framework");
-            } else {
-                // get the framework resource values based on the current config
-                mConfiguredFrameworkRes = frameworkRes.getConfiguredResources(
-                        mConfigComposite.getCurrentConfig());
-            }
-        }
-
-        return mConfiguredFrameworkRes;
-    }
-
-    public Map<String, Map<String, IResourceValue>> getConfiguredProjectResources() {
-        if (mConfiguredProjectRes == null) {
-            ProjectResources project = getProjectResources();
-
-            // make sure they are loaded
-            project.loadAll();
-
-            // get the project resource values based on the current config
-            mConfiguredProjectRes = project.getConfiguredResources(
-                    mConfigComposite.getCurrentConfig());
-        }
-
-        return mConfiguredProjectRes;
-    }
-
-    /**
-     * Returns a {@link ProjectResources} for the framework resources.
-     * @return the framework resources or null if not found.
-     */
-    public ProjectResources getFrameworkResources() {
-        if (mEditedFile != null) {
-            Sdk currentSdk = Sdk.getCurrent();
-            if (currentSdk != null) {
-                IAndroidTarget target = currentSdk.getTarget(mEditedFile.getProject());
-
-                if (target != null) {
-                    AndroidTargetData data = currentSdk.getTargetData(target);
-
-                    if (data != null) {
-                        return data.getFrameworkResources();
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public ProjectResources getProjectResources() {
-        if (mEditedFile != null) {
-            ResourceManager manager = ResourceManager.getInstance();
-            return manager.getProjectResources(mEditedFile.getProject());
-        }
-
-        return null;
-    }
-
-    /**
-     * Creates a new layout file from the specified {@link FolderConfiguration}.
-     */
-    private void createAlternateLayout(final FolderConfiguration config) {
-        new Job("Create Alternate Resource") {
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                // get the folder name
-                String folderName = config.getFolderName(ResourceFolderType.LAYOUT,
-                        Sdk.getCurrent().getTarget(mEditedFile.getProject()));
-                try {
-
-                    // look to see if it exists.
-                    // get the res folder
-                    IFolder res = (IFolder)mEditedFile.getParent().getParent();
-                    String path = res.getLocation().toOSString();
-
-                    File newLayoutFolder = new File(path + File.separator + folderName);
-                    if (newLayoutFolder.isFile()) {
-                        // this should not happen since aapt would have complained
-                        // before, but if one disable the automatic build, this could
-                        // happen.
-                        String message = String.format("File 'res/%1$s' is in the way!",
-                                folderName);
-
-                        AdtPlugin.displayError("Layout Creation", message);
-
-                        return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, message);
-                    } else if (newLayoutFolder.exists() == false) {
-                        // create it.
-                        newLayoutFolder.mkdir();
-                    }
-
-                    // now create the file
-                    File newLayoutFile = new File(newLayoutFolder.getAbsolutePath() +
-                                File.separator + mEditedFile.getName());
-
-                    newLayoutFile.createNewFile();
-
-                    InputStream input = mEditedFile.getContents();
-
-                    FileOutputStream fos = new FileOutputStream(newLayoutFile);
-
-                    byte[] data = new byte[512];
-                    int count;
-                    while ((count = input.read(data)) != -1) {
-                        fos.write(data, 0, count);
-                    }
-
-                    input.close();
-                    fos.close();
-
-                    // refreshes the res folder to show up the new
-                    // layout folder (if needed) and the file.
-                    // We use a progress monitor to catch the end of the refresh
-                    // to trigger the edit of the new file.
-                    res.refreshLocal(IResource.DEPTH_INFINITE, new IProgressMonitor() {
-                        public void done() {
-                            mParent.getDisplay().asyncExec(new Runnable() {
-                                public void run() {
-                                    onConfigurationChange();
-                                }
-                            });
-                        }
-
-                        public void beginTask(String name, int totalWork) {
-                            // pass
-                        }
-
-                        public void internalWorked(double work) {
-                            // pass
-                        }
-
-                        public boolean isCanceled() {
-                            // pass
-                            return false;
-                        }
-
-                        public void setCanceled(boolean value) {
-                            // pass
-                        }
-
-                        public void setTaskName(String name) {
-                            // pass
-                        }
-
-                        public void subTask(String name) {
-                            // pass
-                        }
-
-                        public void worked(int work) {
-                            // pass
-                        }
-                    });
-                } catch (IOException e2) {
-                    String message = String.format(
-                            "Failed to create File 'res/%1$s/%2$s' : %3$s",
-                            folderName, mEditedFile.getName(), e2.getMessage());
-
-                    AdtPlugin.displayError("Layout Creation", message);
-
-                    return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                            message, e2);
-                } catch (CoreException e2) {
-                    String message = String.format(
-                            "Failed to create File 'res/%1$s/%2$s' : %3$s",
-                            folderName, mEditedFile.getName(), e2.getMessage());
-
-                    AdtPlugin.displayError("Layout Creation", message);
-
-                    return e2.getStatus();
-                }
-
-                return Status.OK_STATUS;
-
-            }
-        }.schedule();
-    }
-
-    /**
-     * Computes a layout by calling the correct computeLayout method of ILayoutBridge based on
-     * the implementation API level.
-     */
-    @SuppressWarnings("deprecation")
-    private static ILayoutResult computeLayout(LayoutBridge bridge,
-            IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, boolean renderFullSize,
-            int density, float xdpi, float ydpi,
-            String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback projectCallback, ILayoutLog logger) {
-
-        if (bridge.apiLevel >= ILayoutBridge.API_CURRENT) {
-            // newest API with support for "render full height"
-            // TODO: link boolean to UI.
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, renderFullSize,
-                    density, xdpi, ydpi,
-                    themeName, isProjectTheme,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        } else if (bridge.apiLevel == 3) {
-            // newer api with density support.
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, density, xdpi, ydpi,
-                    themeName, isProjectTheme,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        } else if (bridge.apiLevel == 2) {
-            // api with boolean for separation of project/framework theme
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, themeName, isProjectTheme,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        } else {
-            // oldest api with no density/dpi, and project theme boolean mixed
-            // into the theme name.
-
-            // change the string if it's a custom theme to make sure we can
-            // differentiate them
-            if (isProjectTheme) {
-                themeName = "*" + themeName; //$NON-NLS-1$
-            }
-
-            return bridge.bridge.computeLayout(layoutDescription,
-                    projectKey, screenWidth, screenHeight, themeName,
-                    projectResources, frameworkResources, projectCallback,
-                    logger);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/IGraphicalLayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/IGraphicalLayoutEditor.java
deleted file mode 100755
index 5816af6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/IGraphicalLayoutEditor.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-
-import org.eclipse.gef.ui.parts.SelectionSynchronizer;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.ui.IEditorPart;
-
-/**
- * Interface defining what {@link LayoutEditor} expects from a GraphicalLayoutEditor part.
- *
- * @since GLE2
- */
-/*package*/ interface IGraphicalLayoutEditor extends IEditorPart {
-
-    /**
-     * Sets the UI for the edition of a new file.
-     * @param configuration the configuration of the new file.
-     */
-    abstract void editNewFile(FolderConfiguration configuration);
-
-    /**
-     * Reloads this editor, by getting the new model from the {@link LayoutEditor}.
-     */
-    abstract void reloadEditor();
-
-    /**
-     * Callback for XML model changed. Only update/recompute the layout if the editor is visible
-     */
-    abstract void onXmlModelChanged();
-
-    /**
-     * Responds to a page change that made the Graphical editor page the activated page.
-     */
-    abstract void activated();
-
-    /**
-     * Responds to a page change that made the Graphical editor page the deactivated page
-     */
-    abstract void deactivated();
-
-    /**
-     * Used by LayoutEditor.UiEditorActions.selectUiNode to select a new UI Node
-     * created by  {@link ElementCreateCommand#execute()}.
-     *
-     * @param uiNodeModel The {@link UiElementNode} to select.
-     */
-    abstract void selectModel(UiElementNode uiNodeModel);
-
-    /**
-     * Returns the selection synchronizer object.
-     * The synchronizer can be used to sync the selection of 2 or more EditPartViewers.
-     */
-    abstract public SelectionSynchronizer getSelectionSynchronizer();
-
-    abstract void reloadPalette();
-
-    abstract void recomputeLayout();
-
-    abstract UiDocumentNode getModel();
-
-    abstract LayoutEditor getLayoutEditor();
-
-    abstract Clipboard getClipboard();
-
-    abstract void reloadConfigurationUi(boolean notifyListener);
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCanvas.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCanvas.java
deleted file mode 100755
index a0de610..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCanvas.java
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.layoutlib.api.ILayoutResult;
-import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontMetrics;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferInt;
-import java.awt.image.Raster;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * Displays the image rendered by the {@link GraphicalEditorPart} and handles
- * the interaction with the widgets.
- * <p/>
- *
- * @since GLE2
- *
- * TODO list:
- * - gray on error, keep select but disable d'n'd.
- * - make sure it is scrollable (Canvas derives from Scrollable, so prolly just setting bounds.)
- * - handle drop target (from palette).
- * - handle drag'n'drop (internal, for moving/duplicating).
- * - handle context menu (depending on selection).
- * - selection synchronization with the outline (both ways).
- */
-public class LayoutCanvas extends Canvas {
-
-    /**
-     * Margin around the rendered image. Should be enough space to display the layout
-     * width and height pseudo widgets.
-     */
-    private static final int IMAGE_MARGIN = 5;
-    /**
-     * Minimal size of the selection, in case an empty view or layout is selected.
-     */
-    private static final int SELECTION_MIN_SIZE = 6;
-
-    private ILayoutResult mLastValidResult;
-    private ViewInfo mLastValidViewInfoRoot;
-
-    /** Current background image. Null when there's no image. */
-    private Image mImage;
-
-    private final LinkedList<Selection> mSelections = new LinkedList<Selection>();
-
-    /** Selection border color. Do not dispose, it's a system color. */
-    private Color mSelectionFgColor;
-
-    /** Selection name font. Do not dispose, it's a system font. */
-    private Font mSelectionFont;
-
-    /** Pixel height of the font displaying the selection name. Initially set to 0 and only
-     * initialized in onPaint() when we have a GC. */
-    private int mSelectionFontHeight;
-
-    /** Current hover view info. Null when no mouse hover. */
-    private ViewInfo mHoverViewInfo;
-
-    /** Current mouse hover border rectangle. Null when there's no mouse hover. */
-    private Rectangle mHoverRect;
-
-    /** Hover border color. Must be disposed, it's NOT a system color. */
-    private Color mHoverFgColor;
-
-    private AlternateSelection mAltSelection;
-
-    /**
-     * True when the last {@link #setResult(ILayoutResult)} provided a valid {@link ILayoutResult}
-     * in which case it is also available in {@link #mLastValidResult}.
-     * When false this means the canvas is displaying an out-dated result image & bounds and some
-     * features should be disabled accordingly such a drag'n'drop.
-     */
-    private boolean mIsResultValid;
-
-
-    public LayoutCanvas(Composite parent, int style) {
-        super(parent, style | SWT.DOUBLE_BUFFERED);
-
-        Display d = getDisplay();
-        mSelectionFgColor = d.getSystemColor(SWT.COLOR_RED);
-        mHoverFgColor     = new Color(d, 0xFF, 0x99, 0x00); // orange
-        mSelectionFont    = d.getSystemFont();
-
-        addPaintListener(new PaintListener() {
-            public void paintControl(PaintEvent e) {
-                onPaint(e);
-            }
-        });
-
-        addMouseMoveListener(new MouseMoveListener() {
-            public void mouseMove(MouseEvent e) {
-                onMouseMove(e);
-            }
-        });
-
-        addMouseListener(new MouseListener() {
-            public void mouseUp(MouseEvent e) {
-                onMouseUp(e);
-            }
-
-            public void mouseDown(MouseEvent e) {
-                onMouseDown(e);
-            }
-
-            public void mouseDoubleClick(MouseEvent e) {
-                onDoubleClick(e);
-            }
-        });
-    }
-
-    @Override
-    public void dispose() {
-        super.dispose();
-    }
-
-    /**
-     * Sets the result of the layout rendering. The result object indicates if the layout
-     * rendering succeeded. If it did, it contains a bitmap and the objects rectangles.
-     *
-     * Implementation detail: the bridge's computeLayout() method already returns a newly
-     * allocated ILayourResult. That means we can keep this result and hold on to it
-     * when it is valid.
-     *
-     * @param result The new rendering result, either valid or not.
-     */
-    public void setResult(ILayoutResult result) {
-
-        // disable any hover
-        mHoverRect = null;
-
-        mIsResultValid = (result != null && result.getSuccess() == ILayoutResult.SUCCESS);
-
-        if (mIsResultValid && result != null) {
-            mLastValidResult = result;
-            mLastValidViewInfoRoot = new ViewInfo(result.getRootView());
-            setImage(result.getImage());
-
-            // Check if the selection is still the same (based on the object keys)
-            // and eventually recompute their bounds.
-            for (ListIterator<Selection> it = mSelections.listIterator(); it.hasNext(); ) {
-                Selection s = it.next();
-
-                // Check the if the selected object still exists
-                Object key = s.getViewInfo().getKey();
-                ViewInfo vi = findViewInfoKey(key, mLastValidViewInfoRoot);
-
-                // Remove the previous selection -- if the selected object still exists
-                // we need to recompute its bounds in case it moved so we'll insert a new one
-                // at the same place.
-                it.remove();
-                if (vi != null) {
-                    it.add(new Selection(vi));
-                }
-            }
-
-            // remove the current alternate selection views
-            mAltSelection = null;
-        }
-
-        redraw();
-    }
-
-    //---
-
-    /**
-     * Sets the image of the last *successful* rendering.
-     * Converts the AWT image into an SWT image.
-     */
-    private void setImage(BufferedImage awtImage) {
-        int width = awtImage.getWidth();
-        int height = awtImage.getHeight();
-
-        Raster raster = awtImage.getData(new java.awt.Rectangle(width, height));
-        int[] imageDataBuffer = ((DataBufferInt)raster.getDataBuffer()).getData();
-
-        ImageData imageData = new ImageData(width, height, 32,
-                new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF));
-
-        imageData.setPixels(0, 0, imageDataBuffer.length, imageDataBuffer, 0);
-
-        mImage = new Image(getDisplay(), imageData);
-    }
-
-    /**
-     * Paints the canvas in response to paint events.
-     */
-    private void onPaint(PaintEvent e) {
-        GC gc = e.gc;
-
-        if (mImage != null) {
-            if (!mIsResultValid) {
-                gc.setAlpha(128);
-            }
-
-            gc.drawImage(mImage, IMAGE_MARGIN, IMAGE_MARGIN);
-
-            if (!mIsResultValid) {
-                gc.setAlpha(255);
-            }
-        }
-
-        if (mHoverRect != null) {
-            gc.setForeground(mHoverFgColor);
-            gc.setLineStyle(SWT.LINE_DOT);
-            gc.drawRectangle(mHoverRect);
-        }
-
-        // initialize the selection font height once. We need the GC to do that.
-        if (mSelectionFontHeight == 0) {
-            gc.setFont(mSelectionFont);
-            FontMetrics fm = gc.getFontMetrics();
-            mSelectionFontHeight = fm.getHeight();
-        }
-
-        for (Selection s : mSelections) {
-            drawSelection(gc, s);
-        }
-    }
-
-    private void drawSelection(GC gc, Selection s) {
-        Rectangle r = s.getRect();
-
-        gc.setForeground(mSelectionFgColor);
-        gc.setLineStyle(SWT.LINE_SOLID);
-        gc.drawRectangle(s.mRect);
-
-        String name = s.getName();
-
-        if (name != null) {
-            int xs = r.x + 2;
-            int ys = r.y - mSelectionFontHeight;
-            if (ys < 0) {
-                ys = r.y + r.height;
-            }
-            gc.drawString(name, xs, ys, true /*transparent*/);
-        }
-    }
-
-    /**
-     * Hover on top of a known child.
-     */
-    private void onMouseMove(MouseEvent e) {
-        if (mLastValidResult != null) {
-            ViewInfo root = mLastValidViewInfoRoot;
-            ViewInfo vi = findViewInfoAt(e.x - IMAGE_MARGIN, e.y - IMAGE_MARGIN, root);
-
-            // We don't hover on the root since it's not a widget per see and it is always there.
-            if (vi == root) {
-                vi = null;
-            }
-
-            boolean needsUpdate = vi != mHoverViewInfo;
-            mHoverViewInfo = vi;
-
-            if (vi == null) {
-                mHoverRect = null;
-            } else {
-                Rectangle r = vi.getSelectionRect();
-                mHoverRect = new Rectangle(r.x + IMAGE_MARGIN, r.y + IMAGE_MARGIN,
-                                           r.width, r.height);
-            }
-
-            if (needsUpdate) {
-                redraw();
-            }
-        }
-    }
-
-    private void onMouseDown(MouseEvent e) {
-        // pass, not used yet.
-    }
-
-    /**
-     * Performs selection on mouse up (not mouse down).
-     * <p/>
-     * Shift key is used to toggle in multi-selection.
-     * Alt key is used to cycle selection through objects at the same level than the one
-     * pointed at (i.e. click on an object then alt-click to cycle).
-     */
-    private void onMouseUp(MouseEvent e) {
-        if (mLastValidResult != null) {
-
-            boolean isShift = (e.stateMask & SWT.SHIFT) != 0;
-            boolean isAlt   = (e.stateMask & SWT.ALT)   != 0;
-
-            int x = e.x - IMAGE_MARGIN;
-            int y = e.y - IMAGE_MARGIN;
-            ViewInfo vi = findViewInfoAt(x, y, mLastValidViewInfoRoot);
-
-            if (isShift && !isAlt) {
-                // Case where shift is pressed: pointed object is toggled.
-
-                // reset alternate selection if any
-                mAltSelection = null;
-
-                // If nothing has been found at the cursor, assume it might be a user error
-                // and avoid clearing the existing selection.
-
-                if (vi != null) {
-                    // toggle this selection on-off: remove it if already selected
-                    if (deselect(vi)) {
-                        redraw();
-                        return;
-                    }
-
-                    // otherwise add it.
-                    mSelections.add(new Selection(vi));
-                    redraw();
-                }
-
-            } else if (isAlt) {
-                // Case where alt is pressed: select or cycle the object pointed at.
-
-                // Note: if shift and alt are pressed, shift is ignored. The alternate selection
-                // mechanism does not reset the current multiple selection unless they intersect.
-
-                // We need to remember the "origin" of the alternate selection, to be
-                // able to continue cycling through it later. If there's no alternate selection,
-                // create one. If there's one but not for the same origin object, create a new
-                // one too.
-                if (mAltSelection == null || mAltSelection.getOriginatingView() != vi) {
-                    mAltSelection = new AlternateSelection(vi, findAltViewInfoAt(
-                                                    x, y, mLastValidViewInfoRoot, null));
-
-                    // deselect them all, in case they were partially selected
-                    deselectAll(mAltSelection.getAltViews());
-
-                    // select the current one
-                    ViewInfo vi2 = mAltSelection.getCurrent();
-                    if (vi2 != null) {
-                        mSelections.addFirst(new Selection(vi2));
-                    }
-                } else {
-                    // We're trying to cycle through the current alternate selection.
-                    // First remove the current object.
-                    ViewInfo vi2 = mAltSelection.getCurrent();
-                    deselect(vi2);
-
-                    // Now select the next one.
-                    vi2 = mAltSelection.getNext();
-                    if (vi2 != null) {
-                        mSelections.addFirst(new Selection(vi2));
-                    }
-                }
-                redraw();
-
-            } else {
-                // Case where no modifier is pressed: either select or reset the selection.
-
-                // reset alternate selection if any
-                mAltSelection = null;
-
-                // reset (multi)selection if any
-                if (mSelections.size() > 0) {
-                    if (mSelections.size() == 1 && mSelections.getFirst().getViewInfo() == vi) {
-                        // Selection remains the same, don't touch it.
-                        return;
-                    }
-                    mSelections.clear();
-                }
-
-                if (vi != null) {
-                    mSelections.add(new Selection(vi));
-                }
-                redraw();
-            }
-        }
-    }
-
-    /** Deselects a view info. Returns true if the object was actually selected. */
-    private boolean deselect(ViewInfo viewInfo) {
-        if (viewInfo == null) {
-            return false;
-        }
-
-        for (ListIterator<Selection> it = mSelections.listIterator(); it.hasNext(); ) {
-            Selection s = it.next();
-            if (viewInfo == s.getViewInfo()) {
-                it.remove();
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /** Deselects multiple view infos, */
-    private void deselectAll(List<ViewInfo> viewInfos) {
-        for (ListIterator<Selection> it = mSelections.listIterator(); it.hasNext(); ) {
-            Selection s = it.next();
-            if (viewInfos.contains(s.getViewInfo())) {
-                it.remove();
-            }
-        }
-    }
-
-    private void onDoubleClick(MouseEvent e) {
-        // pass, not used yet.
-    }
-
-    /**
-     * Tries to find a child with the same view key in the view info sub-tree.
-     * Returns null if not found.
-     */
-    private ViewInfo findViewInfoKey(Object viewKey, ViewInfo viewInfo) {
-        if (viewInfo.getKey() == viewKey) {
-            return viewInfo;
-        }
-
-        // try to find a matching child
-        for (ViewInfo child : viewInfo.getChildren()) {
-            ViewInfo v = findViewInfoKey(viewKey, child);
-            if (v != null) {
-                return v;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Tries to find the inner most child matching the given x,y coordinates in the view
-     * info sub-tree. This uses the potentially-expanded selection bounds.
-     *
-     * Returns null if not found.
-     */
-    private ViewInfo findViewInfoAt(int x, int y, ViewInfo viewInfo) {
-        Rectangle r = viewInfo.getSelectionRect();
-        if (r.contains(x, y)) {
-
-            // try to find a matching child first
-            for (ViewInfo child : viewInfo.getChildren()) {
-                ViewInfo v = findViewInfoAt(x, y, child);
-                if (v != null) {
-                    return v;
-                }
-            }
-
-            // if no children matched, this is the view that we're looking for
-            return viewInfo;
-        }
-
-        return null;
-    }
-
-    private ArrayList<ViewInfo> findAltViewInfoAt(
-            int x, int y, ViewInfo parent, ArrayList<ViewInfo> outList) {
-        Rectangle r;
-
-        if (outList == null) {
-            outList = new ArrayList<ViewInfo>();
-
-            // add the parent root only once
-            r = parent.getSelectionRect();
-            if (r.contains(x, y)) {
-                outList.add(parent);
-            }
-        }
-
-        if (parent.getChildren().size() > 0) {
-            // then add all children that match the position
-            for (ViewInfo child : parent.getChildren()) {
-                r = child.getSelectionRect();
-                if (r.contains(x, y)) {
-                    outList.add(child);
-                }
-            }
-
-            // finally recurse in the children
-            for (ViewInfo child : parent.getChildren()) {
-                r = child.getSelectionRect();
-                if (r.contains(x, y)) {
-                    findAltViewInfoAt(x, y, child, outList);
-                }
-            }
-        }
-
-        return outList;
-    }
-
-    /**
-     * Maps a {@link ILayoutViewInfo} in a structure more adapted to our needs.
-     * The only large difference is that we keep both the original bounds of the view info
-     * and we pre-compute the selection bounds which are absolute to the rendered image (where
-     * as the original bounds are relative to the parent view.)
-     * <p/>
-     * Each view also know its parent, which should be handy later.
-     * <p/>
-     * We can't alter {@link ILayoutViewInfo} as it is part of the LayoutBridge and needs to
-     * have a fixed API.
-     */
-    private static class ViewInfo {
-        private final Rectangle mRealRect;
-        private final Rectangle mSelectionRect;
-        private final String mName;
-        private final Object mKey;
-        private final ViewInfo mParent;
-        private final ArrayList<ViewInfo> mChildren = new ArrayList<ViewInfo>();
-
-        /**
-         * Constructs a {@link ViewInfo} hierarchy based on a given {@link ILayoutViewInfo}
-         * hierarchy. This call is recursives and builds a full tree.
-         *
-         * @param viewInfo The root of the {@link ILayoutViewInfo} hierarchy.
-         */
-        public ViewInfo(ILayoutViewInfo viewInfo) {
-            this(viewInfo, null /*parent*/, 0 /*parentX*/, 0 /*parentY*/);
-        }
-
-        private ViewInfo(ILayoutViewInfo viewInfo, ViewInfo parent, int parentX, int parentY) {
-            mParent = parent;
-            mKey  = viewInfo.getViewKey();
-            mName = viewInfo.getName();
-
-            int x = viewInfo.getLeft();
-            int y = viewInfo.getTop();
-            int w = viewInfo.getRight() - x;
-            int h = viewInfo.getBottom() - y;
-
-            mRealRect = new Rectangle(x, y, w, h);
-
-            if (parent != null) {
-                x += parentX;
-                y += parentY;
-            }
-
-            if (viewInfo.getChildren() != null) {
-                for (ILayoutViewInfo child : viewInfo.getChildren()) {
-                    mChildren.add(new ViewInfo(child, this, x, y));
-                }
-            }
-
-            // adjust selection bounds for views which are too small to select
-
-            if (w < SELECTION_MIN_SIZE) {
-                int d = (SELECTION_MIN_SIZE - w) / 2;
-                x -= d;
-                w += SELECTION_MIN_SIZE - w;
-            }
-
-            if (h < SELECTION_MIN_SIZE) {
-                int d = (SELECTION_MIN_SIZE - h) / 2;
-                y -= d;
-                h += SELECTION_MIN_SIZE - h;
-            }
-
-            mSelectionRect = new Rectangle(x, y, w - 1, h - 1);
-        }
-
-        /** Returns the original {@link ILayoutResult} bounds, relative to the parent. */
-        public Rectangle getRealRect() {
-            return mRealRect;
-        }
-
-        /*
-        * Returns the absolute selection bounds of the view info as a rectangle.
-        * The selection bounds will always have a size greater or equal to
-        * {@link #SELECTION_MIN_SIZE}.
-        * The width/height is inclusive (i.e. width = right-left-1).
-        * This is in absolute "screen" coordinates (relative to the rendered bitmap).
-        */
-        public Rectangle getSelectionRect() {
-            return mSelectionRect;
-        }
-
-        /**
-         * Returns the view key. Could be null, although unlikely.
-         * @see ILayoutViewInfo#getViewKey()
-         */
-        public Object getKey() {
-            return mKey;
-        }
-
-        /**
-         * Returns the parent {@link ViewInfo}.
-         * It is null for the root and non-null for children.
-         */
-        public ViewInfo getParent() {
-            return mParent;
-        }
-
-        /**
-         * Returns the list of children of this {@link ViewInfo}.
-         * The list is never null. It can be empty.
-         * By contract, this.getChildren().get(0..n-1).getParent() == this.
-         */
-        public ArrayList<ViewInfo> getChildren() {
-            return mChildren;
-        }
-
-        /**
-         * Returns the name of the {@link ViewInfo}.
-         * Could be null, although unlikely.
-         * Experience shows this is the full qualified Java name of the View.
-         * @see ILayoutViewInfo#getName()
-         */
-        public String getName() {
-            return mName;
-        }
-    }
-
-    /**
-     * Represents one selection.
-     */
-    private static class Selection {
-        /** Current selected view info. Cannot be null. */
-        private final ViewInfo mViewInfo;
-
-        /** Current selection border rectangle. Cannot be null. */
-        private final Rectangle mRect;
-
-        /** The name displayed over the selection, typically the widget class name. Can be null. */
-        private final String mName;
-
-        /**
-         * Creates a new {@link Selection} object.
-         * @param viewInfo The view info being selected. Must not be null.
-         */
-        public Selection(ViewInfo viewInfo) {
-
-            assert viewInfo != null;
-
-            mViewInfo = viewInfo;
-
-            if (viewInfo == null) {
-                mRect = null;
-            } else {
-                Rectangle r = viewInfo.getSelectionRect();
-                mRect = new Rectangle(r.x + IMAGE_MARGIN, r.y + IMAGE_MARGIN, r.width, r.height);
-            }
-
-            String name = viewInfo == null ? null : viewInfo.getName();
-            if (name != null) {
-                // The name is typically a fully-qualified class name. Let's make it a tad shorter.
-
-                if (name.startsWith("android.")) {                                      // $NON-NLS-1$
-                    // For android classes, convert android.foo.Name to android...Name
-                    int first = name.indexOf('.');
-                    int last = name.lastIndexOf('.');
-                    if (last > first) {
-                        name = name.substring(0, first) + ".." + name.substring(last);   // $NON-NLS-1$
-                    }
-                } else {
-                    // For custom non-android classes, it's best to keep the 2 first segments of
-                    // the namespace, e.g. we want to get something like com.example...MyClass
-                    int first = name.indexOf('.');
-                    first = name.indexOf('.', first + 1);
-                    int last = name.lastIndexOf('.');
-                    if (last > first) {
-                        name = name.substring(0, first) + ".." + name.substring(last);   // $NON-NLS-1$
-                    }
-                }
-            }
-
-            mName = name;
-        }
-
-        /**
-         * Returns the selected view info. Cannot be null.
-         */
-        public ViewInfo getViewInfo() {
-            return mViewInfo;
-        }
-
-        /**
-         * Returns the selection border rectangle.
-         * Cannot be null.
-         */
-        public Rectangle getRect() {
-            return mRect;
-        }
-
-        /**
-         * The name displayed over the selection, typically the widget class name.
-         * Can be null.
-         */
-        public String getName() {
-            return mName;
-        }
-    }
-
-    /**
-     * Information for the current alternate selection, i.e. the possible selected items
-     * that are located at the same x/y as the original view, either sibling or parents.
-     */
-    private static class AlternateSelection {
-        private final ViewInfo mOriginatingView;
-        private final List<ViewInfo> mAltViews;
-        private int mIndex;
-
-        /**
-         * Creates a new alternate selection based on the given originating view and the
-         * given list of alternate views. Both cannot be null.
-         */
-        public AlternateSelection(ViewInfo originatingView, List<ViewInfo> altViews) {
-            assert originatingView != null;
-            assert altViews != null;
-            mOriginatingView = originatingView;
-            mAltViews = altViews;
-            mIndex = altViews.size() - 1;
-        }
-
-        /** Returns the list of alternate views. Cannot be null. */
-        public List<ViewInfo> getAltViews() {
-            return mAltViews;
-        }
-
-        /** Returns the originating view. Cannot be null. */
-        public ViewInfo getOriginatingView() {
-            return mOriginatingView;
-        }
-
-        /**
-         * Returns the current alternate view to select.
-         * Initially this is the top-most view.
-         */
-        public ViewInfo getCurrent() {
-            return mIndex >= 0 ? mAltViews.get(mIndex) : null;
-        }
-
-        /**
-         * Changes the current view to be the next one and then returns it.
-         * This loops through the alternate views.
-         */
-        public ViewInfo getNext() {
-            if (mIndex == 0) {
-                mIndex = mAltViews.size() - 1;
-            } else if (mIndex > 0) {
-                mIndex--;
-            }
-
-            return getCurrent();
-        }
-    }
-
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutConstants.java
deleted file mode 100644
index b36c985..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutConstants.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-/**
- * A bunch of constants that map to either:
- * <ul>
- * <li>Android Layouts XML element names (Linear, Relative, Absolute, etc.)
- * <li>Attributes for layout XML elements. 
- * <li>Values for attributes.
- * </ul>
- */
-public class LayoutConstants {
-
-    public static final String RELATIVE_LAYOUT = "RelativeLayout";      //$NON-NLS-1$
-    public static final String LINEAR_LAYOUT   = "LinearLayout";        //$NON-NLS-1$
-    public static final String ABSOLUTE_LAYOUT = "AbsoluteLayout";      //$NON-NLS-1$
-
-    public static final String ATTR_TEXT = "text";                      //$NON-NLS-1$
-    public static final String ATTR_ID = "id";                          //$NON-NLS-1$
-
-    public static final String ATTR_LAYOUT_HEIGHT = "layout_height";    //$NON-NLS-1$
-    public static final String ATTR_LAYOUT_WIDTH = "layout_width";      //$NON-NLS-1$
-
-    public static final String ATTR_LAYOUT_ALIGN_PARENT_TOP = "layout_alignParentTop"; //$NON-NLS-1$
-    public static final String ATTR_LAYOUT_ALIGN_PARENT_BOTTOM = "layout_alignParentBottom"; //$NON-NLS-1$
-    public static final String ATTR_LAYOUT_ALIGN_PARENT_LEFT = "layout_alignParentLeft";//$NON-NLS-1$
-    public static final String ATTR_LAYOUT_ALIGN_PARENT_RIGHT = "layout_alignParentRight";   //$NON-NLS-1$
-    
-    public static final String ATTR_LAYOUT_ALIGN_BASELINE = "layout_alignBaseline"; //$NON-NLS-1$
-
-    public static final String ATTR_LAYOUT_CENTER_VERTICAL = "layout_centerVertical"; //$NON-NLS-1$
-    public static final String ATTR_LAYOUT_CENTER_HORIZONTAL = "layout_centerHorizontal"; //$NON-NLS-1$
-    
-    public static final String ATTR_LAYOUT_TO_RIGHT_OF = "layout_toRightOf";    //$NON-NLS-1$
-    public static final String ATTR_LAYOUT_TO_LEFT_OF = "layout_toLeftOf";      //$NON-NLS-1$
-    
-    public static final String ATTR_LAYOUT_BELOW = "layout_below";              //$NON-NLS-1$
-    public static final String ATTR_LAYOUT_ABOVE = "layout_above";              //$NON-NLS-1$
-    
-    public static final String ATTR_LAYOUT_Y = "layout_y";                      //$NON-NLS-1$
-    public static final String ATTR_LAYOUT_X = "layout_x";                      //$NON-NLS-1$
-
-    public static final String VALUE_WRAP_CONTENT = "wrap_content";             //$NON-NLS-1$
-    public static final String VALUE_FILL_PARENT = "fill_parent";               //$NON-NLS-1$
-    public static final String VALUE_TRUE = "true";                             //$NON-NLS-1$
-    public static final String VALUE_N_DIP = "%ddip";                           //$NON-NLS-1$
-
-    private LayoutConstants() {
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java
deleted file mode 100644
index 4b313f6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-/**
- * Content Assist Processor for /res/layout XML files
- */
-class LayoutContentAssist extends AndroidContentAssist {
-
-    /**
-     * Constructor for LayoutContentAssist 
-     */
-    public LayoutContentAssist() {
-        super(AndroidTargetData.DESCRIPTOR_LAYOUT);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java
deleted file mode 100644
index 99670d8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiActions;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.ui.EclipseUiHelper;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.gef.ui.parts.TreeViewer;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IPartListener;
-import org.eclipse.ui.IShowEditorInput;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchPartSite;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
-import org.eclipse.ui.views.properties.IPropertySheetPage;
-import org.w3c.dom.Document;
-
-/**
- * Multi-page form editor for /res/layout XML files.
- */
-public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPartListener {
-
-    public static final String ID = AndroidConstants.EDITORS_NAMESPACE + ".layout.LayoutEditor"; //$NON-NLS-1$
-
-    /** Root node of the UI element hierarchy */
-    private UiDocumentNode mUiRootNode;
-
-    private IGraphicalLayoutEditor mGraphicalEditor;
-    private int mGraphicalEditorIndex;
-    /** Implementation of the {@link IContentOutlinePage} for this editor */
-    private UiContentOutlinePage mOutline;
-    /** Custom implementation of {@link IPropertySheetPage} for this editor */
-    private UiPropertySheetPage mPropertyPage;
-
-    private UiEditorActions mUiEditorActions;
-
-    /**
-     * Creates the form editor for resources XML files.
-     */
-    public LayoutEditor() {
-        super();
-    }
-
-    /**
-     * @return The root node of the UI element hierarchy
-     */
-    @Override
-    public UiDocumentNode getUiRootNode() {
-        return mUiRootNode;
-    }
-
-    // ---- Base Class Overrides ----
-
-    @Override
-    public void dispose() {
-        getSite().getPage().removePartListener(this);
-
-        super.dispose();
-    }
-
-    /**
-     * Save the XML.
-     * <p/>
-     * The actual save operation is done in the super class by committing
-     * all data to the XML model and then having the Structured XML Editor
-     * save the XML.
-     * <p/>
-     * Here we just need to tell the graphical editor that the model has
-     * been saved.
-     */
-    @Override
-    public void doSave(IProgressMonitor monitor) {
-        super.doSave(monitor);
-        if (mGraphicalEditor != null) {
-            mGraphicalEditor.doSave(monitor);
-        }
-    }
-
-    /**
-     * Returns whether the "save as" operation is supported by this editor.
-     * <p/>
-     * Save-As is a valid operation for the ManifestEditor since it acts on a
-     * single source file.
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public boolean isSaveAsAllowed() {
-        return true;
-    }
-
-    /**
-     * Create the various form pages.
-     */
-    @Override
-    protected void createFormPages() {
-        try {
-            // The graphical layout editor is now enabled by default.
-            // In case there's an issue we provide a way to disable it using an
-            // env variable.
-            if (System.getenv("ANDROID_DISABLE_LAYOUT") == null) {      //$NON-NLS-1$
-                if (mGraphicalEditor == null) {
-
-                    if (System.getenv("USE_GLE2") != null) {            //$NON-NLS-1$ //$NON-NLS-2$
-                        mGraphicalEditor = new GraphicalEditorPart(this);
-                    } else {
-                        mGraphicalEditor = new GraphicalLayoutEditor(this);
-                    }
-
-                    mGraphicalEditorIndex = addPage(mGraphicalEditor, getEditorInput());
-                    setPageText(mGraphicalEditorIndex, mGraphicalEditor.getTitle());
-                } else {
-                    mGraphicalEditor.reloadEditor();
-                }
-
-                // update the config based on the opened file.
-                IEditorInput input = getEditorInput();
-                if (input instanceof FileEditorInput) {
-                    FileEditorInput fileInput = (FileEditorInput)input;
-                    ResourceFolder resFolder = ResourceManager.getInstance().getResourceFolder(
-                            fileInput.getFile());
-                    if (resFolder != null) {
-                        mGraphicalEditor.editNewFile(resFolder.getConfiguration());
-                    }
-                }
-
-                // put in place the listener to handle layout recompute only when needed.
-                getSite().getPage().addPartListener(this);
-            }
-        } catch (PartInitException e) {
-            AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$
-        }
-     }
-
-    /* (non-java doc)
-     * Change the tab/title name to include the name of the layout.
-     */
-    @Override
-    protected void setInput(IEditorInput input) {
-        super.setInput(input);
-        handleNewInput(input);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.part.EditorPart#setInputWithNotify(org.eclipse.ui.IEditorInput)
-     */
-    @Override
-    protected void setInputWithNotify(IEditorInput input) {
-        super.setInputWithNotify(input);
-        handleNewInput(input);
-    }
-
-    /**
-     * Called to replace the current {@link IEditorInput} with another one.
-     * <p/>This is used when {@link MatchingStrategy} returned <code>true</code> which means we're
-     * opening a different configuration of the same layout.
-     */
-    public void showEditorInput(IEditorInput editorInput) {
-        // save the current editor input.
-        doSave(new NullProgressMonitor());
-
-        // get the current page
-        int currentPage = getActivePage();
-
-        // remove the pages, except for the graphical editor, which will be dynamically adapted
-        // to the new model.
-        // page after the graphical editor:
-        int count = getPageCount();
-        for (int i = count - 1 ; i > mGraphicalEditorIndex ; i--) {
-            removePage(i);
-        }
-        // pages before the graphical editor
-        for (int i = mGraphicalEditorIndex - 1 ; i >= 0 ; i--) {
-            removePage(i);
-        }
-
-        // set the current input.
-        setInputWithNotify(editorInput);
-
-        // re-create or reload the pages with the default page shown as the previous active page.
-        createAndroidPages();
-        selectDefaultPage(Integer.toString(currentPage));
-
-        // update the outline
-        if (mOutline != null && mGraphicalEditor != null) {
-            mOutline.reloadModel();
-        }
-    }
-
-    /**
-     * Processes the new XML Model, which XML root node is given.
-     *
-     * @param xml_doc The XML document, if available, or null if none exists.
-     */
-    @Override
-    protected void xmlModelChanged(Document xml_doc) {
-        // init the ui root on demand
-        initUiRootNode(false /*force*/);
-
-        mUiRootNode.loadFromXmlNode(xml_doc);
-
-        // update the model first, since it is used by the viewers.
-        super.xmlModelChanged(xml_doc);
-
-        if (mGraphicalEditor != null) {
-            mGraphicalEditor.onXmlModelChanged();
-        }
-
-        if (mOutline != null) {
-            mOutline.reloadModel();
-        }
-    }
-
-    /* (non-java doc)
-     * Returns the IContentOutlinePage when asked for it.
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object getAdapter(Class adapter) {
-        // for the outline, force it to come from the Graphical Editor.
-        // This fixes the case where a layout file is opened in XML view first and the outline
-        // gets stuck in the XML outline.
-        if (IContentOutlinePage.class == adapter && mGraphicalEditor != null) {
-
-            if (mOutline == null && mGraphicalEditor instanceof GraphicalLayoutEditor) {
-                // TODO add support for GLE2
-                mOutline = new UiContentOutlinePage(
-                        (GraphicalLayoutEditor) mGraphicalEditor,
-                        new TreeViewer());
-            }
-
-            return mOutline;
-        }
-
-        if (IPropertySheetPage.class == adapter && mGraphicalEditor != null) {
-            if (mPropertyPage == null) {
-                mPropertyPage = new UiPropertySheetPage();
-            }
-
-            return mPropertyPage;
-        }
-
-        // return default
-        return super.getAdapter(adapter);
-    }
-
-    @Override
-    protected void pageChange(int newPageIndex) {
-        super.pageChange(newPageIndex);
-
-        if (mGraphicalEditor != null) {
-            if (newPageIndex == mGraphicalEditorIndex) {
-                mGraphicalEditor.activated();
-            } else {
-                mGraphicalEditor.deactivated();
-            }
-        }
-    }
-
-    // ----- IPartListener Methods ----
-
-    public void partActivated(IWorkbenchPart part) {
-        if (part == this) {
-            if (mGraphicalEditor != null) {
-                if (getActivePage() == mGraphicalEditorIndex) {
-                    mGraphicalEditor.activated();
-                } else {
-                    mGraphicalEditor.deactivated();
-                }
-            }
-        }
-    }
-
-    public void partBroughtToTop(IWorkbenchPart part) {
-        partActivated(part);
-    }
-
-    public void partClosed(IWorkbenchPart part) {
-        // pass
-    }
-
-    public void partDeactivated(IWorkbenchPart part) {
-        if (part == this) {
-            if (mGraphicalEditor != null && getActivePage() == mGraphicalEditorIndex) {
-                mGraphicalEditor.deactivated();
-            }
-        }
-    }
-
-    public void partOpened(IWorkbenchPart part) {
-        EclipseUiHelper.showView(EclipseUiHelper.CONTENT_OUTLINE_VIEW_ID, false /* activate */);
-        EclipseUiHelper.showView(EclipseUiHelper.PROPERTY_SHEET_VIEW_ID, false /* activate */);
-    }
-
-    public class UiEditorActions extends UiActions {
-
-        @Override
-        protected UiDocumentNode getRootNode() {
-            return mUiRootNode;
-        }
-
-        // Select the new item
-        @Override
-        protected void selectUiNode(UiElementNode uiNodeToSelect) {
-            mGraphicalEditor.selectModel(uiNodeToSelect);
-        }
-
-        @Override
-        public void commitPendingXmlChanges() {
-            // Pass. There is nothing to commit before the XML is changed here.
-        }
-    }
-
-    public UiEditorActions getUiEditorActions() {
-        if (mUiEditorActions == null) {
-            mUiEditorActions = new UiEditorActions();
-        }
-        return mUiEditorActions;
-    }
-
-    // ---- Local Methods ----
-
-    /**
-     * Returns true if the Graphics editor page is visible. This <b>must</b> be
-     * called from the UI thread.
-     */
-    boolean isGraphicalEditorActive() {
-        IWorkbenchPartSite workbenchSite = getSite();
-        IWorkbenchPage workbenchPage = workbenchSite.getPage();
-
-        // check if the editor is visible in the workbench page
-        if (workbenchPage.isPartVisible(this) && workbenchPage.getActiveEditor() == this) {
-            // and then if the page of the editor is visible (not to be confused with
-            // the workbench page)
-            return mGraphicalEditorIndex == getActivePage();
-        }
-
-        return false;
-    }
-
-    @Override
-    protected void initUiRootNode(boolean force) {
-        // The root UI node is always created, even if there's no corresponding XML node.
-        if (mUiRootNode == null || force) {
-            // get the target data from the opened file (and its project)
-            AndroidTargetData data = getTargetData();
-
-            Document doc = null;
-            if (mUiRootNode != null) {
-                doc = mUiRootNode.getXmlDocument();
-            }
-
-            DocumentDescriptor desc;
-            if (data == null) {
-                desc = new DocumentDescriptor("temp", null /*children*/);
-            } else {
-                desc = data.getLayoutDescriptors().getDescriptor();
-            }
-
-            // get the descriptors from the data.
-            mUiRootNode = (UiDocumentNode) desc.createUiNode();
-            mUiRootNode.setEditor(this);
-
-            onDescriptorsChanged(doc);
-        }
-    }
-
-    private void onDescriptorsChanged(Document document) {
-        if (document != null) {
-            mUiRootNode.loadFromXmlNode(document);
-        } else {
-            mUiRootNode.reloadFromXmlNode(mUiRootNode.getXmlDocument());
-        }
-
-        if (mOutline != null) {
-            mOutline.reloadModel();
-        }
-
-        if (mGraphicalEditor != null) {
-            mGraphicalEditor.reloadEditor();
-            mGraphicalEditor.reloadPalette();
-            mGraphicalEditor.reloadConfigurationUi(true /*notify listener */);
-            mGraphicalEditor.recomputeLayout();
-        }
-    }
-
-    /**
-     * Handles a new input, and update the part name.
-     * @param input the new input.
-     */
-    private void handleNewInput(IEditorInput input) {
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput) input;
-            IFile file = fileInput.getFile();
-            setPartName(String.format("%1$s",
-                    file.getName()));
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutReloadMonitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutReloadMonitor.java
deleted file mode 100644
index 507cb21..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutReloadMonitor.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IResourceEventListener;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResourceDelta;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Monitor for file changes triggering a layout redraw.
- */
-public final class LayoutReloadMonitor implements IFileListener, IResourceEventListener {
-
-    // singleton, enforced by private constructor.
-    private final static LayoutReloadMonitor sThis = new LayoutReloadMonitor();
-
-    /**
-     * Map of listeners by IProject.
-     */
-    private final Map<IProject, List<ILayoutReloadListener>> mListenerMap =
-        new HashMap<IProject, List<ILayoutReloadListener>>();
-
-    private final static int CHANGE_CODE = 0;
-    private final static int CHANGE_RESOURCES = 1;
-    private final static int CHANGE_R = 2;
-    private final static int CHANGE_COUNT = 3;
-    /**
-     * List of projects having received a file change. the boolean[] contains 3 values:
-     * <ul><li>CHANGE_CODE: code change flag.</li>
-     * <li>CHANGE_RESOURCES: resource change flag.</li>
-     * <li>CHANGE_R: R clas change flag</li></ul>
-     */
-    private final Map<IProject, boolean[]> mChangedProjects = new HashMap<IProject, boolean[]>();
-
-    /**
-     * Classes which implement this interface provide a method to respond to resource changes
-     * triggering a layout redraw
-     */
-    public interface ILayoutReloadListener {
-        /**
-         * Sent when the layout needs to be redrawn
-         * @param codeChange The trigger happened due to a code change.
-         * @param rChange The trigger happened due to a change in the R class.
-         * @param resChange The trigger happened due to a resource change.
-         */
-        void reloadLayout(boolean codeChange, boolean rChange, boolean resChange);
-    }
-
-    /**
-     * Returns the single instance of {@link LayoutReloadMonitor}.
-     */
-    public static LayoutReloadMonitor getMonitor() {
-        return sThis;
-    }
-
-    private LayoutReloadMonitor() {
-        ResourceMonitor monitor = ResourceMonitor.getMonitor();
-        monitor.addFileListener(this, IResourceDelta.ADDED | IResourceDelta.CHANGED);
-        monitor.addResourceEventListener(this);
-    }
-
-    /**
-     * Adds a listener for a given {@link IProject}.
-     * @param project
-     * @param listener
-     */
-    public void addListener(IProject project, ILayoutReloadListener listener) {
-        synchronized (mListenerMap) {
-            List<ILayoutReloadListener> list = mListenerMap.get(project);
-            if (list == null) {
-                list = new ArrayList<ILayoutReloadListener>();
-                mListenerMap.put(project, list);
-            }
-
-            list.add(listener);
-        }
-    }
-
-    /**
-     * Removes a listener for a given {@link IProject}.
-     */
-    public void removeListener(IProject project, ILayoutReloadListener listener) {
-        synchronized (mListenerMap) {
-            List<ILayoutReloadListener> list = mListenerMap.get(project);
-            if (list != null) {
-                list.remove(listener);
-            }
-        }
-    }
-
-    /**
-     * Removes a listener, no matter which {@link IProject} it was associated with.
-     */
-    public void removeListener(ILayoutReloadListener listener) {
-        synchronized (mListenerMap) {
-
-            for (List<ILayoutReloadListener> list : mListenerMap.values()) {
-                Iterator<ILayoutReloadListener> it = list.iterator();
-                while (it.hasNext()) {
-                    ILayoutReloadListener i = it.next();
-                    if (i == listener) {
-                        it.remove();
-                    }
-                }
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener#fileChanged(org.eclipse.core.resources.IFile, org.eclipse.core.resources.IMarkerDelta[], int)
-     *
-     * Callback for ResourceMonitor.IFileListener. Called when a file changed.
-     * This records the changes for each project, but does not notify listeners.
-     * @see #resourceChangeEventEnd
-     */
-    public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
-        // get the file project
-        IProject project = file.getProject();
-
-        // if this project has already been marked as modified, we do nothing.
-        boolean[] changeFlags = mChangedProjects.get(project);
-        if (changeFlags != null && changeFlags[CHANGE_CODE] && changeFlags[CHANGE_RESOURCES] &&
-                changeFlags[CHANGE_R]) {
-            return;
-        }
-
-        // now check that the file is *NOT* a layout file (those automatically trigger a layout
-        // reload and we don't want to do it twice.
-        ResourceFolder resFolder = ResourceManager.getInstance().getResourceFolder(file);
-        if (resFolder != null) {
-            if (resFolder.getType() != ResourceFolderType.LAYOUT) {
-                // this is a resource change!
-                if (changeFlags == null) {
-                    changeFlags = new boolean[CHANGE_COUNT];
-                    mChangedProjects.put(project, changeFlags);
-                }
-
-                changeFlags[CHANGE_RESOURCES] = true;
-            }
-        } else if (AndroidConstants.EXT_CLASS.equals(file.getFileExtension())) {
-            if (file.getName().matches("R[\\$\\.](.*)")) {
-                // this is a R change!
-                if (changeFlags == null) {
-                    changeFlags = new boolean[CHANGE_COUNT];
-                    mChangedProjects.put(project, changeFlags);
-                }
-
-                changeFlags[CHANGE_R] = true;
-            } else {
-                // this is a code change!
-                if (changeFlags == null) {
-                    changeFlags = new boolean[CHANGE_COUNT];
-                    mChangedProjects.put(project, changeFlags);
-                }
-
-                changeFlags[CHANGE_CODE] = true;
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IResourceEventListener#resourceChangeEventStart()
-     *
-     * Callback for ResourceMonitor.IResourceEventListener. Called at the beginning of a resource
-     * change event. This is called once, while fileChanged can be called several times.
-     *
-     */
-    public void resourceChangeEventStart() {
-        // nothing to be done here, it all happens in the resourceChangeEventEnd
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IResourceEventListener#resourceChangeEventEnd()
-     *
-     * Callback for ResourceMonitor.IResourceEventListener. Called at the end of a resource
-     * change event. This is where we notify the listeners.
-     */
-    public void resourceChangeEventEnd() {
-        // for each IProject that was changed, we notify all the listeners.
-        synchronized (mListenerMap) {
-            for (Entry<IProject, boolean[]> project : mChangedProjects.entrySet()) {
-                List<ILayoutReloadListener> listeners = mListenerMap.get(project.getKey());
-
-                boolean[] flags = project.getValue();
-
-                if (listeners != null) {
-                    for (ILayoutReloadListener listener : listeners) {
-                        listener.reloadLayout(flags[CHANGE_CODE], flags[CHANGE_R],
-                                flags[CHANGE_RESOURCES]);
-                    }
-                }
-            }
-        }
-
-        // empty the list.
-        mChangedProjects.clear();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutSourceViewerConfig.java
deleted file mode 100644
index bf9f97f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutSourceViewerConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidSourceViewerConfig;
-
-/**
- * Source Viewer Configuration that calls in LayoutContentAssist.
- */
-public class LayoutSourceViewerConfig extends AndroidSourceViewerConfig {
-
-    public LayoutSourceViewerConfig() {
-        super(new LayoutContentAssist());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/MatchingStrategy.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/MatchingStrategy.java
deleted file mode 100644
index a6a19a6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/MatchingStrategy.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorMatchingStrategy;
-import org.eclipse.ui.IEditorReference;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.FileEditorInput;
-
-/**
- * Matching strategy for the Layout Editor. This is used to open all configurations of a layout
- * in the same editor.
- */
-public class MatchingStrategy implements IEditorMatchingStrategy {
-
-    public boolean matches(IEditorReference editorRef, IEditorInput input) {
-        // first check that the file being opened is a layout file.
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput)input;
-            
-            // get the IFile object and check it's in one of the layout folders.
-            IFile iFile = fileInput.getFile();
-            ResourceFolder resFolder = ResourceManager.getInstance().getResourceFolder(iFile);
-            
-            // if it's a layout, we know check the name of the fileInput against the name of the
-            // file being currently edited by the editor since those are independent of the config.
-            if (resFolder != null && resFolder.getType() == ResourceFolderType.LAYOUT) {
-                try {
-                    IEditorInput editorInput = editorRef.getEditorInput();
-                    if (editorInput instanceof FileEditorInput) {
-                        FileEditorInput editorFileInput = (FileEditorInput)editorInput;
-                        IFile editorIFile = editorFileInput.getFile();
-                        
-                        return editorIFile.getProject().equals(iFile.getProject())
-                            && editorIFile.getName().equals(iFile.getName());
-                    }
-                } catch (PartInitException e) {
-                    // we do nothing, we'll just return false.
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteComposite.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteComposite.java
deleted file mode 100755
index 229494c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteComposite.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-
-import java.util.List;
-
-/**
- * A palette composite for the {@link GraphicalEditorPart}.
- * <p/>
- * The palette contains several groups, each with a UI name (e.g. layouts and views) and each
- * with a list of element descriptors.
- * <p/>
- *
- * @since GLE2
- *
- * TODO list:
- * - *Mandatory* for a first release:
- *   - Currently this displays elements as buttons. Eventually this needs to either be replaced
- *     by custom drawing right in here or we need to use a custom control.
- *   - Needs to be able to originate drag'n'drop from these controls onto the GEP.
- *   - Scroll the list.
- * - For later releases:
- *   - Ability to collapse palettes or dockable palettes.
- *   - Different view strategies: big icon, small icons, text vs no text, compact grid.
- *     - This would only be useful with meaningful icons. Out current 1-letter icons are not enough
- *       to get rid of text labels.
- *   - Would be nice to have context-sensitive tools items, e.g. selection arrow tool,
- *     group selection tool, alignment, etc.
- */
-public class PaletteComposite extends Composite {
-
-    /**
-     * Create the composite.
-     * @param parent The parent composite.
-     */
-    public PaletteComposite(Composite parent) {
-        super(parent, SWT.BORDER | SWT.V_SCROLL);
-    }
-
-    @Override
-    protected void checkSubclass() {
-        // Disable the check that prevents subclassing of SWT components
-    }
-
-    /**
-     * Load or reload the palette elements by using the layour and view descriptors from the
-     * given target data.
-     *
-     * @param targetData The target data that contains the descriptors. If null or empty,
-     *   no groups will be created.
-     */
-    public void reloadPalette(AndroidTargetData targetData) {
-
-        for (Control c : getChildren()) {
-            c.dispose();
-        }
-
-        if (targetData != null) {
-            GridLayout gl = new GridLayout(1, false);
-            gl.horizontalSpacing = 0;
-            gl.verticalSpacing = 0;
-            gl.marginHeight = 2;
-            gl.marginBottom = 2;
-            gl.marginLeft = 2;
-            gl.marginRight = 2;
-            gl.marginTop = 2;
-            gl.marginBottom = 2;
-            setLayout(gl);
-
-            /* TODO: All this is TEMPORARY. */
-            Label l = new Label(this, SWT.NONE);
-            l.setText("*** PLACEHOLDER ***");  //$NON-NLS-1$
-            l.setToolTipText("Temporary mock for the palette. Needs to scroll, needs no buttons, needs to drag'n'drop."); //$NON-NLS-1$
-
-            addGroup("Layouts", targetData.getLayoutDescriptors().getLayoutDescriptors());
-            addGroup("Views", targetData.getLayoutDescriptors().getViewDescriptors());
-        }
-
-        layout(true);
-    }
-
-    private void addGroup(String uiName, List<ElementDescriptor> descriptors) {
-        Label label = new Label(this, SWT.NONE);
-        label.setText(uiName);
-
-        for (ElementDescriptor desc : descriptors) {
-            Button b = new Button(this, SWT.PUSH);
-            b.setText(desc.getUiName());
-            b.setImage(desc.getIcon());
-            b.setToolTipText(desc.getTooltip());
-            b.setData(desc);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteFactory.java
deleted file mode 100644
index 7bf6acf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteFactory.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-import org.eclipse.gef.palette.PaletteDrawer;
-import org.eclipse.gef.palette.PaletteGroup;
-import org.eclipse.gef.palette.PaletteRoot;
-import org.eclipse.gef.palette.PaletteTemplateEntry;
-
-import java.util.List;
-
-/**
- * Factory that creates the palette for the {@link GraphicalLayoutEditor}.
- *
- * @since GLE1
- */
-public class PaletteFactory {
-
-    /** Static factory, nothing to instantiate here. */
-    private PaletteFactory() {
-    }
-
-    public static PaletteRoot createPaletteRoot(PaletteRoot currentPalette,
-            AndroidTargetData targetData) {
-
-        if (currentPalette == null) {
-            currentPalette = new PaletteRoot();
-        }
-
-        for (int n = currentPalette.getChildren().size() - 1; n >= 0; n--) {
-            currentPalette.getChildren().remove(n);
-        }
-
-        if (targetData != null) {
-            addTools(currentPalette);
-            addViews(currentPalette, "Layouts",
-                    targetData.getLayoutDescriptors().getLayoutDescriptors());
-            addViews(currentPalette, "Views",
-                    targetData.getLayoutDescriptors().getViewDescriptors());
-        }
-
-        return currentPalette;
-    }
-
-    private static void addTools(PaletteRoot paletteRoot) {
-        PaletteGroup group = new PaletteGroup("Tools");
-
-        // Default tools: selection.
-        // Do not use the MarqueeToolEntry since we don't support multiple selection.
-        /* -- Do not put the selection tool. It's the unique tool so it looks useless.
-              Leave this piece of code here in case we want it back later.
-        PanningSelectionToolEntry entry = new PanningSelectionToolEntry();
-        group.add(entry);
-        paletteRoot.setDefaultEntry(entry);
-        */
-
-        paletteRoot.add(group);
-    }
-
-    private static void addViews(PaletteRoot paletteRoot, String groupName,
-            List<ElementDescriptor> descriptors) {
-        PaletteDrawer group = new PaletteDrawer(groupName);
-
-        for (ElementDescriptor desc : descriptors) {
-            PaletteTemplateEntry entry = new PaletteTemplateEntry(
-                    desc.getUiName(),           // label
-                    desc.getTooltip(),          // short description
-                    desc,                       // template
-                    desc.getImageDescriptor(),  // small icon
-                    desc.getImageDescriptor()   // large icon
-                    );
-
-            group.add(entry);
-        }
-
-        paletteRoot.add(group);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java
deleted file mode 100644
index 742e3d7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectClassLoader;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.layoutlib.api.IProjectCallback;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-
-import java.lang.reflect.Constructor;
-import java.util.HashMap;
-
-/**
- * Loader for Android Project class in order to use them in the layout editor.
- */
-public final class ProjectCallback implements IProjectCallback {
-    
-    private final HashMap<String, Class<?>> mLoadedClasses = new HashMap<String, Class<?>>();
-    private final IProject mProject;
-    private final ClassLoader mParentClassLoader;
-    private final ProjectResources mProjectRes;
-    private boolean mUsed = false;
-    private String mNamespace;
-    
-    ProjectCallback(ClassLoader classLoader, ProjectResources projectRes, IProject project) {
-        mParentClassLoader = classLoader;
-        mProjectRes = projectRes;
-        mProject = project;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     * 
-     * This implementation goes through the output directory of the Eclipse project and loads the
-     * <code>.class</code> file directly.
-     */
-    @SuppressWarnings("unchecked")
-    public Object loadView(String className, Class[] constructorSignature,
-            Object[] constructorParameters)
-            throws ClassNotFoundException, Exception {
-        
-        // look for a cached version
-        Class<?> clazz = mLoadedClasses.get(className);
-        if (clazz != null) {
-            return instantiateClass(clazz, constructorSignature, constructorParameters);
-        }
-        
-        // load the class.
-        ProjectClassLoader loader = new ProjectClassLoader(mParentClassLoader, mProject);
-        try {
-            clazz = loader.loadClass(className);
-            
-            if (clazz != null) {
-                mUsed = true;
-                mLoadedClasses.put(className, clazz);
-                return instantiateClass(clazz, constructorSignature, constructorParameters);
-            }
-        } catch (Error e) {
-            // Log this error with the class name we're trying to load and abort.
-            AdtPlugin.log(e, "ProjectCallback.loadView failed to find class %1$s", className); //$NON-NLS-1$
-        }
-        
-        return null;
-    }
-    
-    /**
-     * Returns the namespace for the project. The namespace contains a standard part + the
-     * application package.
-     *
-     * @return The package namespace of the project or null in case of error.
-     */
-    public String getNamespace() {
-        if (mNamespace == null) {
-            IFile manifestFile = AndroidManifestParser.getManifest(mProject);
-            try {
-                AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile);
-                String javaPackage = data.getPackage();
-                mNamespace = String.format(AndroidConstants.NS_CUSTOM_RESOURCES, javaPackage);
-            } catch (CoreException e) {
-            }
-        }
-
-        return mNamespace;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.IProjectCallback#resolveResourceValue(int)
-     */
-    public String[] resolveResourceValue(int id) {
-        if (mProjectRes != null) {
-            return mProjectRes.resolveResourceValue(id);
-        }
-
-        return null;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.IProjectCallback#resolveResourceValue(int[])
-     */
-    public String resolveResourceValue(int[] id) {
-        if (mProjectRes != null) {
-            return mProjectRes.resolveResourceValue(id);
-        }
-        
-        return null;
-    }
-    
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.IProjectCallback#getResourceValue(java.lang.String, java.lang.String)
-     */
-    public Integer getResourceValue(String type, String name) {
-        if (mProjectRes != null) {
-            return mProjectRes.getResourceValue(type, name);
-        }
-        
-        return null;
-    }
-    
-    /**
-     * Returns whether the loader has received requests to load custom views.
-     * <p/>This allows to efficiently only recreate when needed upon code change in the project.
-     */
-    boolean isUsed() {
-        return mUsed;
-    }
-
-    /**
-     * Instantiate a class object, using a specific constructor and parameters.
-     * @param clazz the class to instantiate
-     * @param constructorSignature the signature of the constructor to use
-     * @param constructorParameters the parameters to use in the constructor.
-     * @return A new class object, created using a specific constructor and parameters.
-     * @throws Exception 
-     */
-    @SuppressWarnings("unchecked")
-    private Object instantiateClass(Class<?> clazz, Class[] constructorSignature,
-            Object[] constructorParameters) throws Exception {
-        Constructor<?> constructor = clazz.getConstructor(constructorSignature);
-        constructor.setAccessible(true);
-        return constructor.newInstance(constructorParameters);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiContentOutlinePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiContentOutlinePage.java
deleted file mode 100644
index 8e15681..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiContentOutlinePage.java
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * 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.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiDocumentTreeEditPart;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiElementTreeEditPart;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiElementTreeEditPartFactory;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiLayoutTreeEditPart;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiViewTreeEditPart;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.CopyCutAction;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.PasteAction;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiActions;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.ui.EclipseUiHelper;
-
-import org.eclipse.gef.EditPartViewer;
-import org.eclipse.gef.ui.parts.ContentOutlinePage;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.ui.IActionBars;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Implementation of the {@link ContentOutlinePage} to display {@link UiElementNode}.
- *
- * @since GLE1
- */
-class UiContentOutlinePage extends ContentOutlinePage {
-
-    private GraphicalLayoutEditor mEditor;
-
-    private Action mAddAction;
-    private Action mDeleteAction;
-    private Action mUpAction;
-    private Action mDownAction;
-
-    private UiOutlineActions mUiActions = new UiOutlineActions();
-
-    public UiContentOutlinePage(GraphicalLayoutEditor editor, final EditPartViewer viewer) {
-        super(viewer);
-        mEditor = editor;
-        IconFactory factory = IconFactory.getInstance();
-
-        mAddAction = new Action("Add...") {
-            @Override
-            public void run() {
-                List<UiElementNode> nodes = getModelSelections();
-                UiElementNode node = nodes != null && nodes.size() > 0 ? nodes.get(0) : null;
-
-                mUiActions.doAdd(node, viewer.getControl().getShell());
-            }
-        };
-        mAddAction.setToolTipText("Adds a new element.");
-        mAddAction.setImageDescriptor(factory.getImageDescriptor("add")); //$NON-NLS-1$
-
-        mDeleteAction = new Action("Remove...") {
-            @Override
-            public void run() {
-                List<UiElementNode> nodes = getModelSelections();
-
-                mUiActions.doRemove(nodes, viewer.getControl().getShell());
-            }
-        };
-        mDeleteAction.setToolTipText("Removes an existing selected element.");
-        mDeleteAction.setImageDescriptor(factory.getImageDescriptor("delete")); //$NON-NLS-1$
-
-        mUpAction = new Action("Up") {
-            @Override
-            public void run() {
-                List<UiElementNode> nodes = getModelSelections();
-
-                mUiActions.doUp(nodes);
-            }
-        };
-        mUpAction.setToolTipText("Moves the selected element up");
-        mUpAction.setImageDescriptor(factory.getImageDescriptor("up")); //$NON-NLS-1$
-
-        mDownAction = new Action("Down") {
-            @Override
-            public void run() {
-                List<UiElementNode> nodes = getModelSelections();
-
-                mUiActions.doDown(nodes);
-            }
-        };
-        mDownAction.setToolTipText("Moves the selected element down");
-        mDownAction.setImageDescriptor(factory.getImageDescriptor("down")); //$NON-NLS-1$
-
-        // all actions disabled by default.
-        mAddAction.setEnabled(false);
-        mDeleteAction.setEnabled(false);
-        mUpAction.setEnabled(false);
-        mDownAction.setEnabled(false);
-
-        addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                ISelection selection = event.getSelection();
-
-                // the selection is never empty. The least it'll contain is the
-                // UiDocumentTreeEditPart object.
-                if (selection instanceof StructuredSelection) {
-                    StructuredSelection structSel = (StructuredSelection)selection;
-
-                    if (structSel.size() == 1 &&
-                            structSel.getFirstElement() instanceof UiDocumentTreeEditPart) {
-                        mDeleteAction.setEnabled(false);
-                        mUpAction.setEnabled(false);
-                        mDownAction.setEnabled(false);
-                    } else {
-                        mDeleteAction.setEnabled(true);
-                        mUpAction.setEnabled(true);
-                        mDownAction.setEnabled(true);
-                    }
-
-                    // the "add" button is always enabled, in order to be able to set the
-                    // initial root node
-                    mAddAction.setEnabled(true);
-                }
-            }
-        });
-    }
-
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    @Override
-    public void createControl(Composite parent) {
-        // create outline viewer page
-        getViewer().createControl(parent);
-
-        // configure outline viewer
-        getViewer().setEditPartFactory(new UiElementTreeEditPartFactory());
-
-        setupOutline();
-        setupContextMenu();
-        setupTooltip();
-        setupDoubleClick();
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.part.Page#setActionBars(org.eclipse.ui.IActionBars)
-     *
-     * Called automatically after createControl
-     */
-    @Override
-    public void setActionBars(IActionBars actionBars) {
-        IToolBarManager toolBarManager = actionBars.getToolBarManager();
-        toolBarManager.add(mAddAction);
-        toolBarManager.add(mDeleteAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(mUpAction);
-        toolBarManager.add(mDownAction);
-
-        IMenuManager menuManager = actionBars.getMenuManager();
-        menuManager.add(mAddAction);
-        menuManager.add(mDeleteAction);
-        menuManager.add(new Separator());
-        menuManager.add(mUpAction);
-        menuManager.add(mDownAction);
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.IPage#dispose()
-     */
-    @Override
-    public void dispose() {
-        breakConnectionWithEditor();
-
-        // dispose
-        super.dispose();
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.IPage#getControl()
-     */
-    @Override
-    public Control getControl() {
-        return getViewer().getControl();
-    }
-
-    void setNewEditor(GraphicalLayoutEditor editor) {
-        mEditor = editor;
-        setupOutline();
-    }
-
-    void breakConnectionWithEditor() {
-        // unhook outline viewer
-        mEditor.getSelectionSynchronizer().removeViewer(getViewer());
-    }
-
-    private void setupOutline() {
-
-        getViewer().setEditDomain(mEditor.getEditDomain());
-
-        // hook outline viewer
-        mEditor.getSelectionSynchronizer().addViewer(getViewer());
-
-        // initialize outline viewer with model
-        getViewer().setContents(mEditor.getModel());
-    }
-
-    private void setupContextMenu() {
-        MenuManager menuManager = new MenuManager();
-        menuManager.setRemoveAllWhenShown(true);
-        menuManager.addMenuListener(new IMenuListener() {
-            /**
-             * The menu is about to be shown. The menu manager has already been
-             * requested to remove any existing menu item. This method gets the
-             * tree selection and if it is of the appropriate type it re-creates
-             * the necessary actions.
-             */
-           public void menuAboutToShow(IMenuManager manager) {
-               List<UiElementNode> selected = getModelSelections();
-
-               if (selected != null) {
-                   doCreateMenuAction(manager, selected);
-                   return;
-               }
-               doCreateMenuAction(manager, null /* ui_node */);
-            }
-        });
-        Control control = getControl();
-        Menu contextMenu = menuManager.createContextMenu(control);
-        control.setMenu(contextMenu);
-    }
-
-    /**
-     * Adds the menu actions to the context menu when the given UI node is selected in
-     * the tree view.
-     *
-     * @param manager The context menu manager
-     * @param selected The UI node selected in the tree. Can be null, in which case the root
-     *                is to be modified.
-     */
-    private void doCreateMenuAction(IMenuManager manager, List<UiElementNode> selected) {
-
-        if (selected != null) {
-            boolean hasXml = false;
-            for (UiElementNode uiNode : selected) {
-                if (uiNode.getXmlNode() != null) {
-                    hasXml = true;
-                    break;
-                }
-            }
-
-            if (hasXml) {
-                manager.add(new CopyCutAction(mEditor.getLayoutEditor(), mEditor.getClipboard(),
-                        null, selected, true /* cut */));
-                manager.add(new CopyCutAction(mEditor.getLayoutEditor(), mEditor.getClipboard(),
-                        null, selected, false /* cut */));
-
-                // Can't paste with more than one element selected (the selection is the target)
-                if (selected.size() <= 1) {
-                    // Paste is not valid if it would add a second element on a terminal element
-                    // which parent is a document -- an XML document can only have one child. This
-                    // means paste is valid if the current UI node can have children or if the parent
-                    // is not a document.
-                    UiElementNode ui_root = selected.get(0).getUiRoot();
-                    if (ui_root.getDescriptor().hasChildren() ||
-                            !(ui_root.getUiParent() instanceof UiDocumentNode)) {
-                        manager.add(new PasteAction(mEditor.getLayoutEditor(),
-                                mEditor.getClipboard(),
-                                selected.get(0)));
-                    }
-                }
-                manager.add(new Separator());
-            }
-        }
-
-        // Append "add" and "remove" actions. They do the same thing as the add/remove
-        // buttons on the side.
-        //
-        // "Add" makes sense only if there's 0 or 1 item selected since the
-        // one selected item becomes the target.
-        if (selected == null || selected.size() <= 1) {
-            manager.add(mAddAction);
-        }
-
-        if (selected != null) {
-            manager.add(mDeleteAction);
-            manager.add(new Separator());
-
-            manager.add(mUpAction);
-            manager.add(mDownAction);
-        }
-
-        if (selected != null && selected.size() == 1) {
-            manager.add(new Separator());
-
-            Action propertiesAction = new Action("Properties") {
-                @Override
-                public void run() {
-                    EclipseUiHelper.showView(EclipseUiHelper.PROPERTY_SHEET_VIEW_ID,
-                            true /* activate */);
-                }
-            };
-            propertiesAction.setToolTipText("Displays properties of the selected element.");
-            manager.add(propertiesAction);
-        }
-    }
-
-    /**
-     * Updates the outline view with the model of the {@link IGraphicalLayoutEditor}.
-     * <p/>
-     * This attemps to preserve the selection, if any.
-     */
-    public void reloadModel() {
-        // Attemps to preserve the UiNode selection, if any
-        List<UiElementNode> uiNodes = null;
-        try {
-            // get current selection using the model rather than the edit part as
-            // reloading the content may change the actual edit part.
-            uiNodes = getModelSelections();
-
-            // perform the update
-            getViewer().setContents(mEditor.getModel());
-
-        } finally {
-            // restore selection
-            if (uiNodes != null) {
-                setModelSelection(uiNodes.get(0));
-            }
-        }
-    }
-
-    /**
-     * Returns the currently selected element, if any, in the viewer.
-     * This returns the viewer's elements (i.e. an {@link UiElementTreeEditPart})
-     * and not the underlying model node.
-     * <p/>
-     * When there is no actual selection, this might still return the root node,
-     * which is of type {@link UiDocumentTreeEditPart}.
-     */
-    @SuppressWarnings("unchecked")
-    private List<UiElementTreeEditPart> getViewerSelections() {
-        ISelection selection = getSelection();
-        if (selection instanceof StructuredSelection) {
-            StructuredSelection structuredSelection = (StructuredSelection)selection;
-
-            if (structuredSelection.size() > 0) {
-                ArrayList<UiElementTreeEditPart> selected = new ArrayList<UiElementTreeEditPart>();
-
-                for (Iterator it = structuredSelection.iterator(); it.hasNext(); ) {
-                    Object selectedObj = it.next();
-
-                    if (selectedObj instanceof UiElementTreeEditPart) {
-                        selected.add((UiElementTreeEditPart) selectedObj);
-                    }
-                }
-
-                return selected.size() > 0 ? selected : null;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the currently selected model element, which is either an
-     * {@link UiViewTreeEditPart} or an {@link UiLayoutTreeEditPart}.
-     * <p/>
-     * Returns null if there is no selection or if the implicit root is "selected"
-     * (which actually represents the lack of a real element selection.)
-     */
-    private List<UiElementNode> getModelSelections() {
-
-        List<UiElementTreeEditPart> parts = getViewerSelections();
-
-        if (parts != null) {
-            ArrayList<UiElementNode> selected = new ArrayList<UiElementNode>();
-
-            for (UiElementTreeEditPart part : parts) {
-                if (part instanceof UiViewTreeEditPart || part instanceof UiLayoutTreeEditPart) {
-                    selected.add((UiElementNode) part.getModel());
-                }
-            }
-
-            return selected.size() > 0 ? selected : null;
-        }
-
-        return null;
-    }
-
-    /**
-     * Selects the corresponding edit part in the tree viewer.
-     */
-    private void setViewerSelection(UiElementTreeEditPart selectedPart) {
-        if (selectedPart != null && !(selectedPart instanceof UiDocumentTreeEditPart)) {
-            LinkedList<UiElementTreeEditPart> segments = new LinkedList<UiElementTreeEditPart>();
-            for (UiElementTreeEditPart part = selectedPart;
-                    !(part instanceof UiDocumentTreeEditPart);
-                    part = (UiElementTreeEditPart) part.getParent()) {
-                segments.add(0, part);
-            }
-            setSelection(new TreeSelection(new TreePath(segments.toArray())));
-        }
-    }
-
-    /**
-     * Selects the corresponding model element in the tree viewer.
-     */
-    private void setModelSelection(UiElementNode uiNodeToSelect) {
-        if (uiNodeToSelect != null) {
-
-            // find an edit part that has the requested model element
-            UiElementTreeEditPart part = findPartForModel(
-                    (UiElementTreeEditPart) getViewer().getContents(),
-                    uiNodeToSelect);
-
-            // if we found a part, select it and reveal it
-            if (part != null) {
-                setViewerSelection(part);
-                getViewer().reveal(part);
-            }
-        }
-    }
-
-    /**
-     * Utility method that tries to find an edit part that matches a given model UI node.
-     *
-     * @param rootPart The root of the viewer edit parts
-     * @param uiNode The UI node model to find
-     * @return The part that matches the model or null if it's not in the sub tree.
-     */
-    private UiElementTreeEditPart findPartForModel(UiElementTreeEditPart rootPart,
-            UiElementNode uiNode) {
-        if (rootPart.getModel() == uiNode) {
-            return rootPart;
-        }
-
-        for (Object part : rootPart.getChildren()) {
-            if (part instanceof UiElementTreeEditPart) {
-                UiElementTreeEditPart found = findPartForModel(
-                        (UiElementTreeEditPart) part, uiNode);
-                if (found != null) {
-                    return found;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets up a custom tooltip when hovering over tree items.
-     * <p/>
-     * The tooltip will display the element's javadoc, if any, or the item's getText otherwise.
-     */
-    private void setupTooltip() {
-        final Tree tree = (Tree) getControl();
-
-        /*
-         * Reference:
-         * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
-         */
-
-        final Listener listener = new Listener() {
-            Shell tip = null;
-            Label label  = null;
-
-            public void handleEvent(Event event) {
-                switch(event.type) {
-                case SWT.Dispose:
-                case SWT.KeyDown:
-                case SWT.MouseExit:
-                case SWT.MouseDown:
-                case SWT.MouseMove:
-                    if (tip != null) {
-                        tip.dispose();
-                        tip = null;
-                        label = null;
-                    }
-                    break;
-                case SWT.MouseHover:
-                    if (tip != null) {
-                        tip.dispose();
-                        tip = null;
-                        label = null;
-                    }
-
-                    String tooltip = null;
-
-                    TreeItem item = tree.getItem(new Point(event.x, event.y));
-                    if (item != null) {
-                        Object data = item.getData();
-                        if (data instanceof UiElementTreeEditPart) {
-                            Object model = ((UiElementTreeEditPart) data).getModel();
-                            if (model instanceof UiElementNode) {
-                                tooltip = ((UiElementNode) model).getDescriptor().getTooltip();
-                            }
-                        }
-
-                        if (tooltip == null) {
-                            tooltip = item.getText();
-                        } else {
-                            tooltip = item.getText() + ":\r" + tooltip;
-                        }
-                    }
-
-
-                    if (tooltip != null) {
-                        Shell shell = tree.getShell();
-                        Display display = tree.getDisplay();
-
-                        tip = new Shell(shell, SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
-                        tip.setBackground(display .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-                        FillLayout layout = new FillLayout();
-                        layout.marginWidth = 2;
-                        tip.setLayout(layout);
-                        label = new Label(tip, SWT.NONE);
-                        label.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
-                        label.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-                        label.setData("_TABLEITEM", item);
-                        label.setText(tooltip);
-                        label.addListener(SWT.MouseExit, this);
-                        label.addListener(SWT.MouseDown, this);
-                        Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-                        Rectangle rect = item.getBounds(0);
-                        Point pt = tree.toDisplay(rect.x, rect.y);
-                        tip.setBounds(pt.x, pt.y, size.x, size.y);
-                        tip.setVisible(true);
-                    }
-                }
-            }
-        };
-
-        tree.addListener(SWT.Dispose, listener);
-        tree.addListener(SWT.KeyDown, listener);
-        tree.addListener(SWT.MouseMove, listener);
-        tree.addListener(SWT.MouseHover, listener);
-    }
-
-    /**
-     * Sets up double-click action on the tree.
-     * <p/>
-     * By default, double-click (a.k.a. "default selection") on a valid list item will
-     * show the property view.
-     */
-    private void setupDoubleClick() {
-        final Tree tree = (Tree) getControl();
-
-        tree.addListener(SWT.DefaultSelection, new Listener() {
-            public void handleEvent(Event event) {
-                EclipseUiHelper.showView(EclipseUiHelper.PROPERTY_SHEET_VIEW_ID,
-                        true /* activate */);
-            }
-        });
-    }
-
-    // ---------------
-
-    private class UiOutlineActions extends UiActions {
-
-        @Override
-        protected UiDocumentNode getRootNode() {
-            return mEditor.getModel(); // this is LayoutEditor.getUiRootNode()
-        }
-
-        // Select the new item
-        @Override
-        protected void selectUiNode(UiElementNode uiNodeToSelect) {
-            setModelSelection(uiNodeToSelect);
-        }
-
-        @Override
-        public void commitPendingXmlChanges() {
-            // Pass. There is nothing to commit before the XML is changed here.
-        }
-
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java
deleted file mode 100644
index 3443272..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.layoutlib.api.IXmlPullParser;
-
-import org.w3c.dom.Node;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@link IXmlPullParser} implementation on top of {@link UiElementNode}.
- * <p/>It's designed to work on layout files, and will most likely not work on other resource
- * files.
- */
-public final class UiElementPullParser extends BasePullParser {
-    
-    private final ArrayList<UiElementNode> mNodeStack = new ArrayList<UiElementNode>();
-    private UiElementNode mRoot;
-    
-    public UiElementPullParser(UiElementNode top) {
-        super();
-        mRoot = top;
-        push(mRoot);
-    }
-    
-    private UiElementNode getCurrentNode() {
-        if (mNodeStack.size() > 0) {
-            return mNodeStack.get(mNodeStack.size()-1);
-        }
-        
-        return null;
-    }
-    
-    private Node getAttribute(int i) {
-        if (mParsingState != START_TAG) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        // get the current uiNode
-        UiElementNode uiNode = getCurrentNode();
-        
-        // get its xml node
-        Node xmlNode = uiNode.getXmlNode();
-
-        if (xmlNode != null) {
-            return xmlNode.getAttributes().item(i);
-        }
-
-        return null;
-    }
-    
-    private void push(UiElementNode node) {
-        mNodeStack.add(node);
-    }
-    
-    private UiElementNode pop() {
-        return mNodeStack.remove(mNodeStack.size()-1);
-    }
-
-    // ------------- IXmlPullParser --------
-
-    /**
-     * {@inheritDoc}
-     * 
-     * This implementation returns the underlying DOM node.
-     */
-    public Object getViewKey() {
-        return getCurrentNode();
-    }
-
-    // ------------- XmlPullParser --------
-
-    public String getPositionDescription() {
-        return "XML DOM element depth:" + mNodeStack.size();
-    }
-
-    public int getAttributeCount() {
-        UiElementNode node = getCurrentNode();
-        if (node != null) {
-            return node.getUiAttributes().size();
-        }
-
-        return 0;
-    }
-
-    public String getAttributeName(int i) {
-        Node attribute = getAttribute(i);
-        if (attribute != null) {
-            return attribute.getLocalName();
-        }
-
-        return null;
-    }
-
-    public String getAttributeNamespace(int i) {
-        Node attribute = getAttribute(i);
-        if (attribute != null) {
-            return attribute.getNamespaceURI();
-        }
-        return ""; //$NON-NLS-1$
-    }
-
-    public String getAttributePrefix(int i) {
-        Node attribute = getAttribute(i);
-        if (attribute != null) {
-            return attribute.getPrefix();
-        }
-        return null;
-    }
-
-    public String getAttributeValue(int i) {
-        Node attribute = getAttribute(i);
-        if (attribute != null) {
-            return attribute.getNodeValue();
-        }
-        
-        return null;
-    }
-
-    public String getAttributeValue(String namespace, String localName) {
-        // get the current uiNode
-        UiElementNode uiNode = getCurrentNode();
-        
-        // get its xml node
-        Node xmlNode = uiNode.getXmlNode();
-        
-        if (xmlNode != null) {
-            Node attribute = xmlNode.getAttributes().getNamedItemNS(namespace, localName);
-            if (attribute != null) {
-                return attribute.getNodeValue();
-            }
-        }
-
-        return null;
-    }
-
-    public int getDepth() {
-        return mNodeStack.size();
-    }
-
-    public String getName() {
-        if (mParsingState == START_TAG || mParsingState == END_TAG) {
-            return getCurrentNode().getDescriptor().getXmlLocalName();
-        }
-
-        return null;
-    }
-
-    public String getNamespace() {
-        if (mParsingState == START_TAG || mParsingState == END_TAG) {
-            return getCurrentNode().getDescriptor().getNamespace();
-        }
-
-        return null;
-    }
-
-    public String getPrefix() {
-        if (mParsingState == START_TAG || mParsingState == END_TAG) {
-            // FIXME will NEVER work
-            if (getCurrentNode().getDescriptor().getXmlLocalName().startsWith("android:")) { //$NON-NLS-1$
-                return "android"; //$NON-NLS-1$
-            }
-        }
-
-        return null;
-    }
-
-    public boolean isEmptyElementTag() throws XmlPullParserException {
-        if (mParsingState == START_TAG) {
-            return getCurrentNode().getUiChildren().size() == 0;
-        }
-        
-        throw new XmlPullParserException("Call to isEmptyElementTag while not in START_TAG",
-                this, null);
-    }
-    
-    @Override
-    public void onNextFromStartDocument() {
-        onNextFromStartTag();
-    }
-    
-    @Override
-    public void onNextFromStartTag() {
-        // get the current node, and look for text or children (children first)
-        UiElementNode node = getCurrentNode();
-        List<UiElementNode> children = node.getUiChildren();
-        if (children.size() > 0) {
-            // move to the new child, and don't change the state.
-            push(children.get(0));
-            
-            // in case the current state is CURRENT_DOC, we set the proper state.
-            mParsingState = START_TAG;
-        } else {
-            if (mParsingState == START_DOCUMENT) {
-                // this handles the case where there's no node.
-                mParsingState = END_DOCUMENT;
-            } else {
-                mParsingState = END_TAG;
-            }
-        }
-    }
-    
-    @Override
-    public void onNextFromEndTag() {
-        // look for a sibling. if no sibling, go back to the parent
-        UiElementNode node = getCurrentNode();
-        node = node.getUiNextSibling();
-        if (node != null) {
-            // to go to the sibling, we need to remove the current node,
-            pop();
-            // and add its sibling.
-            push(node);
-            mParsingState = START_TAG;
-        } else {
-            // move back to the parent
-            pop();
-            
-            // we have only one element left (mRoot), then we're done with the document.
-            if (mNodeStack.size() == 1) {
-                mParsingState = END_DOCUMENT;
-            } else {
-                mParsingState = END_TAG;
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiPropertySheetPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiPropertySheetPage.java
deleted file mode 100644
index 43b73b0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiPropertySheetPage.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.ui.views.properties.PropertySheetEntry;
-import org.eclipse.ui.views.properties.PropertySheetPage;
-
-/**
- * A customized property sheet page for the graphical layout editor.
- * <p/>
- * Currently it just provides a custom tooltip to display attributes javadocs.
- *
- * @since GLE1
- */
-public class UiPropertySheetPage extends PropertySheetPage {
-
-
-    public UiPropertySheetPage() {
-        super();
-    }
-
-    @Override
-    public void createControl(Composite parent) {
-        super.createControl(parent);
-
-        setupTooltip();
-    }
-
-    /**
-     * Sets up a custom tooltip when hovering over tree items.
-     * <p/>
-     * The tooltip will display the element's javadoc, if any, or the item's getText otherwise.
-     */
-    private void setupTooltip() {
-        final Tree tree = (Tree) getControl();
-
-        /*
-         * Reference:
-         * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
-         */
-
-        final Listener listener = new Listener() {
-            Shell tip = null;
-            Label label  = null;
-
-            public void handleEvent(Event event) {
-                switch(event.type) {
-                case SWT.Dispose:
-                case SWT.KeyDown:
-                case SWT.MouseExit:
-                case SWT.MouseDown:
-                case SWT.MouseMove:
-                    if (tip != null) {
-                        tip.dispose();
-                        tip = null;
-                        label = null;
-                    }
-                    break;
-                case SWT.MouseHover:
-                    if (tip != null) {
-                        tip.dispose();
-                        tip = null;
-                        label = null;
-                    }
-
-                    String tooltip = null;
-
-                    TreeItem item = tree.getItem(new Point(event.x, event.y));
-                    if (item != null) {
-                        Object data = item.getData();
-                        if (data instanceof PropertySheetEntry) {
-                            tooltip = ((PropertySheetEntry) data).getDescription();
-                        }
-
-                        if (tooltip == null) {
-                            tooltip = item.getText();
-                        } else {
-                            tooltip = item.getText() + ":\r" + tooltip;
-                        }
-                    }
-
-                    if (tooltip != null) {
-                        Shell shell = tree.getShell();
-                        Display display = tree.getDisplay();
-
-                        tip = new Shell(shell, SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
-                        tip.setBackground(display .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-                        FillLayout layout = new FillLayout();
-                        layout.marginWidth = 2;
-                        tip.setLayout(layout);
-                        label = new Label(tip, SWT.NONE);
-                        label.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
-                        label.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-                        label.setData("_TABLEITEM", item);
-                        label.setText(tooltip);
-                        label.addListener(SWT.MouseExit, this);
-                        label.addListener(SWT.MouseDown, this);
-                        Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-                        Rectangle rect = item.getBounds(0);
-                        Point pt = tree.toDisplay(rect.x, rect.y);
-                        tip.setBounds(pt.x, pt.y, size.x, size.y);
-                        tip.setVisible(true);
-                    }
-                }
-            }
-        };
-
-        tree.addListener(SWT.Dispose, listener);
-        tree.addListener(SWT.KeyDown, listener);
-        tree.addListener(SWT.MouseMove, listener);
-        tree.addListener(SWT.MouseHover, listener);
-
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/WidgetPullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/WidgetPullParser.java
deleted file mode 100644
index 50d259f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/WidgetPullParser.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.layoutlib.api.IXmlPullParser;
-import com.android.sdklib.SdkConstants;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-/**
- * {@link IXmlPullParser} implementation to render android widget bitmap.
- * <p/>The parser emulates a layout that contains just one widget, described by the
- * {@link ViewElementDescriptor} passed in the constructor.
- */
-public class WidgetPullParser extends BasePullParser {
-    
-    private final ViewElementDescriptor mDescriptor;
-    private String[][] mAttributes = new String[][] {
-            { "text", null },
-            { "layout_width", "wrap_content" },
-            { "layout_height", "wrap_content" },
-    };
-
-    public WidgetPullParser(ViewElementDescriptor descriptor) {
-        mDescriptor = descriptor;
-        
-        String[] segments = mDescriptor.getCanonicalClassName().split(AndroidConstants.RE_DOT);
-        mAttributes[0][1] = segments[segments.length-1];
-    }
-
-    public Object getViewKey() {
-        // we need a viewKey or the ILayoutResult will not contain any ILayoutViewInfo
-        return mDescriptor;
-    }
-
-    public int getAttributeCount() {
-        return mAttributes.length; // text attribute
-    }
-
-    public String getAttributeName(int index) {
-        if (index < mAttributes.length) {
-            return mAttributes[index][0];
-        }
-        
-        return null;
-    }
-
-    public String getAttributeNamespace(int index) {
-        return SdkConstants.NS_RESOURCES;
-    }
-
-    public String getAttributePrefix(int index) {
-        // pass
-        return null;
-    }
-
-    public String getAttributeValue(int index) {
-        if (index < mAttributes.length) {
-            return mAttributes[index][1];
-        }
-        
-        return null;
-    }
-
-    public String getAttributeValue(String ns, String name) {
-        if (SdkConstants.NS_RESOURCES.equals(ns)) {
-            for (String[] attribute : mAttributes) {
-                if (name.equals(attribute[0])) {
-                    return attribute[1];
-                }
-            }
-        }
-        
-        return null;
-    }
-
-    public int getDepth() {
-        // pass
-        return 0;
-    }
-
-    public String getName() {
-        return mDescriptor.getXmlLocalName();
-    }
-
-    public String getNamespace() {
-        // pass
-        return null;
-    }
-
-    public String getPositionDescription() {
-        // pass
-        return null;
-    }
-
-    public String getPrefix() {
-        // pass
-        return null;
-    }
-
-    public boolean isEmptyElementTag() throws XmlPullParserException {
-        if (mParsingState == START_TAG) {
-            return true;
-        }
-        
-        throw new XmlPullParserException("Call to isEmptyElementTag while not in START_TAG",
-                this, null);
-    }
-
-    @Override
-    public void onNextFromStartDocument() {
-        // just go to start_tag
-        mParsingState = START_TAG;
-    }
-
-    @Override
-    public void onNextFromStartTag() {
-        // since we have no children, just go to end_tag
-        mParsingState = END_TAG;
-    }
-
-    @Override
-    public void onNextFromEndTag() {
-        // just one tag. we are done.
-        mParsingState = END_DOCUMENT;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigEditDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigEditDialog.java
deleted file mode 100644
index 5c9ceef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigEditDialog.java
+++ /dev/null
@@ -1,304 +0,0 @@
-package com.android.ide.eclipse.adt.internal.editors.layout.configuration;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.VersionQualifier;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.ConfigurationState;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.IQualifierFilter;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.regex.Pattern;
-
-/**
- * Dialog to edit both a {@link LayoutDevice}, and a {@link FolderConfiguration} at the same time.
- */
-public class ConfigEditDialog extends GridDialog {
-
-    private static final Pattern FLOAT_PATTERN = Pattern.compile("\\d*(\\.\\d?)?");
-
-
-    private final FolderConfiguration mConfig = new FolderConfiguration();
-
-    private ConfigurationSelector mConfigSelector;
-    private Composite mStatusComposite;
-    private Label mStatusLabel;
-    private Label mStatusImage;
-
-    private Image mError;
-
-    private String mDeviceName;
-    private String mConfigName;
-    private float mXDpi = Float.NaN;
-    private float mYDpi = Float.NaN;
-
-
-    public ConfigEditDialog(Shell parentShell, FolderConfiguration config) {
-        super(parentShell, 1, false);
-        mConfig.set(config);
-    }
-
-    public void setDeviceName(String name) {
-        mDeviceName = name;
-    }
-
-    public String getDeviceName() {
-        return mDeviceName;
-    }
-
-    public void setXDpi(float xdpi) {
-        mXDpi = xdpi;
-    }
-
-    public float getXDpi() {
-        return mXDpi;
-    }
-
-    public void setYDpi(float ydpi) {
-        mYDpi = ydpi;
-    }
-
-    public float getYDpi() {
-        return mYDpi;
-    }
-
-    public void setConfigName(String name) {
-        mConfigName = name;
-    }
-
-    public String getConfigName() {
-        return mConfigName;
-    }
-
-    public void setConfig(FolderConfiguration config) {
-        mConfig.set(config);
-    }
-
-    public void getConfig(FolderConfiguration config) {
-        config.set(mConfig);
-    }
-
-    @Override
-    public void createDialogContent(Composite parent) {
-        mError = IconFactory.getInstance().getIcon("error"); //$NON-NLS-1$
-
-        Group deviceGroup = new Group(parent, SWT.NONE);
-        deviceGroup.setText("Device");
-        deviceGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
-        deviceGroup.setLayout(new GridLayout(2, false));
-
-        Label l = new Label(deviceGroup, SWT.None);
-        l.setText("Name");
-
-        final Text deviceNameText = new Text(deviceGroup, SWT.BORDER);
-        deviceNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        if (mDeviceName != null) {
-            deviceNameText.setText(mDeviceName);
-        }
-        deviceNameText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mDeviceName = deviceNameText.getText().trim();
-                validateOk();
-            }
-        });
-
-
-        VerifyListener floatVerifier = new VerifyListener() {
-            public void verifyText(VerifyEvent event) {
-                // combine the current content and the new text
-                String text = ((Text)event.widget).getText();
-                text = text.substring(0, event.start) + event.text + text.substring(event.end);
-
-                // now make sure it's a match for the regex
-                event.doit = FLOAT_PATTERN.matcher(text).matches();
-            }
-        };
-
-        l = new Label(deviceGroup, SWT.None);
-        l.setText("x dpi");
-
-        final Text deviceXDpiText = new Text(deviceGroup, SWT.BORDER);
-        deviceXDpiText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        if (Float.isNaN(mXDpi) == false) {
-            deviceXDpiText.setText(String.format("%.1f", mXDpi)); //$NON-NLS-1$
-        }
-        deviceXDpiText.addVerifyListener(floatVerifier);
-        deviceXDpiText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                String value = deviceXDpiText.getText();
-                if (value.length() == 0) {
-                    mXDpi = Float.NaN;
-                } else {
-                    mXDpi = Float.parseFloat(value);
-                }
-            }
-        });
-
-        l = new Label(deviceGroup, SWT.None);
-        l.setText("y dpi");
-
-        final Text deviceYDpiText = new Text(deviceGroup, SWT.BORDER);
-        deviceYDpiText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        if (Float.isNaN(mYDpi) == false) {
-            deviceYDpiText.setText(String.format("%.1f", mYDpi)); //$NON-NLS-1$
-        }
-        deviceYDpiText.addVerifyListener(floatVerifier);
-        deviceYDpiText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                String value = deviceYDpiText.getText();
-                if (value.length() == 0) {
-                    mYDpi = Float.NaN;
-                } else {
-                    mYDpi = Float.parseFloat(value);
-                }
-            }
-        });
-
-        Group configGroup = new Group(parent, SWT.NONE);
-        configGroup.setText("Configuration");
-        configGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
-        configGroup.setLayout(new GridLayout(2, false));
-
-        l = new Label(configGroup, SWT.None);
-        l.setText("Name");
-
-        final Text configNameText = new Text(configGroup, SWT.BORDER);
-        configNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        if (mConfigName != null) {
-            configNameText.setText(mConfigName);
-        }
-        configNameText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mConfigName = configNameText.getText().trim();
-                validateOk();
-            }
-        });
-
-        mConfigSelector = new ConfigurationSelector(configGroup, true /*deviceMode*/);
-        // configure the selector to be in "device mode" and not accept language/region/version
-        // since those are selected from a different combo
-        // FIXME: add version combo.
-        mConfigSelector.setQualifierFilter(new IQualifierFilter() {
-            public boolean accept(ResourceQualifier qualifier) {
-                if (qualifier instanceof LanguageQualifier ||
-                        qualifier instanceof RegionQualifier ||
-                        qualifier instanceof VersionQualifier) {
-                    return false;
-                }
-
-                return true;
-            }
-        });
-        mConfigSelector.setConfiguration(mConfig);
-        GridData gd;
-        mConfigSelector.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-        gd.widthHint = ConfigurationSelector.WIDTH_HINT;
-        gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
-
-        // add a listener to check on the validity of the FolderConfiguration as
-        // they are built.
-        mConfigSelector.setOnChangeListener(new Runnable() {
-            public void run() {
-                if (mConfigSelector.getState() == ConfigurationState.OK) {
-                    mConfigSelector.getConfiguration(mConfig);
-                }
-
-                validateOk();
-            }
-        });
-
-        mStatusComposite = new Composite(parent, SWT.NONE);
-        mStatusComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        GridLayout gl = new GridLayout(2, false);
-        mStatusComposite.setLayout(gl);
-        gl.marginHeight = gl.marginWidth = 0;
-
-        mStatusImage = new Label(mStatusComposite, SWT.NONE);
-        mStatusLabel = new Label(mStatusComposite, SWT.NONE);
-        mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        resetStatus();
-    }
-
-    @Override
-    protected Control createContents(Composite parent) {
-        Control c = super.createContents(parent);
-        validateOk();
-        return c;
-    }
-
-    /**
-     * resets the status label to show the file that will be created.
-     */
-    private void resetStatus() {
-        String displayString = Dialog.shortenText(
-                String.format("Config: %1$s", mConfig.toString()),
-                mStatusLabel);
-        mStatusLabel.setText(displayString);
-    }
-
-    private void setError(String text) {
-        String displayString = Dialog.shortenText(text, mStatusLabel);
-        mStatusLabel.setText(displayString);
-        mStatusImage.setImage(mError);
-        getButton(IDialogConstants.OK_ID).setEnabled(false);
-    }
-
-    private void validateOk() {
-        // check the device name
-        if (mDeviceName == null || mDeviceName.length() == 0) {
-            setError("Device name must not be empty");
-            return;
-        }
-
-        // check the config name
-        if (mConfigName == null || mConfigName.length() == 0) {
-            setError("Configuration name must not be empty");
-            return;
-        }
-
-        // and check the config itself
-        ConfigurationState state = mConfigSelector.getState();
-
-        switch (state) {
-            case INVALID_CONFIG:
-                ResourceQualifier invalidQualifier = mConfigSelector.getInvalidQualifier();
-                setError(String.format(
-                        "Invalid Configuration: %1$s has no filter set.",
-                        invalidQualifier.getName()));
-                return;
-            case REGION_WITHOUT_LANGUAGE:
-                setError("The Region qualifier requires the Language qualifier.");
-                return;
-        }
-
-        // no error
-        mStatusImage.setImage(null);
-        resetStatus();
-        getButton(IDialogConstants.OK_ID).setEnabled(true);
-
-        // need to relayout, because of the change in size in mErrorImage.
-        mStatusComposite.layout();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigManagerDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigManagerDialog.java
deleted file mode 100644
index 61d870b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigManagerDialog.java
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.configuration;
-
-import com.android.ddmuilib.TableHelper;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDeviceManager;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Tree;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Dialog to view the layout devices with action button to create/edit/delete/copy layout devices
- * and configs.
- *
- */
-public class ConfigManagerDialog extends GridDialog {
-
-    private final static String COL_NAME = AdtPlugin.PLUGIN_ID + ".configmanager.name"; //$NON-NLS-1$
-    private final static String COL_CONFIG = AdtPlugin.PLUGIN_ID + ".configmanager.config"; //$NON-NLS-1$
-
-    /**
-     * enum to represent the different origin of the layout devices.
-     */
-    private static enum DeviceType {
-        DEFAULT("Default"),
-        ADDON("Add-on"),
-        CUSTOM("Custom");
-
-        private final String mDisplay;
-
-        DeviceType(String display) {
-            mDisplay = display;
-        }
-
-        String getDisplayString() {
-            return mDisplay;
-        }
-    }
-
-    /**
-     * simple class representing the tree selection with the proper types.
-     */
-    private static class DeviceSelection {
-        public DeviceSelection(DeviceType type, LayoutDevice device,
-                Entry<String, FolderConfiguration> entry) {
-            this.type = type;
-            this.device = device;
-            this.entry = entry;
-        }
-
-        final DeviceType type;
-        final LayoutDevice device;
-        final Entry<String, FolderConfiguration> entry;
-    }
-
-    private final LayoutDeviceManager mManager;
-
-    private TreeViewer mTreeViewer;
-    private Button mNewButton;
-    private Button mEditButton;
-    private Button mCopyButton;
-    private Button mDeleteButton;
-
-    /**
-     * Content provider of the {@link TreeViewer}. The expected input is
-     * {@link LayoutDeviceManager}.
-     *
-     */
-    private final static class DeviceContentProvider implements ITreeContentProvider {
-        private final static DeviceType[] sCategory = new DeviceType[] {
-            DeviceType.DEFAULT, DeviceType.ADDON, DeviceType.CUSTOM
-        };
-
-        private LayoutDeviceManager mLayoutDeviceManager;
-
-        public DeviceContentProvider() {
-        }
-
-        public Object[] getElements(Object inputElement) {
-            return sCategory;
-        }
-
-        public Object[] getChildren(Object parentElement) {
-            if (parentElement instanceof DeviceType) {
-                if (DeviceType.DEFAULT.equals(parentElement)) {
-                    return mLayoutDeviceManager.getDefaultLayoutDevices().toArray();
-                } else if (DeviceType.ADDON.equals(parentElement)) {
-                    return mLayoutDeviceManager.getAddOnLayoutDevice().toArray();
-                } else if (DeviceType.CUSTOM.equals(parentElement)) {
-                    return mLayoutDeviceManager.getUserLayoutDevices().toArray();
-                }
-            } else if (parentElement instanceof LayoutDevice) {
-                LayoutDevice device = (LayoutDevice)parentElement;
-                return device.getConfigs().entrySet().toArray();
-            }
-
-            return null;
-        }
-
-        public Object getParent(Object element) {
-            // parent cannot be computed. this is fine.
-            return null;
-        }
-
-        public boolean hasChildren(Object element) {
-            if (element instanceof DeviceType) {
-                if (DeviceType.DEFAULT.equals(element)) {
-                    return mLayoutDeviceManager.getDefaultLayoutDevices().size() > 0;
-                } else if (DeviceType.ADDON.equals(element)) {
-                    return mLayoutDeviceManager.getAddOnLayoutDevice().size() > 0;
-                } else if (DeviceType.CUSTOM.equals(element)) {
-                    return mLayoutDeviceManager.getUserLayoutDevices().size() > 0;
-                }
-            } else if (element instanceof LayoutDevice) {
-                LayoutDevice device = (LayoutDevice)element;
-                return device.getConfigs().size() > 0;
-            }
-
-            return false;
-        }
-
-
-        public void dispose() {
-            // nothing to dispose
-        }
-
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            if (newInput instanceof LayoutDeviceManager) {
-                mLayoutDeviceManager = (LayoutDeviceManager)newInput;
-                return;
-            }
-
-            // when the dialog closes we get null input
-            if (newInput != null) {
-                throw new IllegalArgumentException(
-                        "ConfigContentProvider requires input to be LayoutDeviceManager");
-            }
-        }
-    }
-
-    /**
-     * Label provider for the {@link TreeViewer}.
-     * Supported elements are {@link DeviceType}, {@link LayoutDevice}, and {@link Entry} (where
-     * the key is a {@link String} object, and the value is a {@link FolderConfiguration} object).
-     *
-     */
-    private final static class DeviceLabelProvider implements ITableLabelProvider {
-
-        public String getColumnText(Object element, int columnIndex) {
-            if (element instanceof DeviceType) {
-                if (columnIndex == 0) {
-                    return ((DeviceType)element).getDisplayString();
-                }
-            } else if (element instanceof LayoutDevice) {
-                if (columnIndex == 0) {
-                    return ((LayoutDevice)element).getName();
-                }
-            } else if (element instanceof Entry<?, ?>) {
-                if (columnIndex == 0) {
-                    return (String)((Entry<?,?>)element).getKey();
-                } else {
-                    return ((Entry<?,?>)element).getValue().toString();
-                }
-            }
-            return null;
-        }
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            // no image
-            return null;
-        }
-
-        public void addListener(ILabelProviderListener listener) {
-            // no listener
-        }
-
-        public void removeListener(ILabelProviderListener listener) {
-            // no listener
-        }
-
-        public void dispose() {
-            // nothing to dispose
-        }
-
-        public boolean isLabelProperty(Object element, String property) {
-            return false;
-        }
-    }
-
-    protected ConfigManagerDialog(Shell parentShell) {
-        super(parentShell, 2, false);
-        mManager = Sdk.getCurrent().getLayoutDeviceManager();
-    }
-
-    @Override
-    protected int getShellStyle() {
-        return super.getShellStyle() | SWT.RESIZE;
-    }
-
-    @Override
-    protected void configureShell(Shell newShell) {
-        super.configureShell(newShell);
-        newShell.setText("Device Configurations");
-    }
-
-    @Override
-    public void createDialogContent(final Composite parent) {
-        GridData gd;
-        GridLayout gl;
-
-        Tree tree = new Tree(parent, SWT.SINGLE | SWT.FULL_SELECTION);
-        tree.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
-        gd.widthHint = 700;
-
-        tree.setHeaderVisible(true);
-        tree.setLinesVisible(true);
-        TableHelper.createTreeColumn(tree, "Name", SWT.LEFT, 150, COL_NAME,
-                AdtPlugin.getDefault().getPreferenceStore());
-        TableHelper.createTreeColumn(tree, "Configuration", SWT.LEFT, 500, COL_CONFIG,
-                AdtPlugin.getDefault().getPreferenceStore());
-
-        mTreeViewer = new TreeViewer(tree);
-        mTreeViewer.setContentProvider(new DeviceContentProvider());
-        mTreeViewer.setLabelProvider(new DeviceLabelProvider());
-        mTreeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
-        mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                setEnabled(getSelection());
-            }
-        });
-
-        Composite buttons = new Composite(parent, SWT.NONE);
-        buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-        buttons.setLayout(gl = new GridLayout());
-        gl.marginHeight = gl.marginWidth = 0;
-
-        mNewButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-        mNewButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mNewButton.setText("New...");
-        mNewButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceSelection selection = getSelection();
-
-                ConfigEditDialog dlg = new ConfigEditDialog(parent.getShell(), null);
-                if (selection.device != null) {
-                    dlg.setDeviceName(selection.device.getName());
-                    dlg.setXDpi(selection.device.getXDpi());
-                    dlg.setYDpi(selection.device.getYDpi());
-                }
-                if (selection.entry != null) {
-                    dlg.setConfigName(selection.entry.getKey());
-                    dlg.setConfig(selection.entry.getValue());
-                }
-
-                if (dlg.open() == Window.OK) {
-                    String deviceName = dlg.getDeviceName();
-                    String configName = dlg.getConfigName();
-                    FolderConfiguration config = new FolderConfiguration();
-                    dlg.getConfig(config);
-
-                    // first if there was no original device, we create one.
-                    // Because the new button is disabled when something else than "custom" is
-                    // selected, we always add to the user devices without checking.
-                    LayoutDevice d;
-                    if (selection.device == null) {
-                        // FIXME: this doesn't check if the device name is taken.
-                        d = mManager.addUserDevice(deviceName, dlg.getXDpi(), dlg.getYDpi());
-                    } else {
-                        // search for it.
-                        d = mManager.getUserLayoutDevice(deviceName);
-                    }
-
-                    if (d != null) {
-                        // then if there was no config, we add it, otherwise we edit it
-                        // (same method that adds/replace a config).
-                        // FIXME this doesn't check if the name was already taken.
-                        mManager.addUserConfiguration(d, configName, config);
-
-                        mTreeViewer.refresh();
-                        select(d, configName);
-                    }
-                }
-            }
-        });
-
-        mEditButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-        mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mEditButton.setText("Edit...");
-        mEditButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceSelection selection = getSelection();
-                ConfigEditDialog dlg = new ConfigEditDialog(parent.getShell(), null);
-                dlg.setDeviceName(selection.device.getName());
-                dlg.setXDpi(selection.device.getXDpi());
-                dlg.setYDpi(selection.device.getYDpi());
-                dlg.setConfigName(selection.entry.getKey());
-                dlg.setConfig(selection.entry.getValue());
-
-                if (dlg.open() == Window.OK) {
-                    String deviceName = dlg.getDeviceName();
-                    String configName = dlg.getConfigName();
-                    FolderConfiguration config = new FolderConfiguration();
-                    dlg.getConfig(config);
-
-                    // replace the device if needed.
-                    // FIXME: this doesn't check if the replacement name doesn't exist already.
-                    LayoutDevice d = mManager.replaceUserDevice(selection.device, deviceName,
-                            dlg.getXDpi(), dlg.getYDpi());
-
-                    // and add/replace the config
-                    mManager.replaceUserConfiguration(d, selection.entry.getKey(), configName,
-                            config);
-
-                    mTreeViewer.refresh();
-                    select(d, configName);
-                }
-            }
-        });
-
-        mCopyButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-        mCopyButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mCopyButton.setText("Copy");
-        mCopyButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceSelection selection = getSelection();
-
-                // is the source a default/add-on device, or are we copying a full device?
-                // if so the target device is a new device.
-                LayoutDevice targetDevice = selection.device;
-                if (selection.type == DeviceType.DEFAULT || selection.type == DeviceType.ADDON ||
-                        selection.entry == null) {
-                    // create a new device
-                    targetDevice = mManager.addUserDevice(
-                            selection.device.getName() + " Copy", // new name
-                            selection.device.getXDpi(),
-                            selection.device.getYDpi());
-                }
-
-                String newConfigName = null; // name of the single new config. used for the select.
-
-                // are we copying the full device?
-                if (selection.entry == null) {
-                    // get the config from the origin device
-                    Map<String, FolderConfiguration> configs = selection.device.getConfigs();
-
-                    // and copy them in the target device
-                    for (Entry<String, FolderConfiguration> entry : configs.entrySet()) {
-                        // we need to make a copy of the config object, or it could be modified
-                        // in default/addon by editing the version in the new device.
-                        FolderConfiguration copy = new FolderConfiguration();
-                        copy.set(entry.getValue());
-
-                        // the name can stay the same since we are copying a full device
-                        // and the target device has its own new name.
-                        mManager.addUserConfiguration(targetDevice, entry.getKey(), copy);
-                    }
-                } else {
-                    // only copy the config. target device is not the same as the selection, don't
-                    // change the config name as we already changed the name of the device.
-                    newConfigName = (selection.device != targetDevice) ?
-                            selection.entry.getKey() : selection.entry.getKey() + " Copy";
-
-                    // copy of the config
-                    FolderConfiguration copy = new FolderConfiguration();
-                    copy.set(selection.entry.getValue());
-
-                    // and create the config
-                    mManager.addUserConfiguration(targetDevice, newConfigName, copy);
-                }
-
-                mTreeViewer.refresh();
-
-                select(targetDevice, newConfigName);
-            }
-        });
-
-        mDeleteButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-        mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mDeleteButton.setText("Delete");
-        mDeleteButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                DeviceSelection selection = getSelection();
-
-                if (selection.entry != null) {
-                    mManager.removeUserConfiguration(selection.device, selection.entry.getKey());
-                } else if (selection.device != null) {
-                    mManager.removeUserDevice(selection.device);
-                }
-
-                mTreeViewer.refresh();
-
-                // either select the device (if we removed a entry, or the top custom node if
-                // we removed a device)
-                select(selection.entry != null ? selection.device : null, null);
-            }
-        });
-
-        Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
-        separator.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-
-        mTreeViewer.setInput(mManager);
-        setEnabled(null); // no selection at the start
-    }
-
-    @Override
-    protected void createButtonsForButtonBar(Composite parent) {
-        // we only want an OK button.
-        createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
-    }
-
-    /**
-     * Returns a {@link DeviceSelection} object representing the selected path in the
-     * {@link TreeViewer}
-     */
-    private DeviceSelection getSelection() {
-        // get the selection paths
-        TreeSelection selection = (TreeSelection)mTreeViewer.getSelection();
-        TreePath[] paths =selection.getPaths();
-
-        if (paths.length == 0) {
-            return null;
-        }
-
-        TreePath pathSelection = paths[0];
-
-        DeviceType type = (DeviceType)pathSelection.getFirstSegment();
-        LayoutDevice device = null;
-        Entry<String, FolderConfiguration> entry = null;
-        switch (pathSelection.getSegmentCount()) {
-            case 2: // layout device is selected
-                device = (LayoutDevice)pathSelection.getLastSegment();
-                break;
-            case 3: // config is selected
-                device = (LayoutDevice)pathSelection.getSegment(1);
-                entry = (Entry<String, FolderConfiguration>)pathSelection.getLastSegment();
-        }
-
-        return new DeviceSelection(type, device, entry);
-    }
-
-    /**
-     * Enables/disables the action button based on the {@link DeviceSelection}.
-     * @param selection the selection
-     */
-    protected void setEnabled(DeviceSelection selection) {
-        if (selection == null) {
-            mNewButton.setEnabled(false);
-            mEditButton.setEnabled(false);
-            mCopyButton.setEnabled(false);
-            mDeleteButton.setEnabled(false);
-        } else {
-            switch (selection.type) {
-                case DEFAULT:
-                case ADDON:
-                    // only allow copy if device is not null
-                    mNewButton.setEnabled(false);
-                    mEditButton.setEnabled(false);
-                    mDeleteButton.setEnabled(false);
-                    mCopyButton.setEnabled(selection.device != null);
-                    break;
-                case CUSTOM:
-                    mNewButton.setEnabled(true); // always true to create new devices.
-                    mEditButton.setEnabled(selection.entry != null); // only edit config for now
-
-                    boolean enabled = selection.device != null; // need at least selected device
-                    mDeleteButton.setEnabled(enabled);          // for delete and copy buttons
-                    mCopyButton.setEnabled(enabled);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Selects a device and optionally a config. Because this is meant to show newly created/edited
-     * device/config, it'll only do so for {@link DeviceType#CUSTOM} devices.
-     * @param device the device to select
-     * @param configName the config to select (optional)
-     */
-    private void select(LayoutDevice device, String configName) {
-        Object[] path;
-        if (device == null) {
-            // select the "custom" node
-            path = new Object[] { DeviceType.CUSTOM };
-        } else if (configName == null) {
-            // this is the easy case. no config to select
-            path = new Object[] { DeviceType.CUSTOM, device };
-        } else {
-            // this is more complex. we have the configName, but the tree contains Entry<?,?>
-            // Look for the entry.
-            Entry<?, ?> match = null;
-            for (Entry<?, ?> entry : device.getConfigs().entrySet()) {
-                if (entry.getKey().equals(configName)) {
-                    match = entry;
-                    break;
-                }
-            }
-
-            if (match != null) {
-                path = new Object[] { DeviceType.CUSTOM, device, match };
-            } else {
-                path = new Object[] { DeviceType.CUSTOM, device };
-            }
-        }
-
-        mTreeViewer.setSelection(new TreeSelection(new TreePath(path)), true /*reveal*/);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
deleted file mode 100644
index b6f9a09..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.configuration;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.VersionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDevice;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutDeviceManager;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.LanguageRegionVerifier;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IStyleResourceValue;
-
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-
-/**
- * A composite that displays the current configuration displayed in a Graphical Layout Editor.
- */
-public class ConfigurationComposite extends Composite {
-
-    private final static String THEME_SEPARATOR = "----------"; //$NON-NLS-1$
-
-    private Button mClippingButton;
-    private Label mCurrentLayoutLabel;
-
-    private Combo mLocale;
-    private Combo mDeviceList;
-    private Combo mDeviceConfigs;
-    private Combo mThemeCombo;
-    private Button mCreateButton;
-
-
-    private int mPlatformThemeCount = 0;
-    private boolean mDisableUpdates = false;
-
-    /** The {@link FolderConfiguration} representing the state of the UI controls */
-    private final FolderConfiguration mCurrentConfig = new FolderConfiguration();
-
-    private List<LayoutDevice> mDevices;
-
-    private final ArrayList<ResourceQualifier[] > mLocaleList =
-        new ArrayList<ResourceQualifier[]>();
-
-    private final IConfigListener mListener;
-
-    private boolean mClipping = true;
-
-    private LayoutDevice mCurrentDevice;
-
-    /**
-     * Interface implemented by the part which owns a {@link ConfigurationComposite}.
-     * This notifies the owners when the configuration change.
-     * The owner must also provide methods to provide the configuration that will
-     * be displayed.
-     */
-    public interface IConfigListener {
-        void onConfigurationChange();
-        void onThemeChange();
-        void onCreate();
-        void OnClippingChange();
-
-        ProjectResources getProjectResources();
-        ProjectResources getFrameworkResources();
-        Map<String, Map<String, IResourceValue>> getConfiguredProjectResources();
-        Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources();
-    }
-
-    public ConfigurationComposite(IConfigListener listener, Composite parent, int style) {
-        super(parent, style);
-        mListener = listener;
-
-        GridLayout gl;
-        GridData gd;
-        int cols = 10; // device*2+config*2+locale*2+separator*2+theme+createBtn
-
-        // ---- First line: collapse button, clipping button, editing config display.
-        Composite labelParent = new Composite(this, SWT.NONE);
-        labelParent.setLayout(gl = new GridLayout(3, false));
-        gl.marginWidth = gl.marginHeight = 0;
-        labelParent.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = cols;
-
-        new Label(labelParent, SWT.NONE).setText("Editing config:");
-        mCurrentLayoutLabel = new Label(labelParent, SWT.NONE);
-        mCurrentLayoutLabel.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.widthHint = 50;
-
-        mClippingButton = new Button(labelParent, SWT.TOGGLE | SWT.FLAT);
-        mClippingButton.setSelection(mClipping);
-        mClippingButton.setToolTipText("Toggles screen clipping on/off");
-        mClippingButton.setImage(IconFactory.getInstance().getIcon("clipping")); //$NON-NLS-1$
-        mClippingButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                OnClippingChange();
-            }
-        });
-
-        // ---- 2nd line: device/config/locale/theme Combos, create button.
-
-        setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        setLayout(gl = new GridLayout(cols, false));
-        gl.marginHeight = 0;
-        gl.horizontalSpacing = 0;
-
-        new Label(this, SWT.NONE).setText("Devices");
-        mDeviceList = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mDeviceList.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mDeviceList.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onDeviceChange(true /* recomputeLayout*/);
-            }
-        });
-
-        new Label(this, SWT.NONE).setText("Config");
-        mDeviceConfigs = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mDeviceConfigs.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mDeviceConfigs.addSelectionListener(new SelectionAdapter() {
-            @Override
-             public void widgetSelected(SelectionEvent e) {
-                onDeviceConfigChange();
-            }
-        });
-
-        new Label(this, SWT.NONE).setText("Locale");
-        mLocale = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mLocale.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mLocale.addVerifyListener(new LanguageRegionVerifier());
-        mLocale.addSelectionListener(new SelectionListener() {
-            public void widgetDefaultSelected(SelectionEvent e) {
-                onLocaleChange();
-            }
-            public void widgetSelected(SelectionEvent e) {
-                onLocaleChange();
-            }
-        });
-
-        // first separator
-        Label separator = new Label(this, SWT.SEPARATOR | SWT.VERTICAL);
-        separator.setLayoutData(gd = new GridData(
-                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
-        gd.heightHint = 0;
-
-        mThemeCombo = new Combo(this, SWT.READ_ONLY | SWT.DROP_DOWN);
-        mThemeCombo.setEnabled(false);
-        updateUIFromResources();
-        mThemeCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onThemeChange();
-            }
-        });
-
-        // second separator
-        separator = new Label(this, SWT.SEPARATOR | SWT.VERTICAL);
-        separator.setLayoutData(gd = new GridData(
-                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
-        gd.heightHint = 0;
-
-        mCreateButton = new Button(this, SWT.PUSH | SWT.FLAT);
-        mCreateButton.setText("Create...");
-        mCreateButton.setEnabled(false);
-        mCreateButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mListener != null) {
-                    mListener.onCreate();
-                }
-            }
-        });
-
-        initUiWithDevices();
-
-        onDeviceConfigChange();
-    }
-
-
-    public FolderConfiguration getCurrentConfig() {
-        return mCurrentConfig;
-    }
-
-    public void getCurrentConfig(FolderConfiguration config) {
-        config.set(mCurrentConfig);
-    }
-
-    /**
-     * Returns the currently selected {@link Density}. This is guaranteed to be non null.
-     */
-    public Density getDensity() {
-        if (mCurrentConfig != null) {
-            PixelDensityQualifier qual = mCurrentConfig.getPixelDensityQualifier();
-            if (qual != null) {
-                // just a sanity check
-                Density d = qual.getValue();
-                if (d != Density.NODPI) {
-                    return d;
-                }
-            }
-        }
-
-        // no config? return medium as the default density.
-        return Density.MEDIUM;
-    }
-
-    /**
-     * Returns the current device xdpi.
-     */
-    public float getXDpi() {
-        if (mCurrentDevice != null) {
-            float dpi = mCurrentDevice.getXDpi();
-            if (Float.isNaN(dpi) == false) {
-                return dpi;
-            }
-        }
-
-        // get the pixel density as the density.
-        return getDensity().getDpiValue();
-    }
-
-    /**
-     * Returns the current device ydpi.
-     */
-    public float getYDpi() {
-        if (mCurrentDevice != null) {
-            float dpi = mCurrentDevice.getYDpi();
-            if (Float.isNaN(dpi) == false) {
-                return dpi;
-            }
-        }
-
-        // get the pixel density as the density.
-        return getDensity().getDpiValue();
-    }
-
-    public Rectangle getScreenBounds() {
-        // get the orientation from the current device config
-        ScreenOrientationQualifier qual = mCurrentConfig.getScreenOrientationQualifier();
-        ScreenOrientation orientation = ScreenOrientation.PORTRAIT;
-        if (qual != null) {
-            orientation = qual.getValue();
-        }
-
-        // get the device screen dimension
-        ScreenDimensionQualifier qual2 = mCurrentConfig.getScreenDimensionQualifier();
-        int s1, s2;
-        if (qual2 != null) {
-            s1 = qual2.getValue1();
-            s2 = qual2.getValue2();
-        } else {
-            s1 = 480;
-            s2 = 320;
-        }
-
-        switch (orientation) {
-            default:
-            case PORTRAIT:
-                return new Rectangle(0, 0, s2, s1);
-            case LANDSCAPE:
-                return new Rectangle(0, 0, s1, s2);
-            case SQUARE:
-                return new Rectangle(0, 0, s1, s1);
-        }
-    }
-
-    /**
-     * Updates the UI from values in the resources, such as languages, regions, themes, etc...
-     * This must be called from the UI thread.
-     */
-    public void updateUIFromResources() {
-        if (mListener == null) {
-            return; // can't do anything w/o it.
-        }
-
-        ProjectResources frameworkProject = mListener.getFrameworkResources();
-
-        mDisableUpdates = true;
-
-        // Reset stuff
-        int selection = mThemeCombo.getSelectionIndex();
-        mThemeCombo.removeAll();
-        mPlatformThemeCount = 0;
-
-        mLocale.removeAll();
-        mLocaleList.clear();
-
-        SortedSet<String> languages = null;
-        ArrayList<String> themes = new ArrayList<String>();
-
-        // get the themes, and languages from the Framework.
-        if (frameworkProject != null) {
-            // get the configured resources for the framework
-            Map<String, Map<String, IResourceValue>> frameworResources =
-                mListener.getConfiguredFrameworkResources();
-
-            if (frameworResources != null) {
-                // get the styles.
-                Map<String, IResourceValue> styles = frameworResources.get(
-                        ResourceType.STYLE.getName());
-
-
-                // collect the themes out of all the styles.
-                for (IResourceValue value : styles.values()) {
-                    String name = value.getName();
-                    if (name.startsWith("Theme.") || name.equals("Theme")) {
-                        themes.add(value.getName());
-                        mPlatformThemeCount++;
-                    }
-                }
-
-                // sort them and add them to the combo
-                Collections.sort(themes);
-
-                for (String theme : themes) {
-                    mThemeCombo.add(theme);
-                }
-
-                mPlatformThemeCount = themes.size();
-                themes.clear();
-            }
-        }
-
-        // now get the themes and languages from the project.
-        ProjectResources project = mListener.getProjectResources();
-        // in cases where the opened file is not linked to a project, this could be null.
-        if (project != null) {
-            // get the configured resources for the project
-            Map<String, Map<String, IResourceValue>> configuredProjectRes =
-                mListener.getConfiguredProjectResources();
-
-            if (configuredProjectRes != null) {
-                // get the styles.
-                Map<String, IResourceValue> styleMap = configuredProjectRes.get(
-                        ResourceType.STYLE.getName());
-
-                if (styleMap != null) {
-                    // collect the themes out of all the styles, ie styles that extend,
-                    // directly or indirectly a platform theme.
-                    for (IResourceValue value : styleMap.values()) {
-                        if (isTheme(value, styleMap)) {
-                            themes.add(value.getName());
-                        }
-                    }
-
-                    // sort them and add them the to the combo.
-                    if (mPlatformThemeCount > 0 && themes.size() > 0) {
-                        mThemeCombo.add(THEME_SEPARATOR);
-                    }
-
-                    Collections.sort(themes);
-
-                    for (String theme : themes) {
-                        mThemeCombo.add(theme);
-                    }
-                }
-            }
-
-            // now get the languages from the project.
-            languages = project.getLanguages();
-        }
-
-        // add the languages to the Combo
-        mLocale.add("Default");
-        mLocaleList.add(new ResourceQualifier[] { null, null });
-
-        if (project != null && languages != null && languages.size() > 0) {
-            for (String language : languages) {
-                // first the language alone
-                mLocale.add(language);
-                LanguageQualifier qual = new LanguageQualifier(language);
-                mLocaleList.add(new ResourceQualifier[] { qual, null });
-
-                // now find the matching regions and add them
-                SortedSet<String> regions = project.getRegions(language);
-                for (String region : regions) {
-                    mLocale.add(String.format("%1$s_%2$s", language, region)); //$NON-NLS-1$
-                    RegionQualifier qual2 = new RegionQualifier(region);
-                    mLocaleList.add(new ResourceQualifier[] { qual, qual2 });
-                }
-
-            }
-        }
-
-        mDisableUpdates = false;
-
-        // handle default selection of themes
-        if (mThemeCombo.getItemCount() > 0) {
-            mThemeCombo.setEnabled(true);
-            if (selection == -1) {
-                selection = 0;
-            }
-
-            if (mThemeCombo.getItemCount() <= selection) {
-                mThemeCombo.select(0);
-            } else {
-                mThemeCombo.select(selection);
-            }
-        } else {
-            mThemeCombo.setEnabled(false);
-        }
-
-        mThemeCombo.getParent().layout();
-    }
-
-    /**
-     * Returns the current theme, or null if the combo has no selection.
-     */
-    public String getTheme() {
-        int themeIndex = mThemeCombo.getSelectionIndex();
-        if (themeIndex != -1) {
-            return mThemeCombo.getItem(themeIndex);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns whether the current theme selection is a project theme.
-     * <p/>The returned value is meaningless if {@link #getTheme()} returns <code>null</code>.
-     * @return true for project theme, false for framework theme
-     */
-    public boolean isProjectTheme() {
-        return mThemeCombo.getSelectionIndex() >= mPlatformThemeCount;
-    }
-
-    public boolean getClipping() {
-        return mClipping;
-    }
-
-    public void setEnabledCreate(boolean enabled) {
-        mCreateButton.setEnabled(enabled);
-    }
-
-    public void setClippingSupport(boolean b) {
-        mClippingButton.setEnabled(b);
-        if (b) {
-            mClippingButton.setToolTipText("Toggles screen clipping on/off");
-        } else {
-            mClipping = true;
-            mClippingButton.setSelection(true);
-            mClippingButton.setToolTipText("Non clipped rendering is not supported");
-        }
-    }
-
-    /**
-     * Update the UI controls state with a given {@link FolderConfiguration}.
-     * <p/>If <var>force</var> is set to <code>true</code> the UI will be changed to exactly reflect
-     * <var>config</var>, otherwise, if a qualifier is not present in <var>config</var>,
-     * the UI control is not modified. However if the value in the control is not the default value,
-     * a warning icon is shown.
-     * @param config The {@link FolderConfiguration} to set.
-     * @param force Whether the UI should be changed to exactly match the received configuration.
-     */
-    public void setConfiguration(FolderConfiguration config, boolean force) {
-        mDisableUpdates = true; // we do not want to trigger onXXXChange when setting new values in the widgets.
-
-        // TODO: find a device that can display this particular config or create a custom one if needed.
-
-
-        // update the string showing the folder name
-        String current = config.toDisplayString();
-        mCurrentLayoutLabel.setText(current != null ? current : "(Default)");
-
-        mDisableUpdates = false;
-    }
-
-    /**
-     * Reloads the list of {@link LayoutDevice} from the {@link Sdk}.
-     * @param notifyListener
-     */
-    public void reloadDevices(boolean notifyListener) {
-        loadDevices();
-        initUiWithDevices();
-        onDeviceChange(notifyListener);
-    }
-
-    private void loadDevices() {
-        mDevices = null;
-
-        Sdk sdk = Sdk.getCurrent();
-        if (sdk != null) {
-            LayoutDeviceManager manager = sdk.getLayoutDeviceManager();
-            mDevices = manager.getCombinedList();
-        }
-    }
-
-    /**
-     * Init the UI with the list of Devices.
-     */
-    private void initUiWithDevices() {
-        // remove older devices if applicable
-        mDeviceList.removeAll();
-        mDeviceConfigs.removeAll();
-
-        // fill with the devices
-        if (mDevices != null) {
-            for (LayoutDevice device : mDevices) {
-                mDeviceList.add(device.getName());
-            }
-            mDeviceList.select(0);
-
-            if (mDevices.size() > 0) {
-                Map<String, FolderConfiguration> configs = mDevices.get(0).getConfigs();
-                Set<String> configNames = configs.keySet();
-                for (String name : configNames) {
-                    mDeviceConfigs.add(name);
-                }
-                mDeviceConfigs.select(0);
-                if (configNames.size() == 1) {
-                    mDeviceConfigs.setEnabled(false);
-                }
-            }
-        }
-
-        // add the custom item
-        mDeviceList.add("Custom...");
-    }
-
-    /**
-     * Call back for language combo selection
-     */
-    private void onLocaleChange() {
-        // because mLanguage triggers onLanguageChange at each modification, the filling
-        // of the combo with data will trigger notifications, and we don't want that.
-        if (mDisableUpdates == true) {
-            return;
-        }
-
-        int localeIndex = mLocale.getSelectionIndex();
-        ResourceQualifier[] localeQualifiers = mLocaleList.get(localeIndex);
-
-        mCurrentConfig.setLanguageQualifier((LanguageQualifier)localeQualifiers[0]); // language
-        mCurrentConfig.setRegionQualifier((RegionQualifier)localeQualifiers[1]); // region
-
-        if (mListener != null) {
-            mListener.onConfigurationChange();
-        }
-    }
-
-    private void onDeviceChange(boolean recomputeLayout) {
-
-        int deviceIndex = mDeviceList.getSelectionIndex();
-        if (deviceIndex != -1) {
-            // check if the user is ask for the custom item
-            if (deviceIndex == mDeviceList.getItemCount() - 1) {
-                ConfigManagerDialog dialog = new ConfigManagerDialog(getShell());
-                dialog.open();
-
-                // save the user devices
-                Sdk.getCurrent().getLayoutDeviceManager().save();
-
-                // reload the combo with the new content.
-                loadDevices();
-                initUiWithDevices();
-
-                // at this point we need to reset the combo to something (hopefully) valid.
-                // look for the previous selected device
-                int index = mDevices.indexOf(mCurrentDevice);
-                if (index != -1) {
-                    mDeviceList.select(index);
-                } else {
-                    // we should at least have one built-in device, so we select it
-                    mDeviceList.select(0);
-                }
-
-                // force a redraw
-                onDeviceChange(true /*recomputeLayout*/);
-
-                return;
-            }
-
-            mCurrentDevice = mDevices.get(deviceIndex);
-        } else {
-            mCurrentDevice = null;
-        }
-
-        mDeviceConfigs.removeAll();
-
-        if (mCurrentDevice != null) {
-            Set<String> configNames = mCurrentDevice.getConfigs().keySet();
-            for (String name : configNames) {
-                mDeviceConfigs.add(name);
-            }
-
-            mDeviceConfigs.select(0);
-            if (configNames.size() == 1) {
-                mDeviceConfigs.setEnabled(false);
-            }
-
-        }
-        if (recomputeLayout) {
-            onDeviceConfigChange();
-        }
-    }
-
-    private void onDeviceConfigChange() {
-        if (mCurrentDevice != null) {
-            int configIndex = mDeviceConfigs.getSelectionIndex();
-            String name = mDeviceConfigs.getItem(configIndex);
-            FolderConfiguration config = mCurrentDevice.getConfigs().get(name);
-
-            // get the current qualifiers from the current config
-            LanguageQualifier lang = mCurrentConfig.getLanguageQualifier();
-            RegionQualifier region = mCurrentConfig.getRegionQualifier();
-            VersionQualifier version = mCurrentConfig.getVersionQualifier();
-
-            // replace the config with the one from the device
-            mCurrentConfig.set(config);
-
-            // and put back the rest of the qualifiers
-            mCurrentConfig.addQualifier(lang);
-            mCurrentConfig.addQualifier(region);
-            mCurrentConfig.addQualifier(version);
-
-            if (mListener != null) {
-                mListener.onConfigurationChange();
-            }
-        }
-    }
-
-    private void onThemeChange() {
-        int themeIndex = mThemeCombo.getSelectionIndex();
-        if (themeIndex != -1) {
-            String theme = mThemeCombo.getItem(themeIndex);
-
-            if (theme.equals(THEME_SEPARATOR)) {
-                mThemeCombo.select(0);
-            }
-
-            if (mListener != null) {
-                mListener.onThemeChange();
-            }
-        }
-    }
-
-    protected void OnClippingChange() {
-        mClipping = mClippingButton.getSelection();
-        if (mListener != null) {
-            mListener.OnClippingChange();
-        }
-    }
-
-    /**
-     * Returns whether the given <var>style</var> is a theme.
-     * This is done by making sure the parent is a theme.
-     * @param value the style to check
-     * @param styleMap the map of styles for the current project. Key is the style name.
-     * @return True if the given <var>style</var> is a theme.
-     */
-    private boolean isTheme(IResourceValue value, Map<String, IResourceValue> styleMap) {
-        if (value instanceof IStyleResourceValue) {
-            IStyleResourceValue style = (IStyleResourceValue)value;
-
-            boolean frameworkStyle = false;
-            String parentStyle = style.getParentStyle();
-            if (parentStyle == null) {
-                // if there is no specified parent style we look an implied one.
-                // For instance 'Theme.light' is implied child style of 'Theme',
-                // and 'Theme.light.fullscreen' is implied child style of 'Theme.light'
-                String name = style.getName();
-                int index = name.lastIndexOf('.');
-                if (index != -1) {
-                    parentStyle = name.substring(0, index);
-                }
-            } else {
-                // remove the useless @ if it's there
-                if (parentStyle.startsWith("@")) {
-                    parentStyle = parentStyle.substring(1);
-                }
-
-                // check for framework identifier.
-                if (parentStyle.startsWith("android:")) {
-                    frameworkStyle = true;
-                    parentStyle = parentStyle.substring("android:".length());
-                }
-
-                // at this point we could have the format style/<name>. we want only the name
-                if (parentStyle.startsWith("style/")) {
-                    parentStyle = parentStyle.substring("style/".length());
-                }
-            }
-
-            if (parentStyle != null) {
-                if (frameworkStyle) {
-                    // if the parent is a framework style, it has to be 'Theme' or 'Theme.*'
-                    return parentStyle.equals("Theme") || parentStyle.startsWith("Theme.");
-                } else {
-                    // if it's a project style, we check this is a theme.
-                    value = styleMap.get(parentStyle);
-                    if (value != null) {
-                        return isTheme(value, styleMap);
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/LayoutCreatorDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/LayoutCreatorDialog.java
deleted file mode 100644
index fdbb366..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/LayoutCreatorDialog.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.configuration;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.ConfigurationState;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Dialog to choose a non existing {@link FolderConfiguration}.
- */
-public final class LayoutCreatorDialog extends GridDialog {
-
-    private ConfigurationSelector mSelector;
-    private Composite mStatusComposite;
-    private Label mStatusLabel;
-    private Label mStatusImage;
-
-    private final FolderConfiguration mConfig = new FolderConfiguration();
-    private final String mFileName;
-    private final IAndroidTarget mTarget;
-
-    /**
-     * Creates a dialog, and init the UI from a {@link FolderConfiguration}.
-     * @param parentShell the parent {@link Shell}.
-     * @param config The starting configuration.
-     */
-    public LayoutCreatorDialog(Shell parentShell, String fileName, IAndroidTarget target,
-            FolderConfiguration config) {
-        super(parentShell, 1, false);
-
-        mFileName = fileName;
-        mTarget = target;
-
-        // FIXME: add some data to know what configurations already exist.
-        mConfig.set(config);
-    }
-
-    @Override
-    public void createDialogContent(Composite parent) {
-        new Label(parent, SWT.NONE).setText(
-                String.format("Configuration for the alternate version of %1$s", mFileName));
-
-        mSelector = new ConfigurationSelector(parent, false /*deviceMode*/);
-        mSelector.setConfiguration(mConfig);
-
-        // parent's layout is a GridLayout as specified in the javadoc.
-        GridData gd = new GridData();
-        gd.widthHint = ConfigurationSelector.WIDTH_HINT;
-        gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
-        mSelector.setLayoutData(gd);
-
-        // add a listener to check on the validity of the FolderConfiguration as
-        // they are built.
-        mSelector.setOnChangeListener(new Runnable() {
-            public void run() {
-                ConfigurationState state = mSelector.getState();
-
-                switch (state) {
-                    case OK:
-                        mSelector.getConfiguration(mConfig);
-
-                        resetStatus();
-                        mStatusImage.setImage(null);
-                        getButton(IDialogConstants.OK_ID).setEnabled(true);
-                        break;
-                    case INVALID_CONFIG:
-                        ResourceQualifier invalidQualifier = mSelector.getInvalidQualifier();
-                        mStatusLabel.setText(String.format(
-                                "Invalid Configuration: %1$s has no filter set.",
-                                invalidQualifier.getName()));
-                        mStatusImage.setImage(IconFactory.getInstance().getIcon("warning")); //$NON-NLS-1$
-                        getButton(IDialogConstants.OK_ID).setEnabled(false);
-                        break;
-                    case REGION_WITHOUT_LANGUAGE:
-                        mStatusLabel.setText(
-                                "The Region qualifier requires the Language qualifier.");
-                        mStatusImage.setImage(IconFactory.getInstance().getIcon("warning")); //$NON-NLS-1$
-                        getButton(IDialogConstants.OK_ID).setEnabled(false);
-                        break;
-                }
-
-                // need to relayout, because of the change in size in mErrorImage.
-                mStatusComposite.layout();
-            }
-        });
-
-        mStatusComposite = new Composite(parent, SWT.NONE);
-        mStatusComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        GridLayout gl = new GridLayout(2, false);
-        mStatusComposite.setLayout(gl);
-        gl.marginHeight = gl.marginWidth = 0;
-
-        mStatusImage = new Label(mStatusComposite, SWT.NONE);
-        mStatusLabel = new Label(mStatusComposite, SWT.NONE);
-        mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        resetStatus();
-    }
-
-    public void getConfiguration(FolderConfiguration config) {
-        config.set(mConfig);
-    }
-
-    /**
-     * resets the status label to show the file that will be created.
-     */
-    private void resetStatus() {
-        String displayString = Dialog.shortenText(String.format("New File: res/%1$s/%2$s",
-                mConfig.getFolderName(ResourceFolderType.LAYOUT, mTarget), mFileName),
-                mStatusLabel);
-        mStatusLabel.setText(displayString);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java
deleted file mode 100644
index b765abd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Service responsible for creating/managing {@link ElementDescriptor} objects for custom
- * View classes per project.
- * <p/>
- * The service provides an on-demand monitoring of custom classes to check for changes. Monitoring
- * starts once a request for an {@link ElementDescriptor} object has been done for a specific
- * class.<br>
- * The monitoring will notify a listen of any changes in the class triggering a change in its
- * associated {@link ElementDescriptor} object.
- * <p/>
- * If the custom class does not exist, no monitoring is put in place to avoid having to listen
- * to all class changes in the projects. 
- * 
- */
-public final class CustomViewDescriptorService {
-
-    private static CustomViewDescriptorService sThis = new CustomViewDescriptorService();
-    
-    /**
-     * Map where keys are the project, and values are another map containing all the known
-     * custom View class for this project. The custom View class are stored in a map
-     * where the keys are the fully qualified class name, and the values are their associated
-     * {@link ElementDescriptor}.
-     */
-    private HashMap<IProject, HashMap<String, ElementDescriptor>> mCustomDescriptorMap =
-        new HashMap<IProject, HashMap<String, ElementDescriptor>>();
-
-    /**
-     * TODO will be used to update the ElementDescriptor of the custom view when it
-     * is modified (either the class itself or its attributes.xml)
-     */
-    @SuppressWarnings("unused")
-    private ICustomViewDescriptorListener mListener;
-    
-    /**
-     * Classes which implements this interface provide a method that deal with modifications
-     * in custom View class triggering a change in its associated {@link ViewClassInfo} object. 
-     */
-    public interface ICustomViewDescriptorListener {
-        /**
-         * Sent when a custom View class has changed and its {@link ElementDescriptor} was modified.
-         * @param project the project containing the class.
-         * @param className the fully qualified class name.
-         * @param descriptor the updated ElementDescriptor.
-         */
-        public void updatedClassInfo(IProject project, String className, ElementDescriptor descriptor);
-    }
-    
-    /**
-     * Returns the singleton instance of {@link CustomViewDescriptorService}.
-     */
-    public static CustomViewDescriptorService getInstance() {
-        return sThis;
-    }
-    
-    /**
-     * Sets the listener receiving custom View class modification notifications.
-     * @param listener the listener to receive the notifications.
-     *
-     * TODO will be used to update the ElementDescriptor of the custom view when it
-     * is modified (either the class itself or its attributes.xml)
-     */
-    public void setListener(ICustomViewDescriptorListener listener) {
-        mListener = listener;
-    }
-    
-    /**
-     * Returns the {@link ElementDescriptor} for a particular project/class.
-     * <p/>
-     * If it is the first time the <code>ElementDescriptor</code> is requested, the method
-     * will check that the specified class is in fact a custom View class. Once this is
-     * established, a monitoring for that particular class is initiated. Any change will
-     * trigger a notification to the {@link ICustomViewDescriptorListener}.
-     * @param project the project containing the class.
-     * @param fqClassName the fully qualified name of the class.
-     * @return a <code>ElementDescriptor</code> or <code>null</code> if the class was not
-     * a custom View class.
-     */
-    public ElementDescriptor getDescriptor(IProject project, String fqClassName) {
-        // look in the map first
-        synchronized (mCustomDescriptorMap) {
-            HashMap<String, ElementDescriptor> map = mCustomDescriptorMap.get(project);
-            
-            if (map != null) {
-                ElementDescriptor descriptor = map.get(fqClassName);
-                if (descriptor != null) {
-                    return descriptor;
-                }
-            }
-        
-            // if we step here, it looks like we haven't created it yet.
-            // First lets check this is in fact a valid type in the project
-            
-            try {
-                // We expect the project to be both opened and of java type (since it's an android
-                // project), so we can create a IJavaProject object from our IProject.
-                IJavaProject javaProject = JavaCore.create(project);
-                
-                // replace $ by . in the class name
-                String javaClassName = fqClassName.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
-        
-                // look for the IType object for this class
-                IType type = javaProject.findType(javaClassName);
-                if (type != null && type.exists()) {
-                    // the type exists. Let's get the parent class and its ViewClassInfo.
-                    
-                    // get the type hierarchy
-                    ITypeHierarchy hierarchy = type.newSupertypeHierarchy(
-                            new NullProgressMonitor());
-                    
-                    ElementDescriptor parentDescriptor = getDescriptor(
-                            hierarchy.getSuperclass(type), project, hierarchy);
-                    
-                    if (parentDescriptor != null) {
-                        // we have a valid parent, lets create a new ElementDescriptor.
-
-                        ViewElementDescriptor descriptor = new ViewElementDescriptor(fqClassName,
-                                fqClassName, // ui_name
-                                fqClassName, // canonical class name
-                                null, // tooltip
-                                null, // sdk_url
-                                getAttributeDescriptor(type, parentDescriptor),
-                                null, // layout attributes
-                                null, // children
-                                false /* mandatory */);
-
-                        synchronized (mCustomDescriptorMap) {
-                            map = mCustomDescriptorMap.get(project);
-                            if (map == null) {
-                                map = new HashMap<String, ElementDescriptor>();
-                                mCustomDescriptorMap.put(project, map);
-                            }
-                        
-                            map.put(fqClassName, descriptor);
-                        }
-                        
-                        //TODO setup listener on this resource change.
-                        
-                        return descriptor;
-                    }
-                }
-            } catch (JavaModelException e) {
-                // there was an error accessing any of the IType, we'll just return null;
-            }
-        }
-
-
-        return null;
-    }
-    
-    /**
-     * Computes (if needed) and returns the {@link ElementDescriptor} for the specified type.
-     * 
-     * @param type 
-     * @param project 
-     * @param typeHierarchy
-     * @return A ViewElementDescriptor or null if type or typeHierarchy is null.
-     */
-    private ViewElementDescriptor getDescriptor(IType type, IProject project,
-            ITypeHierarchy typeHierarchy) {
-        // check if the type is a built-in View class.
-        List<ElementDescriptor> builtInList = null;
-
-        Sdk currentSdk = Sdk.getCurrent();
-        IAndroidTarget target = currentSdk == null ? null : currentSdk.getTarget(project);
-        if (target != null) {
-            AndroidTargetData data = currentSdk.getTargetData(target);
-            builtInList = data.getLayoutDescriptors().getViewDescriptors();
-        }
-
-        // give up if there's no type
-        if (type == null) {
-            return null;
-        }
-
-        String canonicalName = type.getFullyQualifiedName();
-        
-        if (builtInList != null) {
-            for (ElementDescriptor desc : builtInList) {
-                if (desc instanceof ViewElementDescriptor) {
-                    ViewElementDescriptor viewDescriptor = (ViewElementDescriptor)desc;
-                    if (canonicalName.equals(viewDescriptor.getCanonicalClassName())) {
-                        return viewDescriptor;
-                    }
-                }
-            }
-        }
-        
-        // it's not a built-in class? Lets look if the superclass is built-in
-        // give up if there's no type
-        if (typeHierarchy == null) {
-            return null;
-        }
-
-        IType parentType = typeHierarchy.getSuperclass(type);
-        if (parentType != null) {
-            ViewElementDescriptor parentDescriptor = getDescriptor(parentType, project,
-                    typeHierarchy);
-            
-            if (parentDescriptor != null) {
-                // parent class is a valid View class with a descriptor, so we create one
-                // for this class.
-                ViewElementDescriptor descriptor = new ViewElementDescriptor(canonicalName,
-                        canonicalName, // ui_name
-                        canonicalName, // canonical name
-                        null, // tooltip
-                        null, // sdk_url
-                        getAttributeDescriptor(type, parentDescriptor),
-                        null, // layout attributes
-                        null, // children
-                        false /* mandatory */);
-                
-                // add it to the map
-                synchronized (mCustomDescriptorMap) {
-                    HashMap<String, ElementDescriptor> map = mCustomDescriptorMap.get(project);
-                    
-                    if (map == null) {
-                        map = new HashMap<String, ElementDescriptor>();
-                        mCustomDescriptorMap.put(project, map);
-                    }
-                    
-                    map.put(canonicalName, descriptor);
-                    
-                }
-
-                //TODO setup listener on this resource change.
-                
-                return descriptor;
-            }
-        }
-        
-        // class is neither a built-in view class, nor extend one. return null.
-        return null;
-    }
-    
-    /**
-     * Returns the array of {@link AttributeDescriptor} for the specified {@link IType}.
-     * <p/>
-     * The array should contain the descriptor for this type and all its supertypes.
-     * @param type the type for which the {@link AttributeDescriptor} are returned.
-     * @param parentDescriptor the {@link ElementDescriptor} of the direct superclass.
-     */
-    private AttributeDescriptor[] getAttributeDescriptor(IType type,
-            ElementDescriptor parentDescriptor) {
-        // TODO add the class attribute descriptors to the parent descriptors.
-        return parentDescriptor.getAttributes();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java
deleted file mode 100644
index b855587..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.descriptors;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo.LayoutParamsInfo;
-import com.android.sdklib.SdkConstants;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * Complete description of the layout structure.
- */
-public final class LayoutDescriptors implements IDescriptorProvider {
-
-    // Public attributes names, attributes descriptors and elements descriptors
-    public static final String ID_ATTR = "id"; //$NON-NLS-1$
-
-    /** The document descriptor. Contains all layouts and views linked together. */
-    private DocumentDescriptor mRootDescriptor =
-        new DocumentDescriptor("layout_doc", null); //$NON-NLS-1$
-
-    /** The list of all known ViewLayout descriptors. */
-    private ArrayList<ElementDescriptor> mLayoutDescriptors = new ArrayList<ElementDescriptor>();
-
-    /** Read-Only list of View Descriptors. */
-    private List<ElementDescriptor> mROLayoutDescriptors;
-
-    /** The list of all known View (not ViewLayout) descriptors. */
-    private ArrayList<ElementDescriptor> mViewDescriptors = new ArrayList<ElementDescriptor>();
-    
-    /** Read-Only list of View Descriptors. */
-    private List<ElementDescriptor> mROViewDescriptors;
-    
-    /** @return the document descriptor. Contains all layouts and views linked together. */
-    public DocumentDescriptor getDescriptor() {
-        return mRootDescriptor;
-    }
-    
-    /** @return The read-only list of all known ViewLayout descriptors. */
-    public List<ElementDescriptor> getLayoutDescriptors() {
-        return mROLayoutDescriptors;
-    }
-    
-    /** @return The read-only list of all known View (not ViewLayout) descriptors. */
-    public List<ElementDescriptor> getViewDescriptors() {
-        return mROViewDescriptors;
-    }
-    
-    public ElementDescriptor[] getRootElementDescriptors() {
-        return mRootDescriptor.getChildren();
-    }
-
-    /**
-     * Updates the document descriptor.
-     * <p/>
-     * It first computes the new children of the descriptor and then update them
-     * all at once.
-     * <p/> 
-     *  TODO: differentiate groups from views in the tree UI? => rely on icons
-     * <p/> 
-     * 
-     * @param views The list of views in the framework.
-     * @param layouts The list of layouts in the framework.
-     */
-    public synchronized void updateDescriptors(ViewClassInfo[] views, ViewClassInfo[] layouts) {
-        ArrayList<ElementDescriptor> newViews = new ArrayList<ElementDescriptor>();
-        if (views != null) {
-            for (ViewClassInfo info : views) {
-                ElementDescriptor desc = convertView(info);
-                newViews.add(desc);
-            }
-        }
-
-        // Create <include> as a synthetic regular view.
-        // Note: ViewStub is already described by attrs.xml
-        insertInclude(newViews);
-
-        ArrayList<ElementDescriptor> newLayouts = new ArrayList<ElementDescriptor>();
-        if (layouts != null) {
-            for (ViewClassInfo info : layouts) {
-                ElementDescriptor desc = convertView(info);
-                newLayouts.add(desc);
-            }
-        }
-
-        ArrayList<ElementDescriptor> newDescriptors = new ArrayList<ElementDescriptor>();
-        newDescriptors.addAll(newLayouts);
-        newDescriptors.addAll(newViews);
-
-        // Link all layouts to everything else here.. recursively
-        for (ElementDescriptor layoutDesc : newLayouts) {
-            layoutDesc.setChildren(newDescriptors);
-        }
-
-        // The <merge> tag can only be a root tag, so it is added at the end.
-        // It gets everything else as children but it is not made a child itself.
-        ElementDescriptor mergeTag = createMerge(newLayouts);
-        mergeTag.setChildren(newDescriptors);  // mergeTag makes a copy of the list
-        newDescriptors.add(mergeTag);
-        newLayouts.add(mergeTag);
-
-        mViewDescriptors = newViews;
-        mLayoutDescriptors  = newLayouts;
-        mRootDescriptor.setChildren(newDescriptors);
-        
-        mROLayoutDescriptors = Collections.unmodifiableList(mLayoutDescriptors);
-        mROViewDescriptors = Collections.unmodifiableList(mViewDescriptors);
-    }
-
-    /**
-     * Creates an element descriptor from a given {@link ViewClassInfo}.
-     */
-    private ElementDescriptor convertView(ViewClassInfo info) {
-        String xml_name = info.getShortClassName();
-        String tooltip = info.getJavaDoc();
-        
-        ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
-        
-        // All views and groups have an implicit "style" attribute which is a reference.
-        AttributeInfo styleInfo = new DeclareStyleableInfo.AttributeInfo(
-                "style",    //$NON-NLS-1$ xmlLocalName
-                new DeclareStyleableInfo.AttributeInfo.Format[] {
-                        DeclareStyleableInfo.AttributeInfo.Format.REFERENCE
-                    });
-        styleInfo.setJavaDoc("A reference to a custom style"); //tooltip
-        DescriptorsUtils.appendAttribute(attributes,
-                "style",    //$NON-NLS-1$
-                null,       //nsUri
-                styleInfo,
-                false,      //required
-                null);      // overrides
-        
-        // Process all View attributes
-        DescriptorsUtils.appendAttributes(attributes,
-                null, // elementName
-                SdkConstants.NS_RESOURCES,
-                info.getAttributes(),
-                null, // requiredAttributes
-                null /* overrides */);
-        
-        for (ViewClassInfo link = info.getSuperClass();
-                link != null;
-                link = link.getSuperClass()) {
-            AttributeInfo[] attrList = link.getAttributes();
-            if (attrList.length > 0) {
-                attributes.add(new SeparatorAttributeDescriptor(
-                        String.format("Attributes from %1$s", link.getShortClassName()))); 
-                DescriptorsUtils.appendAttributes(attributes,
-                        null, // elementName
-                        SdkConstants.NS_RESOURCES,
-                        attrList,
-                        null, // requiredAttributes
-                        null /* overrides */);
-            }
-        }
-
-        // Process all LayoutParams attributes
-        ArrayList<AttributeDescriptor> layoutAttributes = new ArrayList<AttributeDescriptor>();
-        LayoutParamsInfo layoutParams = info.getLayoutData();
-
-        for(; layoutParams != null; layoutParams = layoutParams.getSuperClass()) {
-            boolean need_separator = true;
-            for (AttributeInfo attr_info : layoutParams.getAttributes()) {
-                if (DescriptorsUtils.containsAttribute(layoutAttributes,
-                        SdkConstants.NS_RESOURCES, attr_info)) {
-                    continue;
-                }
-                if (need_separator) {
-                    String title;
-                    if (layoutParams.getShortClassName().equals(
-                            AndroidConstants.CLASS_NAME_LAYOUTPARAMS)) {
-                        title = String.format("Layout Attributes from %1$s",
-                                    layoutParams.getViewLayoutClass().getShortClassName());
-                    } else {
-                        title = String.format("Layout Attributes from %1$s (%2$s)",
-                                layoutParams.getViewLayoutClass().getShortClassName(),
-                                layoutParams.getShortClassName());
-                    }
-                    layoutAttributes.add(new SeparatorAttributeDescriptor(title));
-                    need_separator = false;
-                }
-                DescriptorsUtils.appendAttribute(layoutAttributes,
-                        null, // elementName
-                        SdkConstants.NS_RESOURCES,
-                        attr_info,
-                        false, // required
-                        null /* overrides */);
-            }
-        }
-
-        return new ViewElementDescriptor(xml_name,
-                xml_name, // ui_name
-                info.getCanonicalClassName(),
-                tooltip,
-                null, // sdk_url
-                attributes.toArray(new AttributeDescriptor[attributes.size()]),
-                layoutAttributes.toArray(new AttributeDescriptor[layoutAttributes.size()]),
-                null, // children
-                false /* mandatory */);
-    }
-
-    /**
-     * Creates a new <include> descriptor and adds it to the list of view descriptors.
-     * 
-     * @param knownViews A list of view descriptors being populated. Also used to find the
-     *   View descriptor and extract its layout attributes.
-     */
-    private void insertInclude(ArrayList<ElementDescriptor> knownViews) {
-        String xml_name = "include";  //$NON-NLS-1$
-
-        // Create the include custom attributes
-        ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
-        
-        // Note that the "layout" attribute does NOT have the Android namespace
-        DescriptorsUtils.appendAttribute(attributes,
-                null, //elementXmlName
-                null, //nsUri
-                new AttributeInfo(
-                        "layout",       //$NON-NLS-1$
-                        new AttributeInfo.Format[] { AttributeInfo.Format.REFERENCE }
-                        ),
-                true,  //required
-                null); //overrides
-
-        DescriptorsUtils.appendAttribute(attributes,
-                null, //elementXmlName
-                SdkConstants.NS_RESOURCES, //nsUri
-                new AttributeInfo(
-                        "id",           //$NON-NLS-1$
-                        new AttributeInfo.Format[] { AttributeInfo.Format.REFERENCE }
-                        ),
-                true,  //required
-                null); //overrides
-
-        // Find View and inherit all its layout attributes
-        AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes(
-                AndroidConstants.CLASS_VIEW, knownViews);
-
-        // Create the include descriptor
-        ViewElementDescriptor desc = new ViewElementDescriptor(xml_name,  // xml_name
-                xml_name, // ui_name
-                null,     // canonical class name, we don't have one
-                "Lets you statically include XML layouts inside other XML layouts.",  // tooltip
-                null, // sdk_url
-                attributes.toArray(new AttributeDescriptor[attributes.size()]),
-                viewLayoutAttribs,  // layout attributes
-                null, // children
-                false /* mandatory */);
-        
-        knownViews.add(desc);
-    }
-
-    /**
-     * Creates and return a new <merge> descriptor.
-     * @param knownLayouts  A list of all known layout view descriptors, used to find the
-     *   FrameLayout descriptor and extract its layout attributes.
-     */
-    private ElementDescriptor createMerge(ArrayList<ElementDescriptor> knownLayouts) {
-        String xml_name = "merge";  //$NON-NLS-1$
-
-        // Find View and inherit all its layout attributes
-        AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes(
-                AndroidConstants.CLASS_FRAMELAYOUT, knownLayouts);
-
-        // Create the include descriptor
-        ViewElementDescriptor desc = new ViewElementDescriptor(xml_name,  // xml_name
-                xml_name, // ui_name
-                null,     // canonical class name, we don't have one
-                "A root tag useful for XML layouts inflated using a ViewStub.",  // tooltip
-                null,  // sdk_url
-                null,  // attributes
-                viewLayoutAttribs,  // layout attributes
-                null,  // children
-                false  /* mandatory */);
-
-        return desc;
-    }
-
-    /**
-     * Finds the descriptor and retrieves all its layout attributes.
-     */
-    private AttributeDescriptor[] findViewLayoutAttributes(
-            String viewFqcn,
-            ArrayList<ElementDescriptor> knownViews) {
-
-        for (ElementDescriptor desc : knownViews) {
-            if (desc instanceof ViewElementDescriptor) {
-                ViewElementDescriptor viewDesc = (ViewElementDescriptor) desc;
-                if (viewFqcn.equals(viewDesc.getCanonicalClassName())) {
-                    return viewDesc.getLayoutAttributes();
-                }
-            }
-        }
-        
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java
deleted file mode 100644
index 1ae9231..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * {@link ViewElementDescriptor} describes the properties expected for a given XML element node
- * representing a class in an XML Layout file.
- * 
- * @see ElementDescriptor
- */
-public final class ViewElementDescriptor extends ElementDescriptor {
-    
-    private String mCanonicalClassName;
-
-    /** The list of layout attributes. Can be empty but not null. */
-    private AttributeDescriptor[] mLayoutAttributes;
-
-    
-    /**
-     * Constructs a new {@link ViewElementDescriptor} based on its XML name, UI name,
-     * the canonical name of the class it represents, its tooltip, its SDK url, its attributes list,
-     * its children list and its mandatory flag.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param ui_name The XML element name for the user interface, typically capitalized.
-     * @param canonicalClassName The canonical class name the {@link ViewElementDescriptor} is
-     * representing.
-     * @param tooltip An optional tooltip. Can be null or empty.
-     * @param sdk_url An optional SKD URL. Can be null or empty.
-     * @param attributes The list of allowed attributes. Can be null or empty.
-     * @param layoutAttributes The list of layout attributes. Can be null or empty.
-     * @param children The list of allowed children. Can be null or empty.
-     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
-     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
-     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
-     *  ceases to exist.
-     */
-    public ViewElementDescriptor(String xml_name, String ui_name,
-            String canonicalClassName,
-            String tooltip, String sdk_url,
-            AttributeDescriptor[] attributes, AttributeDescriptor[] layoutAttributes,
-            ElementDescriptor[] children, boolean mandatory) {
-        super(xml_name, ui_name, tooltip, sdk_url, attributes, children, mandatory);
-        mCanonicalClassName = canonicalClassName;
-        mLayoutAttributes = layoutAttributes != null ? layoutAttributes : new AttributeDescriptor[0];
-    }
-
-    /**
-     * Constructs a new {@link ElementDescriptor} based on its XML name, the canonical
-     * name of the class it represents, and its children list.
-     * The UI name is build by capitalizing the XML name.
-     * The UI nodes will be non-mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param canonicalClassName The canonical class name the {@link ViewElementDescriptor} is
-     * representing.
-     * @param children The list of allowed children. Can be null or empty.
-     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
-     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
-     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
-     *  ceases to exist.
-     */
-    public ViewElementDescriptor(String xml_name, String canonicalClassName,
-            ElementDescriptor[] children,
-            boolean mandatory) {
-        super(xml_name, children, mandatory);
-        mCanonicalClassName = canonicalClassName;
-    }
-
-    /**
-     * Constructs a new {@link ElementDescriptor} based on its XML name and children list.
-     * The UI name is build by capitalizing the XML name.
-     * The UI nodes will be non-mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param canonicalClassName The canonical class name the {@link ViewElementDescriptor} is
-     * representing.
-     * @param children The list of allowed children. Can be null or empty.
-     */
-    public ViewElementDescriptor(String xml_name, String canonicalClassName,
-            ElementDescriptor[] children) {
-        super(xml_name, children);
-        mCanonicalClassName = canonicalClassName;
-    }
-
-    /**
-     * Constructs a new {@link ElementDescriptor} based on its XML name and on the canonical
-     * name of the class it represents.
-     * The UI name is build by capitalizing the XML name.
-     * The UI nodes will be non-mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param canonicalClassName The canonical class name the {@link ViewElementDescriptor} is
-     * representing.
-     */
-    public ViewElementDescriptor(String xml_name, String canonicalClassName) {
-        super(xml_name);
-        mCanonicalClassName = canonicalClassName;
-    }
-    
-    /**
-     * Returns the canonical name of the class represented by this element descriptor.
-     */
-    public String getCanonicalClassName() {
-        return mCanonicalClassName;
-    }
-    
-    /** Returns the list of layout attributes. Can be empty but not null. */
-    public AttributeDescriptor[] getLayoutAttributes() {
-        return mLayoutAttributes;
-    }
-
-    /**
-     * @return A new {@link UiViewElementNode} linked to this descriptor.
-     */
-    @Override
-    public UiElementNode createUiNode() {
-        return new UiViewElementNode(this);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/DropFeedback.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/DropFeedback.java
deleted file mode 100644
index d75e016..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/DropFeedback.java
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutConstants;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor.UiEditorActions;
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiLayoutEditPart.HighlightInfo;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.draw2d.geometry.Rectangle;
-
-import java.util.HashMap;
-import java.util.Map.Entry;
-
-/**
- * Utility methods used when dealing with dropping EditPart on the GLE.
- * <p/>
- * This class uses some temporary static storage to avoid excessive allocations during
- * drop operations. It is expected to only be invoked from the main UI thread with no
- * concurrent access.
- *
- * @since GLE1
- */
-class DropFeedback {
-
-    private static final int TOP    = 0;
-    private static final int LEFT   = 1;
-    private static final int BOTTOM = 2;
-    private static final int RIGHT  = 3;
-    private static final int MAX_DIR = RIGHT;
-
-    private static final int sOppositeDirection[] = { BOTTOM, RIGHT, TOP, LEFT };
-
-    private static final UiElementEditPart sTempClosests[] = new UiElementEditPart[4];
-    private static final int sTempMinDists[] = new int[4];
-
-
-    /**
-     * Target information computed from a drop on a RelativeLayout.
-     * We need only one instance of this and it is sRelativeInfo.
-     */
-    private static class RelativeInfo {
-        /** The two target parts 0 and 1. They can be null, meaning a border is used.
-         *  The direction from part 0 to 1 is always to-the-right or to-the-bottom. */
-        final UiElementEditPart targetParts[] = new UiElementEditPart[2];
-        /** Direction from the anchor part to the drop point. */
-        int direction;
-        /** The index of the "anchor" part, i.e. the closest one selected by the drop.
-         *  This can be either 0 or 1. The corresponding part can be null. */
-        int anchorIndex;
-    }
-
-    /** The single RelativeInfo used to compute results from a drop on a RelativeLayout */
-    private static final RelativeInfo sRelativeInfo = new RelativeInfo();
-    /** A temporary array of 2 {@link UiElementEditPart} to avoid allocations. */
-    private static final UiElementEditPart sTempTwoParts[] = new UiElementEditPart[2];
-
-
-    private DropFeedback() {
-    }
-
-
-    //----- Package methods called by users of this helper class -----
-
-
-    /**
-     * This method is used by {@link ElementCreateCommand#execute()} when a new item
-     * needs to be "dropped" in the current XML document. It creates the new item using
-     * the given descriptor as a child of the given parent part.
-     *
-     * @param parentPart The parent part.
-     * @param descriptor The descriptor for the new XML element.
-     * @param where      The drop location (in parent coordinates)
-     * @param actions    The helper that actually modifies the XML model.
-     */
-    static void addElementToXml(UiElementEditPart parentPart,
-            ElementDescriptor descriptor, Point where,
-            UiEditorActions actions) {
-
-        String layoutXmlName = getXmlLocalName(parentPart);
-        RelativeInfo info = null;
-        UiElementEditPart sibling = null;
-
-        // TODO consider merge like a vertical layout
-        // TODO consider TableLayout like a linear
-        if (LayoutConstants.LINEAR_LAYOUT.equals(layoutXmlName)) {
-            sibling = findLinearTarget(parentPart, where)[1];
-
-        } else if (LayoutConstants.RELATIVE_LAYOUT.equals(layoutXmlName)) {
-            info = findRelativeTarget(parentPart, where, sRelativeInfo);
-            if (info != null) {
-                sibling = info.targetParts[info.anchorIndex];
-                sibling = getNextUiSibling(sibling);
-            }
-        }
-
-        if (actions != null) {
-            UiElementNode uiSibling = sibling != null ? sibling.getUiNode() : null;
-            UiElementNode uiParent = parentPart.getUiNode();
-            UiElementNode uiNode = actions.addElement(uiParent, uiSibling, descriptor,
-                    false /*updateLayout*/);
-
-            if (LayoutConstants.ABSOLUTE_LAYOUT.equals(layoutXmlName)) {
-                adjustAbsoluteAttributes(uiNode, where);
-            } else if (LayoutConstants.RELATIVE_LAYOUT.equals(layoutXmlName)) {
-                adustRelativeAttributes(uiNode, info);
-            }
-        }
-    }
-
-    /**
-     * This method is used by {@link UiLayoutEditPart#showDropTarget(Point)} to compute
-     * highlight information when a drop target is moved over a valid drop area.
-     * <p/>
-     * Since there are no "out" parameters in Java, all the information is returned
-     * via the {@link HighlightInfo} structure passed as parameter.
-     *
-     * @param parentPart    The parent part, always a layout.
-     * @param highlightInfo A structure where result is stored to perform highlight.
-     * @param where         The target drop point, in parent's coordinates
-     * @return The {@link HighlightInfo} structured passed as a parameter, for convenience.
-     */
-    static HighlightInfo computeDropFeedback(UiLayoutEditPart parentPart,
-            HighlightInfo highlightInfo,
-            Point where) {
-        String layoutType = getXmlLocalName(parentPart);
-
-        if (LayoutConstants.ABSOLUTE_LAYOUT.equals(layoutType)) {
-            highlightInfo.anchorPoint = where;
-
-        } else if (LayoutConstants.LINEAR_LAYOUT.equals(layoutType)) {
-            boolean isVertical = isVertical(parentPart);
-
-            highlightInfo.childParts = findLinearTarget(parentPart, where);
-            computeLinearLine(parentPart, isVertical, highlightInfo);
-
-        } else if (LayoutConstants.RELATIVE_LAYOUT.equals(layoutType)) {
-
-            RelativeInfo info = findRelativeTarget(parentPart, where, sRelativeInfo);
-            if (info != null) {
-                highlightInfo.childParts = sRelativeInfo.targetParts;
-                computeRelativeLine(parentPart, info, highlightInfo);
-            }
-        }
-
-        return highlightInfo;
-    }
-
-
-    //----- Misc utilities -----
-
-    /**
-     * Returns the next UI sibling of this part, i.e. the element which is just after in
-     * the UI/XML order in the same parent. Returns null if there's no such part.
-     * <p/>
-     * Note: by "UI sibling" here we mean the sibling in the UiNode hierarchy. By design the
-     * UiNode model has the <em>exact</em> same order as the XML model. This has nothing to do
-     * with the "user interface" order that you see on the rendered Android layouts (e.g. for
-     * LinearLayout they are the same but for AbsoluteLayout or RelativeLayout the UI/XML model
-     * order can be vastly different from the user interface order.)
-     */
-    private static UiElementEditPart getNextUiSibling(UiElementEditPart part) {
-        if (part != null) {
-            UiElementNode uiNode = part.getUiNode();
-            if (uiNode != null) {
-                uiNode = uiNode.getUiNextSibling();
-            }
-            if (uiNode != null) {
-                for (Object childPart : part.getParent().getChildren()) {
-                    if (childPart instanceof UiElementEditPart &&
-                            ((UiElementEditPart) childPart).getUiNode() == uiNode) {
-                        return (UiElementEditPart) childPart;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the XML local name of the ui node associated with this edit part or null.
-     */
-    private static String getXmlLocalName(UiElementEditPart editPart) {
-        UiElementNode uiNode = editPart.getUiNode();
-        if (uiNode != null) {
-            ElementDescriptor desc = uiNode.getDescriptor();
-            if (desc != null) {
-                return desc.getXmlLocalName();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Adjusts the attributes of a new node dropped in an AbsoluteLayout.
-     *
-     * @param uiNode The new node being dropped.
-     * @param where  The drop location (in parent coordinates)
-     */
-    private static void adjustAbsoluteAttributes(final UiElementNode uiNode, final Point where) {
-        if (where == null) {
-            return;
-        }
-        uiNode.getEditor().editXmlModel(new Runnable() {
-            public void run() {
-                uiNode.setAttributeValue(LayoutConstants.ATTR_LAYOUT_X,
-                        String.format(LayoutConstants.VALUE_N_DIP, where.x),
-                        false /* override */);
-                uiNode.setAttributeValue(LayoutConstants.ATTR_LAYOUT_Y,
-                        String.format(LayoutConstants.VALUE_N_DIP, where.y),
-                        false /* override */);
-
-                uiNode.commitDirtyAttributesToXml();
-            }
-        });
-    }
-
-    /**
-     * Adjusts the attributes of a new node dropped in a RelativeLayout:
-     * <ul>
-     * <li> anchor part: the one the user selected (or the closest) and to which the new one
-     *      will "attach". The anchor part can be null, either because the layout is currently
-     *      empty or the user is attaching to an existing empty border.
-     * <li> direction: the direction from the anchor part to the drop point. That's also the
-     *      direction from the anchor part to the new part.
-     * <li> the new node; it is created either after the anchor for right or top directions
-     *      or before the anchor for left or bottom directions. This means the new part can
-     *      reference the id of the anchor part.
-     * </ul>
-     *
-     * Several cases:
-     * <ul>
-     * <li> set:  layout_above/below/toLeftOf/toRightOf to point to the anchor.
-     * <li> copy: layout_centerHorizontal for top/bottom directions
-     * <li> copy: layout_centerVertical for left/right directions.
-     * <li> copy: layout_above/below/toLeftOf/toRightOf for the orthogonal direction
-     *            (i.e. top/bottom or left/right.)
-     * </ul>
-     *
-     * @param uiNode The new node being dropped.
-     * @param info   The context computed by {@link #findRelativeTarget(UiElementEditPart, Point, RelativeInfo)}.
-     */
-    private static void adustRelativeAttributes(final UiElementNode uiNode, RelativeInfo info) {
-        if (uiNode == null || info == null) {
-            return;
-        }
-
-        final UiElementEditPart anchorPart = info.targetParts[info.anchorIndex];  // can be null
-        final int direction = info.direction;
-
-        uiNode.getEditor().editXmlModel(new Runnable() {
-            public void run() {
-                HashMap<String, String> map = new HashMap<String, String>();
-
-                UiElementNode anchorUiNode = anchorPart != null ? anchorPart.getUiNode() : null;
-                String anchorId = anchorUiNode != null
-                                    ? anchorUiNode.getAttributeValue("id")          //$NON-NLS-1$
-                                    : null;
-
-                if (anchorId == null) {
-                    anchorId = DescriptorsUtils.getFreeWidgetId(anchorUiNode);
-                    anchorUiNode.setAttributeValue("id", anchorId, true /*override*/); //$NON-NLS-1$
-                }
-
-                if (anchorId != null) {
-                    switch(direction) {
-                    case TOP:
-                        map.put(LayoutConstants.ATTR_LAYOUT_ABOVE, anchorId);
-                        break;
-                    case BOTTOM:
-                        map.put(LayoutConstants.ATTR_LAYOUT_BELOW, anchorId);
-                        break;
-                    case LEFT:
-                        map.put(LayoutConstants.ATTR_LAYOUT_TO_LEFT_OF, anchorId);
-                        break;
-                    case RIGHT:
-                        map.put(LayoutConstants.ATTR_LAYOUT_TO_RIGHT_OF, anchorId);
-                        break;
-                    }
-
-                    switch(direction) {
-                    case TOP:
-                    case BOTTOM:
-                        map.put(LayoutConstants.ATTR_LAYOUT_CENTER_HORIZONTAL,
-                                anchorUiNode.getAttributeValue(
-                                        LayoutConstants.ATTR_LAYOUT_CENTER_HORIZONTAL));
-
-                        map.put(LayoutConstants.ATTR_LAYOUT_TO_LEFT_OF,
-                                anchorUiNode.getAttributeValue(
-                                        LayoutConstants.ATTR_LAYOUT_TO_LEFT_OF));
-                        map.put(LayoutConstants.ATTR_LAYOUT_TO_RIGHT_OF,
-                                anchorUiNode.getAttributeValue(
-                                        LayoutConstants.ATTR_LAYOUT_TO_RIGHT_OF));
-                        break;
-                    case LEFT:
-                    case RIGHT:
-                        map.put(LayoutConstants.ATTR_LAYOUT_CENTER_VERTICAL,
-                                anchorUiNode.getAttributeValue(
-                                        LayoutConstants.ATTR_LAYOUT_CENTER_VERTICAL));
-                        map.put(LayoutConstants.ATTR_LAYOUT_ALIGN_BASELINE,
-                                anchorUiNode.getAttributeValue(
-                                        LayoutConstants.ATTR_LAYOUT_ALIGN_BASELINE));
-
-                        map.put(LayoutConstants.ATTR_LAYOUT_ABOVE,
-                                anchorUiNode.getAttributeValue(LayoutConstants.ATTR_LAYOUT_ABOVE));
-                        map.put(LayoutConstants.ATTR_LAYOUT_BELOW,
-                                anchorUiNode.getAttributeValue(LayoutConstants.ATTR_LAYOUT_BELOW));
-                        break;
-                    }
-                } else {
-                    // We don't have an anchor node. Assume we're targeting a border and align
-                    // to the parent.
-                    switch(direction) {
-                    case TOP:
-                        map.put(LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_TOP,
-                                LayoutConstants.VALUE_TRUE);
-                        break;
-                    case BOTTOM:
-                        map.put(LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_BOTTOM,
-                                LayoutConstants.VALUE_TRUE);
-                        break;
-                    case LEFT:
-                        map.put(LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_LEFT,
-                                LayoutConstants.VALUE_TRUE);
-                        break;
-                    case RIGHT:
-                        map.put(LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_RIGHT,
-                                LayoutConstants.VALUE_TRUE);
-                        break;
-                    }
-                }
-
-                for (Entry<String, String> entry : map.entrySet()) {
-                    uiNode.setAttributeValue(entry.getKey(), entry.getValue(), true /* override */);
-                }
-                uiNode.commitDirtyAttributesToXml();
-            }
-        });
-    }
-
-
-    //----- LinearLayout --------
-
-    /**
-     * For a given parent edit part that MUST represent a LinearLayout, finds the
-     * element before which the location points.
-     * <p/>
-     * This computes the edit part that corresponds to what will be the "next sibling" of the new
-     * element.
-     * <p/>
-     * It returns null if it can't be determined, in which case the element will be added at the
-     * end of the parent child list.
-     *
-     * @return The edit parts that correspond to what will be the "prev" and "next sibling" of the
-     *         new element. The previous sibling can be null if adding before the first element.
-     *         The next sibling can be null if adding after the last element.
-     */
-    private static UiElementEditPart[] findLinearTarget(UiElementEditPart parent, Point point) {
-        // default orientation is horizontal
-        boolean isVertical = isVertical(parent);
-
-        int target = isVertical ? point.y : point.x;
-
-        UiElementEditPart prev = null;
-        UiElementEditPart next = null;
-
-        for (Object child : parent.getChildren()) {
-            if (child instanceof UiElementEditPart) {
-                UiElementEditPart childPart = (UiElementEditPart) child;
-                Point p = childPart.getBounds().getCenter();
-                int middle = isVertical ? p.y : p.x;
-                if (target < middle) {
-                    next = childPart;
-                    break;
-                }
-                prev = childPart;
-            }
-        }
-
-        sTempTwoParts[0] = prev;
-        sTempTwoParts[1] = next;
-        return sTempTwoParts;
-    }
-
-    /**
-     * Computes the highlight line between two parts.
-     * <p/>
-     * The two parts are listed in HighlightInfo.childParts[2]. Any of the parts
-     * can be null.
-     * The result is stored in HighlightInfo.
-     * <p/>
-     * Caller must clear the HighlightInfo as appropriate before this call.
-     *
-     * @param parentPart    The parent part, always a layout.
-     * @param isVertical    True for vertical parts, thus computing an horizontal line.
-     * @param highlightInfo The in-out highlight info.
-     */
-    private static void computeLinearLine(UiLayoutEditPart parentPart,
-            boolean isVertical, HighlightInfo highlightInfo) {
-        Rectangle r = parentPart.getBounds();
-
-        if (isVertical) {
-            Point p = null;
-            UiElementEditPart part = highlightInfo.childParts[0];
-            if (part != null) {
-                p = part.getBounds().getBottom();
-            } else {
-                part = highlightInfo.childParts[1];
-                if (part != null) {
-                    p = part.getBounds().getTop();
-                }
-            }
-            if (p != null) {
-                // horizontal line with middle anchor point
-                highlightInfo.tempPoints[0].setLocation(0, p.y);
-                highlightInfo.tempPoints[1].setLocation(r.width, p.y);
-                highlightInfo.linePoints = highlightInfo.tempPoints;
-                highlightInfo.anchorPoint = p.setLocation(r.width / 2, p.y);
-            }
-        } else {
-            Point p = null;
-            UiElementEditPart part = highlightInfo.childParts[0];
-            if (part != null) {
-                p = part.getBounds().getRight();
-            } else {
-                part = highlightInfo.childParts[1];
-                if (part != null) {
-                    p = part.getBounds().getLeft();
-                }
-            }
-            if (p != null) {
-                // vertical line with middle anchor point
-                highlightInfo.tempPoints[0].setLocation(p.x, 0);
-                highlightInfo.tempPoints[1].setLocation(p.x, r.height);
-                highlightInfo.linePoints = highlightInfo.tempPoints;
-                highlightInfo.anchorPoint = p.setLocation(p.x, r.height / 2);
-            }
-        }
-    }
-
-    /**
-     * Returns true if the linear layout is marked as vertical.
-     *
-     * @param parent The a layout part that must be a LinearLayout
-     * @return True if the linear layout has a vertical orientation attribute.
-     */
-    private static boolean isVertical(UiElementEditPart parent) {
-        String orientation = parent.getStringAttr("orientation");     //$NON-NLS-1$
-        boolean isVertical = "vertical".equals(orientation) ||        //$NON-NLS-1$
-                             "1".equals(orientation);                 //$NON-NLS-1$
-        return isVertical;
-    }
-
-
-    //----- RelativeLayout --------
-
-    /**
-     * Finds the "target" relative layout item for the drop operation & feedback.
-     * <p/>
-     * If the drop point is exactly on a current item, simply returns the side the drop will occur
-     * compared to the center of that element. For the actual XML, we'll need to insert *after*
-     * that element to make sure that referenced are defined in the right order.
-     * In that case the result contains two elements, the second one always being on the right or
-     * bottom side of the first one. When insert in XML, we want to insert right before that
-     * second element or at the end of the child list if the second element is null.
-     * <p/>
-     * If the drop point is not exactly on a current element, find the closest in each
-     * direction and align with the two closest of these.
-     *
-     * @return null if we fail to find anything (such as there are currently no items to compare
-     *         with); otherwise fills the {@link RelativeInfo} and return it.
-     */
-    private static RelativeInfo findRelativeTarget(UiElementEditPart parent,
-            Point point,
-            RelativeInfo outInfo) {
-
-        for (int i = 0; i < 4; i++) {
-            sTempMinDists[i] = Integer.MAX_VALUE;
-            sTempClosests[i] = null;
-        }
-
-
-        for (Object child : parent.getChildren()) {
-            if (child instanceof UiElementEditPart) {
-                UiElementEditPart childPart = (UiElementEditPart) child;
-                Rectangle r = childPart.getBounds();
-                if (r.contains(point)) {
-
-                    float rx = ((float)(point.x - r.x) / (float)r.width ) - 0.5f;
-                    float ry = ((float)(point.y - r.y) / (float)r.height) - 0.5f;
-
-                    /*   TOP
-                     *  \   /
-                     *   \ /
-                     * L  X  R
-                     *   / \
-                     *  /   \
-                     *   BOT
-                     */
-
-                    int index = 0;
-                    if (Math.abs(rx) >= Math.abs(ry)) {
-                        if (rx < 0) {
-                            outInfo.direction = LEFT;
-                            index = 1;
-                        } else {
-                            outInfo.direction = RIGHT;
-                        }
-                    } else {
-                        if (ry < 0) {
-                            outInfo.direction = TOP;
-                            index = 1;
-                        } else {
-                            outInfo.direction = BOTTOM;
-                        }
-                    }
-
-                    outInfo.anchorIndex = index;
-                    outInfo.targetParts[index] = childPart;
-                    outInfo.targetParts[1 - index] = findClosestPart(childPart,
-                            outInfo.direction);
-
-                    return outInfo;
-                }
-
-                computeClosest(point, childPart, sTempClosests, sTempMinDists, TOP);
-                computeClosest(point, childPart, sTempClosests, sTempMinDists, LEFT);
-                computeClosest(point, childPart, sTempClosests, sTempMinDists, BOTTOM);
-                computeClosest(point, childPart, sTempClosests, sTempMinDists, RIGHT);
-            }
-        }
-
-        UiElementEditPart closest = null;
-        int minDist = Integer.MAX_VALUE;
-        int minDir = -1;
-
-        for (int i = 0; i <= MAX_DIR; i++) {
-            if (sTempClosests[i] != null && sTempMinDists[i] < minDist) {
-                closest = sTempClosests[i];
-                minDist = sTempMinDists[i];
-                minDir = i;
-            }
-        }
-
-        if (closest != null) {
-            int index = 0;
-            switch(minDir) {
-            case TOP:
-            case LEFT:
-                index = 0;
-                break;
-            case BOTTOM:
-            case RIGHT:
-                index = 1;
-                break;
-            }
-            outInfo.anchorIndex = index;
-            outInfo.targetParts[index] = closest;
-            outInfo.targetParts[1 - index] = findClosestPart(closest, sOppositeDirection[minDir]);
-            outInfo.direction = sOppositeDirection[minDir];
-            return outInfo;
-        }
-
-        return null;
-    }
-
-    /**
-     * Computes the highlight line for a drop on a RelativeLayout.
-     * <p/>
-     * The line is always placed on the side of the anchor part indicated by the
-     * direction. The direction always point from the anchor part to the drop point.
-     * <p/>
-     * If there's no anchor part, use the other one with a reversed direction.
-     * <p/>
-     * On output, this updates the {@link HighlightInfo}.
-     */
-    private static void computeRelativeLine(UiLayoutEditPart parentPart,
-            RelativeInfo relInfo,
-            HighlightInfo highlightInfo) {
-
-        UiElementEditPart[] parts = relInfo.targetParts;
-        int dir = relInfo.direction;
-        int index = relInfo.anchorIndex;
-        UiElementEditPart part = parts[index];
-
-        if (part == null) {
-            dir = sOppositeDirection[dir];
-            part = parts[1 - index];
-        }
-        if (part == null) {
-            // give up if both parts are null
-            return;
-        }
-
-        Rectangle r = part.getBounds();
-        Point p = null;
-        switch(dir) {
-        case TOP:
-            p = r.getTop();
-            break;
-        case BOTTOM:
-            p = r.getBottom();
-            break;
-        case LEFT:
-            p = r.getLeft();
-            break;
-        case RIGHT:
-            p = r.getRight();
-            break;
-        }
-
-        highlightInfo.anchorPoint = p;
-
-        r = parentPart.getBounds();
-        switch(dir) {
-        case TOP:
-        case BOTTOM:
-            // horizontal line with middle anchor point
-            highlightInfo.tempPoints[0].setLocation(0, p.y);
-            highlightInfo.tempPoints[1].setLocation(r.width, p.y);
-            highlightInfo.linePoints = highlightInfo.tempPoints;
-            highlightInfo.anchorPoint = p;
-            break;
-        case LEFT:
-        case RIGHT:
-            // vertical line with middle anchor point
-            highlightInfo.tempPoints[0].setLocation(p.x, 0);
-            highlightInfo.tempPoints[1].setLocation(p.x, r.height);
-            highlightInfo.linePoints = highlightInfo.tempPoints;
-            highlightInfo.anchorPoint = p;
-            break;
-        }
-    }
-
-    /**
-     * Given a certain reference point (drop point), computes the distance to the given
-     * part in the given direction. For example if direction is top, only accepts parts which
-     * bottom is above the reference point, computes their distance and then updates the
-     * current minimal distances and current closest parts arrays accordingly.
-     */
-    private static void computeClosest(Point refPoint,
-            UiElementEditPart compareToPart,
-            UiElementEditPart[] currClosests,
-            int[] currMinDists,
-            int direction) {
-        Rectangle r = compareToPart.getBounds();
-
-        Point p = null;
-        boolean usable = false;
-
-        switch(direction) {
-        case TOP:
-            p = r.getBottom();
-            usable = p.y <= refPoint.y;
-            break;
-        case BOTTOM:
-            p = r.getTop();
-            usable = p.y >= refPoint.y;
-            break;
-        case LEFT:
-            p = r.getRight();
-            usable = p.x <= refPoint.x;
-            break;
-        case RIGHT:
-            p = r.getLeft();
-            usable = p.x >= refPoint.x;
-            break;
-        }
-
-        if (usable) {
-            int d = p.getDistance2(refPoint);
-            if (d < currMinDists[direction]) {
-                currMinDists[direction] = d;
-                currClosests[direction] = compareToPart;
-            }
-        }
-    }
-
-    /**
-     * Given a reference parts, finds the closest part in the parent in the given direction.
-     * For example if direction is top, finds the closest sibling part which is above the
-     * reference part and non-overlapping (they can touch.)
-     */
-    private static UiElementEditPart findClosestPart(UiElementEditPart referencePart,
-            int direction) {
-        if (referencePart == null || referencePart.getParent() == null) {
-            return null;
-        }
-
-        Rectangle r = referencePart.getBounds();
-        Point ref = null;
-        switch(direction) {
-        case TOP:
-            ref = r.getTop();
-            break;
-        case BOTTOM:
-            ref = r.getBottom();
-            break;
-        case LEFT:
-            ref = r.getLeft();
-            break;
-        case RIGHT:
-            ref = r.getRight();
-            break;
-        }
-
-        int minDist = Integer.MAX_VALUE;
-        UiElementEditPart closestPart = null;
-
-        for (Object childPart : referencePart.getParent().getChildren()) {
-            if (childPart != referencePart && childPart instanceof UiElementEditPart) {
-                r = ((UiElementEditPart) childPart).getBounds();
-                Point p = null;
-                boolean usable = false;
-
-                switch(direction) {
-                case TOP:
-                    p = r.getBottom();
-                    usable = p.y <= ref.y;
-                    break;
-                case BOTTOM:
-                    p = r.getTop();
-                    usable = p.y >= ref.y;
-                    break;
-                case LEFT:
-                    p = r.getRight();
-                    usable = p.x <= ref.x;
-                    break;
-                case RIGHT:
-                    p = r.getLeft();
-                    usable = p.x >= ref.x;
-                    break;
-                }
-
-                if (usable) {
-                    int d = p.getDistance2(ref);
-                    if (d < minDist) {
-                        minDist = d;
-                        closestPart = (UiElementEditPart) childPart;
-                    }
-                }
-            }
-        }
-
-        return closestPart;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementCreateCommand.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementCreateCommand.java
deleted file mode 100644
index 562570f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementCreateCommand.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor.UiEditorActions;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.gef.commands.Command;
-
-/**
- * A command that knows how to instantiate a new element based on a given {@link ElementDescriptor},
- * the parent {@link UiElementEditPart} and an optional target location.
- *
- * @since GLE1
- */
-public class ElementCreateCommand extends Command {
-
-    /** Descriptor of the new element to create */
-    private final ElementDescriptor mDescriptor;
-    /** The edit part that hosts the new edit part */
-    private final UiElementEditPart mParentPart;
-    /** The drop location in parent coordinates */
-    private final Point mTargetPoint;
-
-    /**
-     * Creates a new {@link ElementCreateCommand}.
-     *
-     * @param descriptor Descriptor of the new element to create
-     * @param targetPart The edit part that hosts the new edit part
-     * @param targetPoint The drop location in parent coordinates
-     */
-    public ElementCreateCommand(ElementDescriptor descriptor,
-            UiElementEditPart targetPart, Point targetPoint) {
-                mDescriptor = descriptor;
-                mParentPart = targetPart;
-                mTargetPoint = targetPoint;
-    }
-
-    // --- Methods inherited from Command ---
-
-    @Override
-    public boolean canExecute() {
-        return mDescriptor != null &&
-            mParentPart != null &&
-            mParentPart.getUiNode() != null &&
-            mParentPart.getUiNode().getEditor() instanceof LayoutEditor;
-    }
-
-    @Override
-    public void execute() {
-        super.execute();
-        UiElementNode uiParent = mParentPart.getUiNode();
-        if (uiParent != null) {
-            final AndroidEditor editor = uiParent.getEditor();
-            if (editor instanceof LayoutEditor) {
-                ((LayoutEditor) editor).wrapUndoRecording(
-                        String.format("Create %1$s", mDescriptor.getXmlLocalName()),
-                        new Runnable() {
-                    public void run() {
-                        UiEditorActions actions = ((LayoutEditor) editor).getUiEditorActions();
-                        if (actions != null) {
-                            DropFeedback.addElementToXml(mParentPart, mDescriptor, mTargetPoint,
-                                    actions);
-                        }
-                    }
-                });
-            }
-        }
-    }
-
-    @Override
-    public void redo() {
-        throw new UnsupportedOperationException("redo not supported by this command"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void undo() {
-        throw new UnsupportedOperationException("undo not supported by this command"); //$NON-NLS-1$
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementFigure.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementFigure.java
deleted file mode 100644
index 23c2c9e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementFigure.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import org.eclipse.draw2d.ColorConstants;
-import org.eclipse.draw2d.Figure;
-import org.eclipse.draw2d.Graphics;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.swt.SWT;
-
-
-/**
- * The figure used to draw basic elements.
- * <p/>
- * The figure is totally empty and transparent except for the selection border.
- *
- * @since GLE1
- */
-class ElementFigure extends Figure {
-
-    private boolean mIsSelected;
-    private Rectangle mInnerBounds;
-
-    public ElementFigure() {
-        setOpaque(false);
-    }
-
-    public void setSelected(boolean isSelected) {
-        if (isSelected != mIsSelected) {
-            mIsSelected = isSelected;
-            repaint();
-        }
-    }
-
-    @Override
-    public void setBounds(Rectangle rect) {
-        super.setBounds(rect);
-
-        mInnerBounds = getBounds().getCopy();
-        if (mInnerBounds.width > 0) {
-            mInnerBounds.width--;
-        }
-        if (mInnerBounds.height > 0) {
-            mInnerBounds.height--;
-        }
-    }
-
-    public Rectangle getInnerBounds() {
-        return mInnerBounds;
-    }
-
-    @Override
-    protected void paintBorder(Graphics graphics) {
-        super.paintBorder(graphics);
-
-        if (mIsSelected) {
-            graphics.setLineWidth(1);
-            graphics.setLineStyle(SWT.LINE_SOLID);
-            graphics.setForegroundColor(ColorConstants.red);
-            graphics.drawRectangle(getInnerBounds());
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/LayoutFigure.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/LayoutFigure.java
deleted file mode 100644
index 6334751..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/LayoutFigure.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiLayoutEditPart.HighlightInfo;
-
-import org.eclipse.draw2d.ColorConstants;
-import org.eclipse.draw2d.Figure;
-import org.eclipse.draw2d.Graphics;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.swt.SWT;
-
-/**
- * The figure used to draw the feedback on a layout.
- * <p/>
- * By default the figure is transparent and empty.
- * The base {@link ElementFigure} knows how to draw the selection border.
- * This figure knows how to draw the drop feedback.
- *
- * @since GLE1
- */
-class LayoutFigure extends ElementFigure {
-
-    private HighlightInfo mHighlightInfo;
-
-    public LayoutFigure() {
-        super();
-    }
-
-    public void setHighlighInfo(HighlightInfo highlightInfo) {
-        mHighlightInfo = highlightInfo;
-        repaint();
-    }
-
-    /**
-     * Paints the "border" for this figure.
-     * <p/>
-     * The parent {@link Figure#paint(Graphics)} calls {@link #paintFigure(Graphics)} then
-     * {@link #paintClientArea(Graphics)} then {@link #paintBorder(Graphics)}. Here we thus
-     * draw the actual highlight border but also the highlight anchor lines and points so that
-     * we can make sure they are all drawn on top of the border.
-     * <p/>
-     * Note: This method doesn't really need to restore its graphic state. The parent
-     * Figure will do it for us.
-     * <p/>
-     *
-     * @param graphics The Graphics object used for painting
-     */
-    @Override
-    protected void paintBorder(Graphics graphics) {
-        super.paintBorder(graphics);
-
-        if (mHighlightInfo == null) {
-            return;
-        }
-
-        // Draw the border. We want other highlighting to be drawn on top of the border.
-        if (mHighlightInfo.drawDropBorder) {
-            graphics.setLineWidth(3);
-            graphics.setLineStyle(SWT.LINE_SOLID);
-            graphics.setForegroundColor(ColorConstants.green);
-            graphics.drawRectangle(getInnerBounds().getCopy().shrink(1, 1));
-        }
-
-        Rectangle bounds = getBounds();
-        int bx = bounds.x;
-        int by = bounds.y;
-        int w = bounds.width;
-        int h = bounds.height;
-
-        // Draw frames of target child parts, if any
-        if (mHighlightInfo.childParts != null) {
-            graphics.setLineWidth(2);
-            graphics.setLineStyle(SWT.LINE_DOT);
-            graphics.setForegroundColor(ColorConstants.lightBlue);
-            for (UiElementEditPart part : mHighlightInfo.childParts) {
-                if (part != null) {
-                    graphics.drawRectangle(part.getBounds().getCopy().translate(bx, by));
-                }
-            }
-        }
-
-        // Draw the target line, if any
-        if (mHighlightInfo.linePoints != null) {
-            int x1 = mHighlightInfo.linePoints[0].x;
-            int y1 = mHighlightInfo.linePoints[0].y;
-            int x2 = mHighlightInfo.linePoints[1].x;
-            int y2 = mHighlightInfo.linePoints[1].y;
-
-            // if the line is right to the edge, draw it one pixel more inside so that the
-            // full 2-pixel width be visible.
-            if (x1 <= 0) x1++;
-            if (x2 <= 0) x2++;
-            if (y1 <= 0) y1++;
-            if (y2 <= 0) y2++;
-
-            if (x1 >= w - 1) x1--;
-            if (x2 >= w - 1) x2--;
-            if (y1 >= h - 1) y1--;
-            if (y2 >= h - 1) y2--;
-
-            x1 += bx;
-            x2 += bx;
-            y1 += by;
-            y2 += by;
-
-            graphics.setLineWidth(2);
-            graphics.setLineStyle(SWT.LINE_DASH);
-            graphics.setLineCap(SWT.CAP_ROUND);
-            graphics.setForegroundColor(ColorConstants.orange);
-            graphics.drawLine(x1, y1, x2, y2);
-        }
-
-        // Draw the anchor point, if any
-        if (mHighlightInfo.anchorPoint != null) {
-            int x = mHighlightInfo.anchorPoint.x;
-            int y = mHighlightInfo.anchorPoint.y;
-
-            // If the point is right on the edge, draw it one pixel inside so that it
-            // matches the highlight line. It makes it slightly more visible that way.
-            if (x <= 0) x++;
-            if (y <= 0) y++;
-            if (x >= w - 1) x--;
-            if (y >= h - 1) y--;
-            x += bx;
-            y += by;
-
-            graphics.setLineWidth(2);
-            graphics.setLineStyle(SWT.LINE_SOLID);
-            graphics.setLineCap(SWT.CAP_ROUND);
-            graphics.setForegroundColor(ColorConstants.orange);
-            graphics.drawLine(x-5, y-5, x+5, y+5);
-            graphics.drawLine(x-5, y+5, x+5, y-5);
-            // 7 * cos(45) == 5 so we use 8 for the circle radius (it looks slightly better than 7)
-            graphics.setLineWidth(1);
-            graphics.drawOval(x-8, y-8, 16, 16);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentEditPart.java
deleted file mode 100644
index 9f6557c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentEditPart.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.draw2d.AbstractBackground;
-import org.eclipse.draw2d.ColorConstants;
-import org.eclipse.draw2d.FreeformLayer;
-import org.eclipse.draw2d.FreeformLayout;
-import org.eclipse.draw2d.Graphics;
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.Label;
-import org.eclipse.draw2d.geometry.Insets;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.EditPolicy;
-import org.eclipse.gef.Request;
-import org.eclipse.gef.RequestConstants;
-import org.eclipse.gef.editpolicies.RootComponentEditPolicy;
-import org.eclipse.gef.requests.DropRequest;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.widgets.Display;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferInt;
-
-/**
- * Graphical edit part for the root document.
- * <p/>
- * It acts as a simple container.
- *
- * @since GLE1
- */
-public class UiDocumentEditPart extends UiElementEditPart {
-
-    private Display mDisplay;
-    private FreeformLayer mLayer;
-    private ImageBackground mImage;
-    private Label mChild = null;
-
-    final static class ImageBackground extends AbstractBackground {
-
-        private BufferedImage mBufferedImage;
-        private Image mImage;
-
-        ImageBackground() {
-        }
-
-        ImageBackground(BufferedImage image, Display display) {
-            setImage(image, display);
-        }
-
-        @Override
-        public void paintBackground(IFigure figure, Graphics graphics, Insets insets) {
-            if (mImage != null) {
-                Rectangle rect = getPaintRectangle(figure, insets);
-                graphics.drawImage(mImage, rect.x, rect.y);
-            }
-        }
-
-        void setImage(BufferedImage image, Display display) {
-            if (image != null) {
-                int[] data = ((DataBufferInt)image.getData().getDataBuffer()).getData();
-
-                ImageData imageData = new ImageData(image.getWidth(), image.getHeight(), 32,
-                      new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF));
-
-                imageData.setPixels(0, 0, data.length, data, 0);
-
-                mImage = new Image(display, imageData);
-            } else {
-                mImage = null;
-            }
-        }
-
-        BufferedImage getBufferedImage() {
-            return mBufferedImage;
-        }
-    }
-
-    public UiDocumentEditPart(UiDocumentNode uiDocumentNode, Display display) {
-        super(uiDocumentNode);
-        mDisplay = display;
-    }
-
-    @Override
-    protected IFigure createFigure() {
-        mLayer = new FreeformLayer();
-        mLayer.setLayoutManager(new FreeformLayout());
-
-        mLayer.setOpaque(true);
-        mLayer.setBackgroundColor(ColorConstants.lightGray);
-
-        return mLayer;
-    }
-
-    @Override
-    protected void refreshVisuals() {
-        UiElementNode model = (UiElementNode)getModel();
-
-        Object editData = model.getEditData();
-        if (editData instanceof BufferedImage) {
-            BufferedImage image = (BufferedImage)editData;
-
-            if (mImage == null || image != mImage.getBufferedImage()) {
-                mImage = new ImageBackground(image, mDisplay);
-            }
-
-            mLayer.setBorder(mImage);
-
-            if (mChild != null && mChild.getParent() == mLayer) {
-                mLayer.remove(mChild);
-            }
-        } else if (editData instanceof String) {
-            mLayer.setBorder(null);
-            if (mChild == null) {
-                mChild = new Label();
-            }
-            mChild.setText((String)editData);
-
-            if (mChild != null && mChild.getParent() != mLayer) {
-                mLayer.add(mChild);
-            }
-            Rectangle bounds = mChild.getTextBounds();
-            bounds.x = bounds.y = 0;
-            mLayer.setConstraint(mChild, bounds);
-        }
-
-        // refresh the children as well
-        refreshChildrenVisuals();
-    }
-
-    @Override
-    protected void hideSelection() {
-        // no selection at this level.
-    }
-
-    @Override
-    protected void showSelection() {
-        // no selection at this level.
-    }
-
-    @Override
-    protected void createEditPolicies() {
-        super.createEditPolicies();
-
-        // This policy indicates this a root component that cannot be removed
-        installEditPolicy(EditPolicy.COMPONENT_ROLE, new RootComponentEditPolicy());
-
-        installLayoutEditPolicy(this);
-    }
-
-    /**
-     * Returns the EditPart that should be used as the target for the specified Request.
-     * For instance this is called during drag'n'drop with a CreateRequest.
-     * <p/>
-     * For the root document, we want the first child edit part to the be the target
-     * since an XML document can have only one root element.
-     *
-     * {@inheritDoc}
-     */
-    @Override
-    public EditPart getTargetEditPart(Request request) {
-        if (request != null && request.getType() == RequestConstants.REQ_CREATE) {
-            // We refuse the drop if it's not in the bounds of the document.
-            if (request instanceof DropRequest) {
-                Point where = ((DropRequest) request).getLocation().getCopy();
-                UiElementNode uiNode = getUiNode();
-                if (uiNode instanceof UiDocumentNode) {
-                    // Take the bounds of the background image as the valid drop zone
-                    Object editData = uiNode.getEditData();
-                    if (editData instanceof BufferedImage) {
-                        BufferedImage image = (BufferedImage)editData;
-                        int w = image.getWidth();
-                        int h = image.getHeight();
-                        if (where.x > w || where.y > h) {
-                            return null;
-                        }
-                    }
-
-                }
-            }
-
-            // For the root document, we want the first child edit part to the be the target
-            // since an XML document can have only one root element.
-            if (getChildren().size() > 0) {
-                Object o = getChildren().get(0);
-                if (o instanceof EditPart) {
-                    return ((EditPart) o).getTargetEditPart(request);
-                }
-            }
-        }
-        return super.getTargetEditPart(request);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentTreeEditPart.java
deleted file mode 100644
index b78c519..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentTreeEditPart.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-
-import java.util.List;
-
-/**
- * Implementation of {@link UiElementTreeEditPart} for the document root.
- *
- * @since GLE1
- */
-public class UiDocumentTreeEditPart extends UiElementTreeEditPart {
-
-    public UiDocumentTreeEditPart(UiDocumentNode model) {
-        super(model);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected List getModelChildren() {
-        return getUiNode().getUiChildren();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementEditPart.java
deleted file mode 100644
index 75c7b6d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementEditPart.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.gef.DragTracker;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.EditPolicy;
-import org.eclipse.gef.GraphicalEditPart;
-import org.eclipse.gef.Request;
-import org.eclipse.gef.RequestConstants;
-import org.eclipse.gef.commands.Command;
-import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
-import org.eclipse.gef.editpolicies.LayoutEditPolicy;
-import org.eclipse.gef.editpolicies.SelectionEditPolicy;
-import org.eclipse.gef.requests.CreateRequest;
-import org.eclipse.gef.requests.DropRequest;
-import org.eclipse.gef.tools.SelectEditPartTracker;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-import java.util.List;
-
-/**
- * An {@link EditPart} for a {@link UiElementNode}.
- *
- * @since GLE1
- */
-public abstract class UiElementEditPart extends AbstractGraphicalEditPart
-    implements IUiUpdateListener {
-
-    public UiElementEditPart(UiElementNode uiElementNode) {
-        setModel(uiElementNode);
-    }
-
-    //-------------------------
-    // Derived classes must define these
-
-    abstract protected void hideSelection();
-    abstract protected void showSelection();
-
-    //-------------------------
-    // Base class overrides
-
-    @Override
-    public DragTracker getDragTracker(Request request) {
-        return new SelectEditPartTracker(this);
-    }
-
-    @Override
-    protected void createEditPolicies() {
-        /*
-         * This is no longer needed, as a selection edit policy is set by the parent layout.
-         * Leave this code commented out right now, I'll want to play with this later.
-         *
-        installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE,
-                new NonResizableSelectionEditPolicy(this));
-         */
-    }
-
-    /* (non-javadoc)
-     * Returns a List containing the children model objects.
-     * Must not return null, instead use the super which returns an empty list.
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    protected List getModelChildren() {
-        return getUiNode().getUiChildren();
-    }
-
-    @Override
-    public void activate() {
-        super.activate();
-        getUiNode().addUpdateListener(this);
-    }
-
-    @Override
-    public void deactivate() {
-        super.deactivate();
-        getUiNode().removeUpdateListener(this);
-    }
-
-    @Override
-    protected void refreshVisuals() {
-        if (getFigure().getParent() != null) {
-            ((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), getBounds());
-        }
-
-        // update the visuals of the children as well
-        refreshChildrenVisuals();
-    }
-
-    protected void refreshChildrenVisuals() {
-        if (children != null) {
-            for (Object child : children) {
-                if (child instanceof UiElementEditPart) {
-                    UiElementEditPart childPart = (UiElementEditPart)child;
-                    childPart.refreshVisuals();
-                }
-            }
-        }
-    }
-
-    //-------------------------
-    // IUiUpdateListener implementation
-
-    public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
-        // TODO: optimize by refreshing only when needed
-        switch(state) {
-        case ATTR_UPDATED:
-            refreshVisuals();
-            break;
-        case CHILDREN_CHANGED:
-            refreshChildren();
-
-            // new children list, need to update the layout
-            refreshVisuals();
-            break;
-        case CREATED:
-            refreshVisuals();
-            break;
-        case DELETED:
-            // pass
-            break;
-        }
-    }
-
-    //-------------------------
-    // Local methods
-
-    /** @return The object model casted to an {@link UiElementNode} */
-    public final UiElementNode getUiNode() {
-        return (UiElementNode) getModel();
-    }
-
-    protected final ElementDescriptor getDescriptor() {
-        return getUiNode().getDescriptor();
-    }
-
-    protected final UiElementEditPart getEditPartParent() {
-        EditPart parent = getParent();
-        if (parent instanceof UiElementEditPart) {
-            return (UiElementEditPart)parent;
-        }
-        return null;
-    }
-
-    /**
-     * Returns a given XML attribute.
-     * @param attrName The local name of the attribute.
-     * @return the attribute as a {@link String}, if it exists, or <code>null</code>
-     */
-    protected final String getStringAttr(String attrName) {
-        UiElementNode uiNode = getUiNode();
-        if (uiNode.getXmlNode() != null) {
-            Node xmlNode = uiNode.getXmlNode();
-            if (xmlNode != null) {
-                NamedNodeMap nodeAttributes = xmlNode.getAttributes();
-                if (nodeAttributes != null) {
-                    Node attr = nodeAttributes.getNamedItemNS(
-                            SdkConstants.NS_RESOURCES, attrName);
-                    if (attr != null) {
-                        return attr.getNodeValue();
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    protected final Rectangle getBounds() {
-        UiElementNode model = (UiElementNode)getModel();
-
-        Object editData = model.getEditData();
-
-        if (editData != null) {
-            // assert with fully qualified class name to prevent import changes to another
-            // Rectangle class.
-            assert (editData instanceof org.eclipse.draw2d.geometry.Rectangle);
-
-            return (Rectangle)editData;
-        }
-
-        // return a dummy rect
-        return new Rectangle(0, 0, 0, 0);
-    }
-
-    /**
-     * Returns the EditPart that should be used as the target for the specified Request.
-     * <p/>
-     * For instance this is called during drag'n'drop with a CreateRequest.
-     * <p/>
-     * Reject being a target for elements which descriptor does not allow children.
-     *
-     * {@inheritDoc}
-     */
-    @Override
-    public EditPart getTargetEditPart(Request request) {
-        if (request != null && request.getType() == RequestConstants.REQ_CREATE) {
-            // Reject being a target for elements which descriptor does not allow children.
-            if (!getUiNode().getDescriptor().hasChildren()) {
-                return null;
-            }
-        }
-        return super.getTargetEditPart(request);
-    }
-
-    /**
-     * Used by derived classes {@link UiDocumentEditPart} and {@link UiLayoutEditPart}
-     * to accept drag'n'drop of new items from the palette.
-     *
-     * @param layoutEditPart The layout edit part where this policy is installed. It can
-     *        be either a {@link UiDocumentEditPart} or a {@link UiLayoutEditPart}.
-     */
-    protected void installLayoutEditPolicy(final UiElementEditPart layoutEditPart) {
-        // This policy indicates how elements can be constrained by the layout.
-        // TODO Right now we use the XY layout policy since our constraints are
-        // handled by the android rendering engine rather than GEF. Tweak as
-        // appropriate.
-        installEditPolicy(EditPolicy.LAYOUT_ROLE,  new LayoutEditPolicy() {
-
-            /**
-             * We don't allow layout children to be resized yet.
-             * <p/>
-             * Typical choices would be:
-             * <ul>
-             * <li> ResizableEditPolicy, to allow for selection, move and resize.
-             * <li> NonResizableEditPolicy, to allow for selection, move but not resize.
-             * <li> SelectionEditPolicy to allow for only selection.
-             * </ul>
-             * <p/>
-             * TODO: make this depend on the part layout. For an AbsoluteLayout we should
-             * probably use a NonResizableEditPolicy and SelectionEditPolicy for the rest.
-             * Whether to use ResizableEditPolicy or NonResizableEditPolicy should depend
-             * on the child in an AbsoluteLayout.
-             */
-            @Override
-            protected EditPolicy createChildEditPolicy(EditPart child) {
-                if (child instanceof UiElementEditPart) {
-                    return new NonResizableSelectionEditPolicy((UiElementEditPart) child);
-                }
-                return null;
-            }
-
-            @Override
-            protected Command getCreateCommand(CreateRequest request) {
-                // We store the ElementDescriptor in the request.factory.type
-                Object newType = request.getNewObjectType();
-                if (newType instanceof ElementDescriptor) {
-                    Point where = request.getLocation().getCopy();
-                    Point origin = getLayoutContainer().getClientArea().getLocation();
-                    where.translate(origin.getNegated());
-
-                    // The host is the EditPart where this policy is installed,
-                    // e.g. this UiElementEditPart.
-                    EditPart host = getHost();
-                    if (host instanceof UiElementEditPart) {
-
-                        return new ElementCreateCommand((ElementDescriptor) newType,
-                                (UiElementEditPart) host,
-                                where);
-                    }
-                }
-
-                return null;
-            }
-
-            @Override
-            protected Command getMoveChildrenCommand(Request request) {
-                // TODO Auto-generated method stub
-                return null;
-            }
-
-            @Override
-            public void showLayoutTargetFeedback(Request request) {
-                super.showLayoutTargetFeedback(request);
-
-                // for debugging
-                // System.out.println("target: " + request.toString() + " -- " + layoutEditPart.getUiNode().getBreadcrumbTrailDescription(false));
-
-                if (layoutEditPart instanceof UiLayoutEditPart &&
-                        request instanceof DropRequest) {
-                    Point where = ((DropRequest) request).getLocation().getCopy();
-                    Point origin = getLayoutContainer().getClientArea().getLocation();
-                    where.translate(origin.getNegated());
-
-                    ((UiLayoutEditPart) layoutEditPart).showDropTarget(where);
-                }
-            }
-
-            @Override
-            protected void eraseLayoutTargetFeedback(Request request) {
-                super.eraseLayoutTargetFeedback(request);
-                if (layoutEditPart instanceof UiLayoutEditPart) {
-                    ((UiLayoutEditPart) layoutEditPart).hideDropTarget();
-                }
-            }
-
-            @Override
-            protected IFigure createSizeOnDropFeedback(CreateRequest createRequest) {
-                // TODO understand if this is useful for us or remove
-                return super.createSizeOnDropFeedback(createRequest);
-            }
-
-        });
-    }
-
-    protected static class NonResizableSelectionEditPolicy extends SelectionEditPolicy {
-
-        private final UiElementEditPart mEditPart;
-
-        public NonResizableSelectionEditPolicy(UiElementEditPart editPart) {
-            mEditPart = editPart;
-        }
-
-        @Override
-        protected void hideSelection() {
-            mEditPart.hideSelection();
-        }
-
-        @Override
-        protected void showSelection() {
-            mEditPart.showSelection();
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPart.java
deleted file mode 100644
index 81737f8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPart.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.gef.editparts.AbstractTreeEditPart;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
-
-/**
- * Base {@link AbstractTreeEditPart} to represent {@link UiElementNode} objects in the
- * {@link IContentOutlinePage} linked to the layout editor.
- *
- * @since GLE1
- */
-public class UiElementTreeEditPart extends AbstractTreeEditPart {
-
-    public UiElementTreeEditPart(UiElementNode uiElementNode) {
-        setModel(uiElementNode);
-    }
-
-    @Override
-    protected void createEditPolicies() {
-        // TODO Auto-generated method stub
-        super.createEditPolicies();
-    }
-
-    @Override
-    protected Image getImage() {
-        return getUiNode().getDescriptor().getIcon();
-    }
-
-    @Override
-    protected String getText() {
-        return getUiNode().getShortDescription();
-    }
-
-    @Override
-    public void activate() {
-        if (!isActive()) {
-            super.activate();
-            // TODO
-        }
-    }
-
-    @Override
-    public void deactivate() {
-        if (isActive()) {
-            super.deactivate();
-            // TODO
-        }
-    }
-
-    /**
-     * Returns the casted model object represented by this {@link AbstractTreeEditPart}.
-     */
-    protected UiElementNode getUiNode() {
-        return (UiElementNode)getModel();
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPartFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPartFactory.java
deleted file mode 100644
index c10298c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPartFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.EditPartFactory;
-import org.eclipse.gef.editparts.AbstractTreeEditPart;
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
-
-/**
- * {@link EditPartFactory} to create {@link AbstractTreeEditPart} for {@link UiElementNode} objects.
- * These objects are used in the {@link IContentOutlinePage} linked to the layout editor.
- *
- * @since GLE1
- */
-public class UiElementTreeEditPartFactory implements EditPartFactory {
-
-    public EditPart createEditPart(EditPart context, Object model) {
-        if (model instanceof UiDocumentNode) {
-            return new UiDocumentTreeEditPart((UiDocumentNode) model);
-        } else if (model instanceof UiElementNode) {
-            UiElementNode node = (UiElementNode) model;
-            if (node.getDescriptor().hasChildren()) {
-                return new UiLayoutTreeEditPart(node);
-            } else {
-                return new UiViewTreeEditPart(node);
-            }
-        }
-        return null;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementsEditPartFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementsEditPartFactory.java
deleted file mode 100644
index 5f17937..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementsEditPartFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.EditPartFactory;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * A factory that returns the appropriate {@link EditPart} for a given model object.
- * <p/>
- * The only model objects we use are {@link UiElementNode} objects and they are
- * edited using {@link UiElementEditPart}.
- *
- * @since GLE1
- */
-public class UiElementsEditPartFactory implements EditPartFactory {
-
-    private Display mDisplay;
-
-    public UiElementsEditPartFactory(Display display) {
-        mDisplay = display;
-    }
-
-    public EditPart createEditPart(EditPart context, Object model) {
-        if (model instanceof UiDocumentNode) {
-            return new UiDocumentEditPart((UiDocumentNode) model, mDisplay);
-        } else if (model instanceof UiElementNode) {
-            UiElementNode node = (UiElementNode) model;
-
-            if (node.getDescriptor().hasChildren()) {
-                return new UiLayoutEditPart(node);
-            }
-
-            return new UiViewEditPart(node);
-        }
-        return null;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutEditPart.java
deleted file mode 100644
index 14d6edb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutEditPart.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.XYLayout;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.gef.EditPolicy;
-import org.eclipse.gef.commands.Command;
-import org.eclipse.gef.editpolicies.ContainerEditPolicy;
-import org.eclipse.gef.requests.CreateRequest;
-
-/**
- * Graphical edit part for an {@link UiElementNode} that represents a ViewLayout.
- * <p/>
- * It acts as a simple container.
- *
- * @since GLE1
- */
-public final class UiLayoutEditPart extends UiElementEditPart {
-
-    static class HighlightInfo {
-        public boolean drawDropBorder;
-        public UiElementEditPart[] childParts;
-        public Point anchorPoint;
-        public Point linePoints[];
-
-        public final Point tempPoints[] = new Point[] { new Point(), new Point() };
-
-        public void clear() {
-            drawDropBorder = false;
-            childParts = null;
-            anchorPoint = null;
-            linePoints = null;
-        }
-    }
-
-    private final HighlightInfo mHighlightInfo = new HighlightInfo();
-
-    public UiLayoutEditPart(UiElementNode uiElementNode) {
-        super(uiElementNode);
-    }
-
-    @Override
-    protected void createEditPolicies() {
-        super.createEditPolicies();
-
-        installEditPolicy(EditPolicy.CONTAINER_ROLE, new ContainerEditPolicy() {
-            @Override
-            protected Command getCreateCommand(CreateRequest request) {
-                return null;
-            }
-        });
-
-        installLayoutEditPolicy(this);
-    }
-
-    @Override
-    protected IFigure createFigure() {
-        IFigure f = new LayoutFigure();
-        f.setLayoutManager(new XYLayout());
-        return f;
-    }
-
-    @Override
-    protected void showSelection() {
-        IFigure f = getFigure();
-        if (f instanceof ElementFigure) {
-            ((ElementFigure) f).setSelected(true);
-        }
-    }
-
-    @Override
-    protected void hideSelection() {
-        IFigure f = getFigure();
-        if (f instanceof ElementFigure) {
-            ((ElementFigure) f).setSelected(false);
-        }
-    }
-
-    public void showDropTarget(Point where) {
-        if (where != null) {
-            mHighlightInfo.clear();
-            mHighlightInfo.drawDropBorder = true;
-            DropFeedback.computeDropFeedback(this, mHighlightInfo, where);
-
-            IFigure f = getFigure();
-            if (f instanceof LayoutFigure) {
-                ((LayoutFigure) f).setHighlighInfo(mHighlightInfo);
-            }
-        }
-    }
-
-    public void hideDropTarget() {
-        mHighlightInfo.clear();
-        IFigure f = getFigure();
-        if (f instanceof LayoutFigure) {
-            ((LayoutFigure) f).setHighlighInfo(mHighlightInfo);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutTreeEditPart.java
deleted file mode 100644
index 5e78b46..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutTreeEditPart.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import java.util.List;
-
-/**
- * Implementation of {@link UiElementTreeEditPart} for layout objects.
- *
- * @since GLE1
- */
-public class UiLayoutTreeEditPart extends UiElementTreeEditPart {
-
-    public UiLayoutTreeEditPart(UiElementNode node) {
-        super(node);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected List getModelChildren() {
-        return getUiNode().getUiChildren();
-    }
-
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewEditPart.java
deleted file mode 100644
index 430e1ce..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewEditPart.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.XYLayout;
-
-/**
- * Graphical edit part for an {@link UiElementNode} that represents a View.
- *
- * @since GLE1
- */
-public class UiViewEditPart extends UiElementEditPart {
-
-    public UiViewEditPart(UiElementNode uiElementNode) {
-        super(uiElementNode);
-    }
-
-    @Override
-    protected IFigure createFigure() {
-        IFigure f = new ElementFigure();
-        f.setLayoutManager(new XYLayout());
-        return f;
-    }
-
-    @Override
-    protected void showSelection() {
-        IFigure f = getFigure();
-        if (f instanceof ElementFigure) {
-            ((ElementFigure) f).setSelected(true);
-        }
-    }
-
-    @Override
-    protected void hideSelection() {
-        IFigure f = getFigure();
-        if (f instanceof ElementFigure) {
-            ((ElementFigure) f).setSelected(false);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewTreeEditPart.java
deleted file mode 100644
index 22cc952..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewTreeEditPart.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.parts;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * Implementation of {@link UiElementTreeEditPart} for view objects.
- *
- * @since GLE1
- */
-public class UiViewTreeEditPart extends UiElementTreeEditPart {
-
-    public UiViewTreeEditPart(UiElementNode node) {
-        super(node);
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java
deleted file mode 100644
index 0d3f339..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout.uimodel;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IProject;
-
-import java.util.List;
-
-/**
- * Specialized version of {@link UiElementNode} for the {@link ViewElementDescriptor}s.
- */
-public class UiViewElementNode extends UiElementNode {
-
-    private AttributeDescriptor[] mCachedAttributeDescriptors;
-
-    public UiViewElementNode(ViewElementDescriptor elementDescriptor) {
-        super(elementDescriptor);
-    }
-
-    /**
-     * Returns an AttributeDescriptor array that depends on the current UiParent.
-     * <p/>
-     * The array merges both "direct" attributes with the descriptor layout attributes.
-     * The array instance is cached and cleared if the UiParent is changed.
-     */
-    @Override
-    public AttributeDescriptor[] getAttributeDescriptors() {
-        if (mCachedAttributeDescriptors != null) {
-            return mCachedAttributeDescriptors;
-        }
-
-        UiElementNode ui_parent = getUiParent();
-        AttributeDescriptor[] direct_attrs = super.getAttributeDescriptors();
-        mCachedAttributeDescriptors = direct_attrs;
-
-        AttributeDescriptor[] layout_attrs = null;
-        boolean need_xmlns = false;
-
-        if (ui_parent instanceof UiDocumentNode) {
-            // Limitation: right now the layout behaves as if everything was
-            // owned by a FrameLayout.
-            // TODO replace by something user-configurable.
-
-            List<ElementDescriptor> layoutDescriptors = null;
-            IProject project = getEditor().getProject();
-            if (project != null) {
-                Sdk currentSdk = Sdk.getCurrent();
-                IAndroidTarget target = currentSdk.getTarget(project);
-                if (target != null) {
-                    AndroidTargetData data = currentSdk.getTargetData(target);
-                    layoutDescriptors = data.getLayoutDescriptors().getLayoutDescriptors();
-                }
-            }
-            
-            if (layoutDescriptors != null) {
-                for (ElementDescriptor desc : layoutDescriptors) {
-                    if (desc instanceof ViewElementDescriptor &&
-                            desc.getXmlName().equals(AndroidConstants.CLASS_NAME_FRAMELAYOUT)) {
-                        layout_attrs = ((ViewElementDescriptor) desc).getLayoutAttributes();
-                        need_xmlns = true;
-                        break;
-                    }
-                }
-            }
-        } else if (ui_parent instanceof UiViewElementNode){
-            layout_attrs =
-                ((ViewElementDescriptor) ui_parent.getDescriptor()).getLayoutAttributes();
-        }
-
-        if (layout_attrs == null || layout_attrs.length == 0) {
-            return mCachedAttributeDescriptors;
-        }
-
-        mCachedAttributeDescriptors =
-            new AttributeDescriptor[direct_attrs.length +
-                                    layout_attrs.length +
-                                    (need_xmlns ? 1 : 0)];
-        System.arraycopy(direct_attrs, 0,
-                mCachedAttributeDescriptors, 0,
-                direct_attrs.length);
-        System.arraycopy(layout_attrs, 0,
-                mCachedAttributeDescriptors, direct_attrs.length,
-                layout_attrs.length);
-        if (need_xmlns) {
-            AttributeDescriptor desc = new XmlnsAttributeDescriptor(
-                    "android",  //$NON-NLS-1$
-                    SdkConstants.NS_RESOURCES);
-            mCachedAttributeDescriptors[direct_attrs.length + layout_attrs.length] = desc;
-        }
-
-        return mCachedAttributeDescriptors;
-    }
-    
-    /**
-     * Sets the parent of this UI node.
-     * <p/>
-     * Also removes the cached AttributeDescriptor array that depends on the current UiParent.
-     */
-    @Override
-    protected void setUiParent(UiElementNode parent) {
-        super.setUiParent(parent);
-        mCachedAttributeDescriptors = null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java
deleted file mode 100644
index 349048f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-/**
- * Content Assist Processor for AndroidManifest.xml
- */
-final class ManifestContentAssist extends AndroidContentAssist {
-
-    /**
-     * Constructor for ManifestContentAssist 
-     */
-    public ManifestContentAssist() {
-        super(AndroidTargetData.DESCRIPTOR_MANIFEST);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java
deleted file mode 100644
index f6c7687..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.manifest.pages.ApplicationPage;
-import com.android.ide.eclipse.adt.internal.editors.manifest.pages.InstrumentationPage;
-import com.android.ide.eclipse.adt.internal.editors.manifest.pages.OverviewPage;
-import com.android.ide.eclipse.adt.internal.editors.manifest.pages.PermissionPage;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.sdklib.xml.AndroidXPathFactory;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.FileEditorInput;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.util.List;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Multi-page form editor for AndroidManifest.xml. 
- */
-public final class ManifestEditor extends AndroidEditor {
-
-    public static final String ID = AndroidConstants.EDITORS_NAMESPACE + ".manifest.ManifestEditor"; //$NON-NLS-1$
-    
-    private final static String EMPTY = ""; //$NON-NLS-1$
-    
-    /** Root node of the UI element hierarchy */
-    private UiElementNode mUiManifestNode;
-    /** The Application Page tab */
-    private ApplicationPage mAppPage;
-    /** The Overview Manifest Page tab */
-    private OverviewPage mOverviewPage;
-    /** The Permission Page tab */
-    private PermissionPage mPermissionPage;
-    /** The Instrumentation Page tab */
-    private InstrumentationPage mInstrumentationPage;
-    
-    private IFileListener mMarkerMonitor;
-    
-
-    /**
-     * Creates the form editor for AndroidManifest.xml.
-     */
-    public ManifestEditor() {
-        super();
-    }
-    
-    @Override
-    public void dispose() {
-        super.dispose();
-
-        ResourceMonitor.getMonitor().removeFileListener(mMarkerMonitor);
-    }
-
-    /**
-     * Return the root node of the UI element hierarchy, which here
-     * is the "manifest" node.
-     */
-    @Override
-    public UiElementNode getUiRootNode() {
-        return mUiManifestNode;
-    }
-    
-    /**
-     * Returns the Manifest descriptors for the file being edited.
-     */
-    public AndroidManifestDescriptors getManifestDescriptors() {
-        AndroidTargetData data = getTargetData();
-        if (data != null) {
-            return data.getManifestDescriptors();
-        }
-        
-        return null;
-    }
-    
-    // ---- Base Class Overrides ----
-
-    /**
-     * Returns whether the "save as" operation is supported by this editor.
-     * <p/>
-     * Save-As is a valid operation for the ManifestEditor since it acts on a
-     * single source file. 
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public boolean isSaveAsAllowed() {
-        return true;
-    }
-
-    /**
-     * Creates the various form pages.
-     */
-    @Override
-    protected void createFormPages() {
-        try {
-            addPage(mOverviewPage = new OverviewPage(this));
-            addPage(mAppPage = new ApplicationPage(this));
-            addPage(mPermissionPage = new PermissionPage(this));
-            addPage(mInstrumentationPage = new InstrumentationPage(this));
-        } catch (PartInitException e) {
-            AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$
-        }
-    }
-
-    /* (non-java doc)
-     * Change the tab/title name to include the project name.
-     */
-    @Override
-    protected void setInput(IEditorInput input) {
-        super.setInput(input);
-        IFile inputFile = getInputFile();
-        if (inputFile != null) {
-            startMonitoringMarkers();
-            setPartName(String.format("%1$s Manifest", inputFile.getProject().getName()));
-        }
-    }
-
-    /**
-     * Processes the new XML Model, which XML root node is given.
-     * 
-     * @param xml_doc The XML document, if available, or null if none exists.
-     */
-    @Override
-    protected void xmlModelChanged(Document xml_doc) {
-        // create the ui root node on demand.
-        initUiRootNode(false /*force*/);
-
-        loadFromXml(xml_doc);
-
-        super.xmlModelChanged(xml_doc);
-    }
-    
-    private void loadFromXml(Document xmlDoc) {
-        mUiManifestNode.setXmlDocument(xmlDoc);
-        if (xmlDoc != null) {
-            ElementDescriptor manifest_desc = mUiManifestNode.getDescriptor();
-            try {
-                XPath xpath = AndroidXPathFactory.newXPath();
-                Node node = (Node) xpath.evaluate("/" + manifest_desc.getXmlName(),  //$NON-NLS-1$
-                        xmlDoc,
-                        XPathConstants.NODE);
-                assert node != null && node.getNodeName().equals(manifest_desc.getXmlName());
-
-                // Refresh the manifest UI node and all its descendants 
-                mUiManifestNode.loadFromXmlNode(node);
-            } catch (XPathExpressionException e) {
-                AdtPlugin.log(e, "XPath error when trying to find '%s' element in XML.", //$NON-NLS-1$
-                        manifest_desc.getXmlName());
-            }
-        }
-    }
-
-    private void onDescriptorsChanged(UiElementNode oldManifestNode) {
-        mUiManifestNode.reloadFromXmlNode(oldManifestNode.getXmlNode());
-
-        if (mOverviewPage != null) {
-            mOverviewPage.refreshUiApplicationNode();
-        }
-
-        if (mAppPage != null) {
-            mAppPage.refreshUiApplicationNode();
-        }
-        
-        if (mPermissionPage != null) {
-            mPermissionPage.refreshUiNode();
-        }
-        
-        if (mInstrumentationPage != null) {
-            mInstrumentationPage.refreshUiNode();
-        }
-    }
-
-    /**
-     * Reads and processes the current markers and adds a listener for marker changes. 
-     */
-    private void startMonitoringMarkers() {
-        final IFile inputFile = getInputFile();
-        if (inputFile != null) {
-            updateFromExistingMarkers(inputFile);
-            
-            mMarkerMonitor = new IFileListener() {
-                public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
-                    if (file.equals(inputFile)) {
-                        processMarkerChanges(markerDeltas);
-                    }
-                }
-            };
-            
-            ResourceMonitor.getMonitor().addFileListener(mMarkerMonitor, IResourceDelta.CHANGED);
-        }
-    }
-
-    /**
-     * Processes the markers of the specified {@link IFile} and updates the error status of 
-     * {@link UiElementNode}s and {@link UiAttributeNode}s.
-     * @param inputFile the file being edited.
-     */
-    private void updateFromExistingMarkers(IFile inputFile) {
-        try {
-            // get the markers for the file
-            IMarker[] markers = inputFile.findMarkers(AndroidConstants.MARKER_ANDROID, true,
-                    IResource.DEPTH_ZERO);
-            
-            AndroidManifestDescriptors desc = getManifestDescriptors();
-            if (desc != null) {
-                ElementDescriptor appElement = desc.getApplicationElement();
-                
-                if (appElement != null) {
-                    UiElementNode app_ui_node = mUiManifestNode.findUiChildNode(
-                            appElement.getXmlName());
-                    List<UiElementNode> children = app_ui_node.getUiChildren();
-
-                    for (IMarker marker : markers) {
-                        processMarker(marker, children, IResourceDelta.ADDED);
-                    }
-                }
-            }
-            
-        } catch (CoreException e) {
-            // findMarkers can throw an exception, in which case, we'll do nothing.
-        }
-    }
-    
-    /**
-     * Processes a {@link IMarker} change.
-     * @param markerDeltas the list of {@link IMarkerDelta}
-     */
-    private void processMarkerChanges(IMarkerDelta[] markerDeltas) {
-        AndroidManifestDescriptors descriptors = getManifestDescriptors();
-        if (descriptors != null && descriptors.getApplicationElement() != null) {
-            UiElementNode app_ui_node = mUiManifestNode.findUiChildNode(
-                    descriptors.getApplicationElement().getXmlName());
-            List<UiElementNode> children = app_ui_node.getUiChildren();
-    
-            for (IMarkerDelta markerDelta : markerDeltas) {
-                processMarker(markerDelta.getMarker(), children, markerDelta.getKind());
-            }
-        }
-    }
-
-    /**
-     * Processes a new/old/updated marker.
-     * @param marker The marker being added/removed/changed
-     * @param nodeList the list of activity/service/provider/receiver nodes.
-     * @param kind the change kind. Can be {@link IResourceDelta#ADDED},
-     * {@link IResourceDelta#REMOVED}, or {@link IResourceDelta#CHANGED}
-     */
-    private void processMarker(IMarker marker, List<UiElementNode> nodeList, int kind) {
-        // get the data from the marker
-        String nodeType = marker.getAttribute(AndroidConstants.MARKER_ATTR_TYPE, EMPTY);
-        if (nodeType == EMPTY) {
-            return;
-        }
-        
-        String className = marker.getAttribute(AndroidConstants.MARKER_ATTR_CLASS, EMPTY);
-        if (className == EMPTY) {
-            return;
-        }
-
-        for (UiElementNode ui_node : nodeList) {
-            if (ui_node.getDescriptor().getXmlName().equals(nodeType)) {
-                for (UiAttributeNode attr : ui_node.getUiAttributes()) {
-                    if (attr.getDescriptor().getXmlLocalName().equals(
-                            AndroidManifestDescriptors.ANDROID_NAME_ATTR)) {
-                        if (attr.getCurrentValue().equals(className)) {
-                            if (kind == IResourceDelta.REMOVED) {
-                                attr.setHasError(false);
-                            } else {
-                                attr.setHasError(true);
-                            }
-                            return;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates the initial UI Root Node, including the known mandatory elements.
-     * @param force if true, a new UiManifestNode is recreated even if it already exists.
-     */
-    @Override
-    protected void initUiRootNode(boolean force) {
-        // The manifest UI node is always created, even if there's no corresponding XML node.
-        if (mUiManifestNode != null && force == false) {
-            return;
-        }
-        
-        AndroidManifestDescriptors manifestDescriptor = getManifestDescriptors();
-        
-        if (manifestDescriptor != null) {
-            // save the old manifest node if it exists
-            UiElementNode oldManifestNode = mUiManifestNode;
-
-            ElementDescriptor manifestElement = manifestDescriptor.getManifestElement();   
-            mUiManifestNode = manifestElement.createUiNode();
-            mUiManifestNode.setEditor(this);
-    
-            // Similarly, always create the /manifest/application and /manifest/uses-sdk nodes
-            ElementDescriptor appElement = manifestDescriptor.getApplicationElement();
-            boolean present = false;
-            for (UiElementNode ui_node : mUiManifestNode.getUiChildren()) {
-                if (ui_node.getDescriptor() == appElement) {
-                    present = true;
-                    break;
-                }
-            }
-            if (!present) {
-                mUiManifestNode.appendNewUiChild(appElement);
-            }
-
-            appElement = manifestDescriptor.getUsesSdkElement();
-            present = false;
-            for (UiElementNode ui_node : mUiManifestNode.getUiChildren()) {
-                if (ui_node.getDescriptor() == appElement) {
-                    present = true;
-                    break;
-                }
-            }
-            if (!present) {
-                mUiManifestNode.appendNewUiChild(appElement);
-            }
-
-            if (oldManifestNode != null) {
-                onDescriptorsChanged(oldManifestNode);
-            }
-        } else {
-            // create a dummy descriptor/uinode until we have real descriptors
-            ElementDescriptor desc = new ElementDescriptor("manifest", //$NON-NLS-1$
-                    "temporary descriptors due to missing decriptors", //$NON-NLS-1$
-                    null /*tooltip*/, null /*sdk_url*/, null /*attributes*/,
-                    null /*children*/, false /*mandatory*/);
-            mUiManifestNode = desc.createUiNode();
-            mUiManifestNode.setEditor(this);
-        }
-    }
-    
-    /**
-     * Returns the {@link IFile} being edited, or <code>null</code> if it couldn't be computed.
-     */
-    private IFile getInputFile() {
-        IEditorInput input = getEditorInput();
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput) input;
-            return fileInput.getFile();
-        }
-        
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditorContributor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditorContributor.java
deleted file mode 100644
index 8beca30..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditorContributor.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.ide.IDEActionFactory;
-import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
-import org.eclipse.ui.texteditor.ITextEditor;
-import org.eclipse.ui.texteditor.ITextEditorActionConstants;
-
-/**
- * Manages the installation/deinstallation of global actions for multi-page
- * editors. Responsible for the redirection of global actions to the active
- * editor. Multi-page contributor replaces the contributors for the individual
- * editors in the multi-page editor.
- * 
- * TODO: Doesn't look like we need this. Remove it if not needed.
- * @deprecated
- */
-final class ManifestEditorContributor extends MultiPageEditorActionBarContributor {
-    private IEditorPart mActiveEditorPart;
-
-    /**
-     * Creates a multi-page contributor.
-     * 
-     * Marked as Private so it can't be instanciated. This is a cheap way to make sure
-     * it's not being used. As noted in constructor, should be removed if not used.
-     * @deprecated
-     */
-    private ManifestEditorContributor() {
-        super();
-    }
-
-    /**
-     * Returns the action registed with the given text editor.
-     *
-     * @return IAction or null if editor is null.
-     */
-    protected IAction getAction(ITextEditor editor, String actionID) {
-        return (editor == null ? null : editor.getAction(actionID));
-    }
-
-    /*
-     * (non-JavaDoc) Method declared in
-     * AbstractMultiPageEditorActionBarContributor.
-     */
-
-    @Override
-    public void setActivePage(IEditorPart part) {
-        if (mActiveEditorPart == part)
-            return;
-
-        mActiveEditorPart = part;
-
-        IActionBars actionBars = getActionBars();
-        if (actionBars != null) {
-
-            ITextEditor editor =
-                (part instanceof ITextEditor) ? (ITextEditor)part : null;
-
-            actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),
-                    getAction(editor, ITextEditorActionConstants.DELETE));
-            actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(),
-                    getAction(editor, ITextEditorActionConstants.UNDO));
-            actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(),
-                    getAction(editor, ITextEditorActionConstants.REDO));
-            actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(),
-                    getAction(editor, ITextEditorActionConstants.CUT));
-            actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
-                    getAction(editor, ITextEditorActionConstants.COPY));
-            actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(),
-                    getAction(editor, ITextEditorActionConstants.PASTE));
-            actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
-                    getAction(editor, ITextEditorActionConstants.SELECT_ALL));
-            actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(),
-                    getAction(editor, ITextEditorActionConstants.FIND));
-            actionBars.setGlobalActionHandler(
-                    IDEActionFactory.BOOKMARK.getId(), getAction(editor,
-                            IDEActionFactory.BOOKMARK.getId()));
-            actionBars.updateActionBars();
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestSourceViewerConfig.java
deleted file mode 100644
index 04f75eb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestSourceViewerConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest;
-
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidSourceViewerConfig;
-
-/**
- * Source Viewer Configuration that calls in ManifestContentAssist.
- */
-public final class ManifestSourceViewerConfig extends AndroidSourceViewerConfig {
-
-    public ManifestSourceViewerConfig() {
-        super(new ManifestContentAssist());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java
deleted file mode 100644
index 2667871..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ListAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ReferenceAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.runtime.IStatus;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.Map.Entry;
-
-
-/**
- * Complete description of the AndroidManifest.xml structure.
- * <p/>
- * The root element are static instances which always exists.
- * However their sub-elements and attributes are created only when the SDK changes or is
- * loaded the first time.
- */
-public final class AndroidManifestDescriptors implements IDescriptorProvider {
-
-    private static final String MANIFEST_NODE_NAME = "manifest";                //$NON-NLS-1$
-    private static final String ANDROID_MANIFEST_STYLEABLE = "AndroidManifest"; //$NON-NLS-1$
-
-    // Public attributes names, attributes descriptors and elements descriptors
-    
-    public static final String ANDROID_LABEL_ATTR = "label";    //$NON-NLS-1$
-    public static final String ANDROID_NAME_ATTR  = "name";     //$NON-NLS-1$
-    public static final String PACKAGE_ATTR       = "package";  //$NON-NLS-1$
-
-    /** The {@link ElementDescriptor} for the root Manifest element. */
-    private final ElementDescriptor MANIFEST_ELEMENT;
-    /** The {@link ElementDescriptor} for the root Application element. */
-    private final ElementDescriptor APPLICATION_ELEMENT;
-
-    /** The {@link ElementDescriptor} for the root Instrumentation element. */
-    private final ElementDescriptor INTRUMENTATION_ELEMENT;
-    /** The {@link ElementDescriptor} for the root Permission element. */
-    private final ElementDescriptor PERMISSION_ELEMENT;
-    /** The {@link ElementDescriptor} for the root UsesPermission element. */
-    private final ElementDescriptor USES_PERMISSION_ELEMENT;
-    /** The {@link ElementDescriptor} for the root UsesSdk element. */
-    private final ElementDescriptor USES_SDK_ELEMENT;
-
-    /** The {@link ElementDescriptor} for the root PermissionGroup element. */
-    private final ElementDescriptor PERMISSION_GROUP_ELEMENT;
-    /** The {@link ElementDescriptor} for the root PermissionTree element. */
-    private final ElementDescriptor PERMISSION_TREE_ELEMENT;
-
-    /** Private package attribute for the manifest element. Needs to be handled manually. */
-    private final TextAttributeDescriptor PACKAGE_ATTR_DESC;
-    
-    public AndroidManifestDescriptors() {
-        APPLICATION_ELEMENT = createElement("application", null, true); //$NON-NLS-1$ + no child & mandatory
-        INTRUMENTATION_ELEMENT = createElement("instrumentation"); //$NON-NLS-1$
-
-        PERMISSION_ELEMENT = createElement("permission"); //$NON-NLS-1$
-        USES_PERMISSION_ELEMENT = createElement("uses-permission"); //$NON-NLS-1$
-        USES_SDK_ELEMENT = createElement("uses-sdk", null, true); //$NON-NLS-1$ + no child & mandatory
-
-        PERMISSION_GROUP_ELEMENT = createElement("permission-group"); //$NON-NLS-1$
-        PERMISSION_TREE_ELEMENT = createElement("permission-tree"); //$NON-NLS-1$
-
-        MANIFEST_ELEMENT = createElement(
-                        MANIFEST_NODE_NAME, // xml name
-                        new ElementDescriptor[] {
-                                        APPLICATION_ELEMENT,
-                                        INTRUMENTATION_ELEMENT,
-                                        PERMISSION_ELEMENT,
-                                        USES_PERMISSION_ELEMENT,
-                                        PERMISSION_GROUP_ELEMENT,
-                                        PERMISSION_TREE_ELEMENT,
-                                        USES_SDK_ELEMENT,
-                        },
-                        true /* mandatory */);
-
-        // The "package" attribute is treated differently as it doesn't have the standard
-        // Android XML namespace.
-        PACKAGE_ATTR_DESC = new PackageAttributeDescriptor(PACKAGE_ATTR,
-                "Package",
-                null /* nsUri */,
-                "This attribute gives a unique name for the package, using a Java-style naming convention to avoid name collisions.\nFor example, applications published by Google could have names of the form com.google.app.appname");
-    }
-    
-    public ElementDescriptor[] getRootElementDescriptors() {
-        return new ElementDescriptor[] { MANIFEST_ELEMENT };
-    }
-    
-    public ElementDescriptor getDescriptor() {
-        return getManifestElement();
-    }
-    
-    public ElementDescriptor getApplicationElement() {
-        return APPLICATION_ELEMENT;
-    }
-    
-    public ElementDescriptor getManifestElement() {
-        return MANIFEST_ELEMENT;
-    }
-    
-    public ElementDescriptor getUsesSdkElement() {
-        return USES_SDK_ELEMENT;
-    }
-    
-    public ElementDescriptor getInstrumentationElement() {
-        return INTRUMENTATION_ELEMENT;
-    }
-    
-    public ElementDescriptor getPermissionElement() {
-        return PERMISSION_ELEMENT;
-    }
-    
-    public ElementDescriptor getUsesPermissionElement() {
-        return USES_PERMISSION_ELEMENT;
-    }
-    
-    public ElementDescriptor getPermissionGroupElement() {
-        return PERMISSION_GROUP_ELEMENT;
-    }
-    
-    public ElementDescriptor getPermissionTreeElement() {
-        return PERMISSION_TREE_ELEMENT;
-    }
-
-    /**
-     * Updates the document descriptor.
-     * <p/>
-     * It first computes the new children of the descriptor and then updates them
-     * all at once.
-     * 
-     * @param manifestMap The map style => attributes from the attrs_manifest.xml file
-     */
-    public synchronized void updateDescriptors(
-            Map<String, DeclareStyleableInfo> manifestMap) {
-
-        XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
-                "android", //$NON-NLS-1$
-                SdkConstants.NS_RESOURCES); 
-
-        // -- setup the required attributes overrides --
-        
-        Set<String> required = new HashSet<String>();
-        required.add("provider/authorities");  //$NON-NLS-1$
-        
-        // -- setup the various attribute format overrides --
-        
-        // The key for each override is "element1,element2,.../attr-xml-local-name" or
-        // "*/attr-xml-local-name" to match the attribute in any element.
-        
-        Map<String, Object> overrides = new HashMap<String, Object>();
-
-        overrides.put("*/icon", new DescriptorsUtils.ITextAttributeCreator() { //$NON-NLS-1$
-            public TextAttributeDescriptor create(String xmlName, String uiName, String nsUri,
-                    String tooltip) {
-                return new ReferenceAttributeDescriptor(
-                        ResourceType.DRAWABLE,
-                        xmlName, uiName, nsUri,
-                        tooltip);
-            }
-        });
-        
-        overrides.put("*/theme",         ThemeAttributeDescriptor.class);   //$NON-NLS-1$
-        overrides.put("*/permission",    ListAttributeDescriptor.class);    //$NON-NLS-1$
-        overrides.put("*/targetPackage", ManifestPkgAttrDescriptor.class);  //$NON-NLS-1$
-        
-        overrides.put("uses-library/name", ListAttributeDescriptor.class);       //$NON-NLS-1$
-
-        overrides.put("action,category,uses-permission/" + ANDROID_NAME_ATTR,    //$NON-NLS-1$
-                      ListAttributeDescriptor.class);
-        overrides.put("application/" + ANDROID_NAME_ATTR, ApplicationAttributeDescriptor.class);  //$NON-NLS-1$
-
-        overrideClassName(overrides, "activity", AndroidConstants.CLASS_ACTIVITY);           //$NON-NLS-1$
-        overrideClassName(overrides, "receiver", AndroidConstants.CLASS_BROADCASTRECEIVER);  //$NON-NLS-1$
-        overrideClassName(overrides, "service", AndroidConstants.CLASS_SERVICE);             //$NON-NLS-1$
-        overrideClassName(overrides, "provider", AndroidConstants.CLASS_CONTENTPROVIDER);    //$NON-NLS-1$
-        overrideClassName(overrides, "instrumentation", AndroidConstants.CLASS_INSTRUMENTATION);    //$NON-NLS-1$
-
-        // -- list element nodes already created --
-        // These elements are referenced by already opened editors, so we want to update them
-        // but not re-create them when reloading an SDK on the fly.
-        
-        HashMap<String, ElementDescriptor> elementDescs =
-            new HashMap<String, ElementDescriptor>();
-        elementDescs.put(MANIFEST_ELEMENT.getXmlLocalName(),         MANIFEST_ELEMENT);
-        elementDescs.put(APPLICATION_ELEMENT.getXmlLocalName(),      APPLICATION_ELEMENT);
-        elementDescs.put(INTRUMENTATION_ELEMENT.getXmlLocalName(),   INTRUMENTATION_ELEMENT);
-        elementDescs.put(PERMISSION_ELEMENT.getXmlLocalName(),       PERMISSION_ELEMENT);
-        elementDescs.put(USES_PERMISSION_ELEMENT.getXmlLocalName(),  USES_PERMISSION_ELEMENT);
-        elementDescs.put(USES_SDK_ELEMENT.getXmlLocalName(),         USES_SDK_ELEMENT);
-        elementDescs.put(PERMISSION_GROUP_ELEMENT.getXmlLocalName(), PERMISSION_GROUP_ELEMENT);
-        elementDescs.put(PERMISSION_TREE_ELEMENT.getXmlLocalName(),  PERMISSION_TREE_ELEMENT);
-
-        // --
-
-        inflateElement(manifestMap,
-                overrides,
-                required,
-                elementDescs,
-                MANIFEST_ELEMENT,
-                "AndroidManifest"); //$NON-NLS-1$
-        insertAttribute(MANIFEST_ELEMENT, PACKAGE_ATTR_DESC);
-        
-        sanityCheck(manifestMap, MANIFEST_ELEMENT);
-    }
-    
-    /**
-     * Sets up an attribute override for ANDROID_NAME_ATTR using a ClassAttributeDescriptor
-     * with the specified class name.
-     */
-    private static void overrideClassName(Map<String, Object> overrides,
-            String elementName, final String className) {
-        overrides.put(elementName + "/" + ANDROID_NAME_ATTR,
-                new DescriptorsUtils.ITextAttributeCreator() {
-            public TextAttributeDescriptor create(String xmlName, String uiName, String nsUri,
-                    String tooltip) {
-                uiName += "*";  //$NON-NLS-1$
-                if (AndroidConstants.CLASS_ACTIVITY.equals(className)) {
-                    return new ClassAttributeDescriptor(
-                            className,
-                            PostActivityCreationAction.getAction(),
-                            xmlName,
-                            uiName,
-                            nsUri,
-                            tooltip,
-                            true /*mandatory */,
-                            true /*defaultToProjectOnly*/);
-                } else if (AndroidConstants.CLASS_BROADCASTRECEIVER.equals(className)) {
-                    return new ClassAttributeDescriptor(
-                            className,
-                            PostReceiverCreationAction.getAction(),
-                            xmlName,
-                            uiName,
-                            nsUri,
-                            tooltip,
-                            true /*mandatory */,
-                            true /*defaultToProjectOnly*/);
-                } else if (AndroidConstants.CLASS_INSTRUMENTATION.equals(className)) {
-                    return new ClassAttributeDescriptor(
-                            className,
-                            null, // no post action
-                            xmlName,
-                            uiName,
-                            nsUri,
-                            tooltip,
-                            true /*mandatory */,
-                            false /*defaultToProjectOnly*/);
-                } else {
-                    return new ClassAttributeDescriptor(
-                            className,
-                            xmlName,
-                            uiName,
-                            nsUri,
-                            tooltip,
-                            true /*mandatory */);
-                }
-            }
-        });
-    }
-
-    /**
-     * Returns a new ElementDescriptor constructed from the information given here
-     * and the javadoc & attributes extracted from the style map if any.
-     * <p/>
-     * Creates an element with no attribute overrides.
-     */
-    private ElementDescriptor createElement(
-            String xmlName,
-            ElementDescriptor[] childrenElements,
-            boolean mandatory) {
-        // Creates an element with no attribute overrides.
-        String styleName = guessStyleName(xmlName);
-        String sdkUrl = DescriptorsUtils.MANIFEST_SDK_URL + styleName; 
-        String uiName = getUiName(xmlName);
-
-        ElementDescriptor element = new ManifestElementDescriptor(xmlName, uiName, null, sdkUrl,
-                null, childrenElements, mandatory);
-
-        return element;
-    }
-
-    /**
-     * Returns a new ElementDescriptor constructed from its XML local name.
-     * <p/>
-     * This version creates an element not mandatory.
-     */
-    private ElementDescriptor createElement(String xmlName) {
-        // Creates an element with no child and not mandatory
-        return createElement(xmlName, null, false);
-    }
-
-    /**
-     * Inserts an attribute in this element attribute list if it is not present there yet
-     * (based on the attribute XML name.)
-     * The attribute is inserted at the beginning of the attribute list.
-     */
-    private void insertAttribute(ElementDescriptor element, AttributeDescriptor newAttr) {
-        AttributeDescriptor[] attributes = element.getAttributes();
-        for (AttributeDescriptor attr : attributes) {
-            if (attr.getXmlLocalName().equals(newAttr.getXmlLocalName())) {
-                return;
-            }
-        }
-        
-        AttributeDescriptor[] newArray = new AttributeDescriptor[attributes.length + 1];
-        newArray[0] = newAttr;
-        System.arraycopy(attributes, 0, newArray, 1, attributes.length);
-        element.setAttributes(newArray);
-    }
-
-    /**
-     * "Inflates" the properties of an {@link ElementDescriptor} from the styleable declaration.
-     * <p/>
-     * This first creates all the attributes for the given ElementDescriptor.
-     * It then finds all children of the descriptor, inflate them recursively and set them
-     * as child to this ElementDescriptor.
-     * 
-     * @param styleMap The input styleable map for manifest elements & attributes.
-     * @param overrides A list of attribute overrides (to customize the type of the attribute
-     *          descriptors).
-     * @param requiredAttributes Set of attributes to be marked as required.
-     * @param existingElementDescs A map of already created element descriptors, keyed by
-     *          XML local name. This is used to use the static elements created initially by this
-     *          class, which are referenced directly by editors (so that reloading an SDK won't
-     *          break these references).
-     * @param elemDesc The current {@link ElementDescriptor} to inflate.
-     * @param styleName The name of the {@link ElementDescriptor} to inflate. Its XML local name
-     *          will be guessed automatically from the style name. 
-     */
-    private void inflateElement(
-            Map<String, DeclareStyleableInfo> styleMap,
-            Map<String, Object> overrides,
-            Set<String> requiredAttributes,
-            HashMap<String, ElementDescriptor> existingElementDescs,
-            ElementDescriptor elemDesc,
-            String styleName) {
-        assert elemDesc != null;
-        assert styleName != null;
-        
-        // define attributes
-        DeclareStyleableInfo style = styleMap != null ? styleMap.get(styleName) : null;
-        if (style != null) {
-            ArrayList<AttributeDescriptor> attrDescs = new ArrayList<AttributeDescriptor>();
-            DescriptorsUtils.appendAttributes(attrDescs,
-                    elemDesc.getXmlLocalName(),
-                    SdkConstants.NS_RESOURCES,
-                    style.getAttributes(),
-                    requiredAttributes,
-                    overrides);
-            elemDesc.setTooltip(style.getJavaDoc());
-            elemDesc.setAttributes(attrDescs.toArray(new AttributeDescriptor[attrDescs.size()]));
-        }
-        
-        // find all elements that have this one as parent
-        ArrayList<ElementDescriptor> children = new ArrayList<ElementDescriptor>();
-        for (Entry<String, DeclareStyleableInfo> entry : styleMap.entrySet()) {
-            DeclareStyleableInfo childStyle = entry.getValue();
-            boolean isParent = false;
-            String[] parents = childStyle.getParents();
-            if (parents != null) {
-                for (String parent: parents) {
-                    if (styleName.equals(parent)) {
-                        isParent = true;
-                        break;
-                    }
-                }
-            }
-            if (isParent) {
-                String childStyleName = entry.getKey();
-                String childXmlName = guessXmlName(childStyleName);
-                
-                // create or re-use element
-                ElementDescriptor child = existingElementDescs.get(childXmlName);
-                if (child == null) {
-                    child = createElement(childXmlName);
-                    existingElementDescs.put(childXmlName, child);
-                }
-                children.add(child);
-                
-                inflateElement(styleMap,
-                        overrides,
-                        requiredAttributes,
-                        existingElementDescs,
-                        child,
-                        childStyleName);
-            }
-        }
-        elemDesc.setChildren(children.toArray(new ElementDescriptor[children.size()]));
-    }
-
-    /**
-     * Get an UI name from the element XML name.
-     * <p/>
-     * Capitalizes the first letter and replace non-alphabet by a space followed by a capital.
-     */
-    private String getUiName(String xmlName) {
-        StringBuilder sb = new StringBuilder();
-
-        boolean capitalize = true;
-        for (char c : xmlName.toCharArray()) {
-            if (capitalize && c >= 'a' && c <= 'z') {
-                sb.append((char)(c + 'A' - 'a'));
-                capitalize = false;
-            } else if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
-                sb.append(' ');
-                capitalize = true;
-            } else {
-                sb.append(c);
-            }
-        }
-        
-        return sb.toString();
-    }
-
-    /**
-     * Guesses the style name for a given XML element name.
-     * <p/> 
-     * The rules are:
-     * - capitalize the first letter: 
-     * - if there's a dash, skip it and capitalize the next one
-     * - prefix AndroidManifest
-     * The exception is "manifest" which just becomes AndroidManifest.
-     * <p/>
-     * Examples:
-     * - manifest        => AndroidManifest
-     * - application     => AndroidManifestApplication
-     * - uses-permission => AndroidManifestUsesPermission
-     */
-    private String guessStyleName(String xmlName) {
-        StringBuilder sb = new StringBuilder();
-
-        if (!xmlName.equals(MANIFEST_NODE_NAME)) {
-            boolean capitalize = true;
-            for (char c : xmlName.toCharArray()) {
-                if (capitalize && c >= 'a' && c <= 'z') {
-                    sb.append((char)(c + 'A' - 'a'));
-                    capitalize = false;
-                } else if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
-                    // not a letter -- skip the character and capitalize the next one
-                    capitalize = true;
-                } else {
-                    sb.append(c);
-                }
-            }
-        }
-        
-        sb.insert(0, ANDROID_MANIFEST_STYLEABLE);
-        return sb.toString();
-    }
-
-    /**
-     * This method performs a sanity check to make sure all the styles declared in the
-     * manifestMap are actually defined in the actual element descriptors and reachable from
-     * the manifestElement root node.
-     */
-    private void sanityCheck(Map<String, DeclareStyleableInfo> manifestMap,
-            ElementDescriptor manifestElement) {
-        TreeSet<String> elementsDeclared = new TreeSet<String>();
-        findAllElementNames(manifestElement, elementsDeclared);
-
-        TreeSet<String> stylesDeclared = new TreeSet<String>();
-        for (String styleName : manifestMap.keySet()) {
-            if (styleName.startsWith(ANDROID_MANIFEST_STYLEABLE)) {
-                stylesDeclared.add(styleName);
-            }
-        }
-        
-        for (Iterator<String> it = elementsDeclared.iterator(); it.hasNext();) {
-            String xmlName = it.next();
-            String styleName = guessStyleName(xmlName);
-            if (stylesDeclared.remove(styleName)) {
-                it.remove();
-            }
-        }
-
-        StringBuilder sb = new StringBuilder();
-        if (!stylesDeclared.isEmpty()) {
-            sb.append("Warning, ADT/SDK Mismatch! The following elements are declared by the SDK but unknown to ADT: ");
-            for (String name : stylesDeclared) {
-                name = guessXmlName(name);
-                
-                if (name != stylesDeclared.last()) {
-                    sb.append(", ");    //$NON-NLS-1$
-                }
-            }
-            
-            AdtPlugin.log(IStatus.WARNING, "%s", sb.toString());
-            AdtPlugin.printToConsole((String)null, sb);
-            sb.setLength(0);
-        }
-
-        if (!elementsDeclared.isEmpty()) {
-            sb.append("Warning, ADT/SDK Mismatch! The following elements are declared by ADT but not by the SDK: ");
-            for (String name : elementsDeclared) {
-                sb.append(name);
-                if (name != elementsDeclared.last()) {
-                    sb.append(", ");    //$NON-NLS-1$
-                }
-            }
-
-            AdtPlugin.log(IStatus.WARNING, "%s", sb.toString());
-            AdtPlugin.printToConsole((String)null, sb);
-        }
-    }
-
-    /**
-     * Performs an approximate translation of the style name into a potential
-     * xml name. This is more or less the reverse from guessStyleName().
-     * 
-     * @return The XML local name for a given style name. 
-     */
-    private String guessXmlName(String name) {
-        StringBuilder sb = new StringBuilder();
-        if (ANDROID_MANIFEST_STYLEABLE.equals(name)) {
-            sb.append(MANIFEST_NODE_NAME);
-        } else {
-            name = name.replace(ANDROID_MANIFEST_STYLEABLE, "");    //$NON-NLS-1$
-            boolean first_char = true;
-            for (char c : name.toCharArray()) {
-                if (c >= 'A' && c <= 'Z') {
-                    if (!first_char) {
-                        sb.append('-');
-                    }
-                    c = (char) (c - 'A' + 'a');
-                }
-                sb.append(c);
-                first_char = false;
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Helper method used by {@link #sanityCheck(Map, ElementDescriptor)} to find all the
-     * {@link ElementDescriptor} names defined by the tree of descriptors.
-     * <p/>
-     * Note: this assumes no circular reference in the tree of {@link ElementDescriptor}s.
-     */
-    private void findAllElementNames(ElementDescriptor element, TreeSet<String> declared) {
-        declared.add(element.getXmlName());
-        for (ElementDescriptor desc : element.getChildren()) {
-            findAllElementNames(desc, declared);
-        }
-    }
-
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ApplicationAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ApplicationAttributeDescriptor.java
deleted file mode 100644
index 5dfc684..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ApplicationAttributeDescriptor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * Describes an 'Application' class XML attribute. It is displayed by a
- * {@link UiClassAttributeNode}, that restricts creation and selection to classes
- * inheriting from android.app.Application.
- */
-public class ApplicationAttributeDescriptor extends TextAttributeDescriptor {
-
-    public ApplicationAttributeDescriptor(String xmlLocalName, String uiName,
-            String nsUri, String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-    
-    /**
-     * @return A new {@link UiClassAttributeNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiClassAttributeNode("android.app.Application", //$NON-NLS-1$
-                null /* postCreationAction */, false /* mandatory */, this, uiParent,
-                true /*defaultToProjectOnly*/);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ClassAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ClassAttributeDescriptor.java
deleted file mode 100644
index 1137dcf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ClassAttributeDescriptor.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.sdklib.SdkConstants;
-
-/**
- * Describes an XML attribute representing a class name.
- * It is displayed by a {@link UiClassAttributeNode}.
- */
-public class ClassAttributeDescriptor extends TextAttributeDescriptor {
-
-    /** Superclass of the class value. */
-    private String mSuperClassName;
-    
-    private IPostTypeCreationAction mPostCreationAction;
-    
-    /** indicates if the class parameter is mandatory */
-    boolean mMandatory;
-
-    private final boolean mDefaultToProjectOnly;
-    
-    /**
-     * Creates a new {@link ClassAttributeDescriptor}
-     * @param superClassName the fully qualified name of the superclass of the class represented
-     * by the attribute.
-     * @param xmlLocalName The XML name of the attribute (case sensitive, with android: prefix).
-     * @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param tooltip A non-empty tooltip string or null.
-     * @param mandatory indicates if the class attribute is mandatory.
-     */
-    public ClassAttributeDescriptor(String superClassName,
-            String xmlLocalName,
-            String uiName,
-            String nsUri,
-            String tooltip,
-            boolean mandatory) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-        mSuperClassName = superClassName;
-        mDefaultToProjectOnly = true;
-    }
-
-    /**
-     * Creates a new {@link ClassAttributeDescriptor}
-     * @param superClassName the fully qualified name of the superclass of the class represented
-     * by the attribute.
-     * @param postCreationAction the {@link IPostTypeCreationAction} to be executed on the
-     *        newly created class.
-     * @param xmlLocalName The XML local name of the attribute (case sensitive).
-     * @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
-     * @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
-     *              See {@link SdkConstants#NS_RESOURCES} for a common value.
-     * @param tooltip A non-empty tooltip string or null.
-     * @param mandatory indicates if the class attribute is mandatory.
-     * @param defaultToProjectOnly True if only classes from the sources of this project should
-     *         be shown by default in the class browser.
-     */
-    public ClassAttributeDescriptor(String superClassName,
-            IPostTypeCreationAction postCreationAction,
-            String xmlLocalName,
-            String uiName,
-            String nsUri,
-            String tooltip,
-            boolean mandatory,
-            boolean defaultToProjectOnly) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-        mSuperClassName = superClassName;
-        mPostCreationAction = postCreationAction;
-        mDefaultToProjectOnly = defaultToProjectOnly;
-    }
-
-    /**
-     * @return A new {@link UiClassAttributeNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiClassAttributeNode(mSuperClassName, mPostCreationAction,
-                mMandatory, this, uiParent, mDefaultToProjectOnly);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestElementDescriptor.java
deleted file mode 100644
index 7c02850..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestElementDescriptor.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiManifestElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * {@link ManifestElementDescriptor} describes an XML element node, with its
- * element name, its possible attributes, its possible child elements but also
- * its display name and tooltip.
- * 
- * This {@link ElementDescriptor} is specialized to create {@link UiManifestElementNode} UI nodes.
- */
-public class ManifestElementDescriptor extends ElementDescriptor {
-
-    /**
-     * Constructs a new {@link ManifestElementDescriptor}.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param ui_name The XML element name for the user interface, typically capitalized.
-     * @param tooltip An optional tooltip. Can be null or empty.
-     * @param sdk_url An optional SKD URL. Can be null or empty.
-     * @param attributes The list of allowed attributes. Can be null or empty.
-     * @param children The list of allowed children. Can be null or empty.
-     * @param mandatory Whether this node must always exist (even for empty models).
-     */
-    public ManifestElementDescriptor(String xml_name, String ui_name, String tooltip, String sdk_url,
-            AttributeDescriptor[] attributes,
-            ElementDescriptor[] children,
-            boolean mandatory) {
-        super(xml_name, ui_name, tooltip, sdk_url, attributes, children, mandatory);
-    }
-
-    /**
-     * Constructs a new {@link ManifestElementDescriptor}.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param ui_name The XML element name for the user interface, typically capitalized.
-     * @param tooltip An optional tooltip. Can be null or empty.
-     * @param sdk_url An optional SKD URL. Can be null or empty.
-     * @param attributes The list of allowed attributes. Can be null or empty.
-     * @param children The list of allowed children. Can be null or empty.
-     */
-    public ManifestElementDescriptor(String xml_name, String ui_name, String tooltip, String sdk_url,
-            AttributeDescriptor[] attributes,
-            ElementDescriptor[] children) {
-        super(xml_name, ui_name, tooltip, sdk_url, attributes, children, false);
-    }
-
-    /**
-     * This is a shortcut for
-     * ManifestElementDescriptor(xml_name, xml_name.capitalize(), null, null, null, children).
-     * This constructor is mostly used for unit tests.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     */
-    public ManifestElementDescriptor(String xml_name, ElementDescriptor[] children) {
-        super(xml_name, children);
-    }
-
-    /**
-     * This is a shortcut for
-     * ManifestElementDescriptor(xml_name, xml_name.capitalize(), null, null, null, null).
-     * This constructor is mostly used for unit tests.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     */
-    public ManifestElementDescriptor(String xml_name) {
-        super(xml_name, null);
-    }
-
-    /**
-     * @return A new {@link UiElementNode} linked to this descriptor.
-     */
-    @Override
-    public UiElementNode createUiNode() {
-        return new UiManifestElementNode(this);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestPkgAttrDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestPkgAttrDescriptor.java
deleted file mode 100755
index 2ed86bb1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestPkgAttrDescriptor.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiManifestPkgAttrNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * Describes a package XML attribute. It is displayed by a {@link UiManifestPkgAttrNode}.
- */
-public class ManifestPkgAttrDescriptor extends TextAttributeDescriptor {
-
-    public ManifestPkgAttrDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-    
-    /**
-     * @return A new {@link UiManifestPkgAttrNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiManifestPkgAttrNode(this, uiParent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PackageAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PackageAttributeDescriptor.java
deleted file mode 100644
index 2de32e5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PackageAttributeDescriptor.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiPackageAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * Describes a package XML attribute. It is displayed by a {@link UiPackageAttributeNode}.
- */
-public class PackageAttributeDescriptor extends TextAttributeDescriptor {
-
-    public PackageAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-    
-    /**
-     * @return A new {@link UiPackageAttributeNode} linked to this descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiPackageAttributeNode(this, uiParent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java
deleted file mode 100644
index e10e0e7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction;
-
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-
-/**
- * Action to be executed after an Activity class is created.
- */
-class PostActivityCreationAction implements IPostTypeCreationAction {
-    
-    private final static PostActivityCreationAction sAction = new PostActivityCreationAction();
-    
-    private PostActivityCreationAction() {
-        // private constructor to enforce singleton.
-    }
-    
-    
-    /**
-     * Returns the action.
-     */
-    public static IPostTypeCreationAction getAction() {
-        return sAction;
-    }
-
-    /**
-     * Processes a newly created Activity.
-     * 
-     */
-    public void processNewType(IType newType) {
-        try {
-            String methodContent = 
-                "    /** Called when the activity is first created. */\n" +
-                "    @Override\n" +
-                "    public void onCreate(Bundle savedInstanceState) {\n" +
-                "        super.onCreate(savedInstanceState);\n" +
-                "\n" +
-                "        // TODO Auto-generated method stub\n" +
-                "    }";
-            newType.createMethod(methodContent, null /* sibling*/, false /* force */,
-                    new NullProgressMonitor());
-
-            // we need to add the import for Bundle, so we need the compilation unit.
-            // Since the type could be enclosed in other types, we loop till we find it.
-            ICompilationUnit compilationUnit = null;
-            IJavaElement element = newType;
-            do {
-                IJavaElement parentElement = element.getParent();
-                if (parentElement !=  null) {
-                    if (parentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
-                        compilationUnit = (ICompilationUnit)parentElement;
-                    }
-                    
-                    element = parentElement;
-                } else {
-                    break;
-                }
-            } while (compilationUnit == null);
-            
-            if (compilationUnit != null) {
-                compilationUnit.createImport(AndroidConstants.CLASS_BUNDLE,
-                        null /* sibling */, new NullProgressMonitor());
-            }
-        } catch (JavaModelException e) {
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java
deleted file mode 100644
index d16a7d6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction;
-
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-
-/**
- * Action to be executed after an BroadcastReceiver class is created.
- */
-class PostReceiverCreationAction implements IPostTypeCreationAction {
-    
-    private final static PostReceiverCreationAction sAction = new PostReceiverCreationAction();
-    
-    private PostReceiverCreationAction() {
-        // private constructor to enforce singleton.
-    }
-    
-    /**
-     * Returns the action.
-     */
-    public static IPostTypeCreationAction getAction() {
-        return sAction;
-    }
-
-    /**
-     * Processes a newly created Activity.
-     * 
-     */
-    public void processNewType(IType newType) {
-        try {
-            String methodContent = 
-                "    @Override\n" +
-                "    public void onReceive(Context context, Intent intent) {\n" +
-                "        // TODO Auto-generated method stub\n" +
-                "    }";
-            newType.createMethod(methodContent, null /* sibling*/, false /* force */,
-                    new NullProgressMonitor());
-
-            // we need to add the import for Bundle, so we need the compilation unit.
-            // Since the type could be enclosed in other types, we loop till we find it.
-            ICompilationUnit compilationUnit = null;
-            IJavaElement element = newType;
-            do {
-                IJavaElement parentElement = element.getParent();
-                if (parentElement !=  null) {
-                    if (parentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
-                        compilationUnit = (ICompilationUnit)parentElement;
-                    }
-                    
-                    element = parentElement;
-                } else {
-                    break;
-                }
-            } while (compilationUnit == null);
-            
-            if (compilationUnit != null) {
-                compilationUnit.createImport(AndroidConstants.CLASS_CONTEXT,
-                        null /* sibling */, new NullProgressMonitor());
-                compilationUnit.createImport(AndroidConstants.CLASS_INTENT,
-                        null /* sibling */, new NullProgressMonitor());
-            }
-        } catch (JavaModelException e) {
-            // looks like the class already existed (this happens when the user check to create
-            // inherited abstract methods).
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ThemeAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ThemeAttributeDescriptor.java
deleted file mode 100644
index 4241f14..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ThemeAttributeDescriptor.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-
-/**
- * Describes a Theme/Style XML attribute displayed by a {@link UiResourceAttributeNode}
- */
-public final class ThemeAttributeDescriptor extends TextAttributeDescriptor {
-
-    public ThemeAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
-            String tooltip) {
-        super(xmlLocalName, uiName, nsUri, tooltip);
-    }
-    
-    /**
-     * @return A new {@link UiResourceAttributeNode} linked to this theme descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiResourceAttributeNode(ResourceType.STYLE, this, uiParent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java
deleted file mode 100644
index d5abc09..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.model;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.sdklib.xml.AndroidManifest;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.Flags;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.search.IJavaSearchScope;
-import org.eclipse.jdt.core.search.SearchEngine;
-import org.eclipse.jdt.ui.IJavaElementSearchConstants;
-import org.eclipse.jdt.ui.JavaUI;
-import org.eclipse.jdt.ui.actions.OpenNewClassWizardAction;
-import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension;
-import org.eclipse.jdt.ui.dialogs.ITypeInfoRequestor;
-import org.eclipse.jdt.ui.dialogs.ITypeSelectionComponent;
-import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension;
-import org.eclipse.jdt.ui.wizards.NewClassWizardPage;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.SelectionDialog;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.w3c.dom.Element;
-
-import java.util.ArrayList;
-
-/**
- * Represents an XML attribute for a class, that can be modified using a simple text field or
- * a dialog to choose an existing class. Also, there's a link to create a new class.
- * <p/>
- * See {@link UiTextAttributeNode} for more information.
- */
-public class UiClassAttributeNode extends UiTextAttributeNode {
-
-    private String mReferenceClass;
-    private IPostTypeCreationAction mPostCreationAction;
-    private boolean mMandatory;
-    private final boolean mDefaultToProjectOnly;
-
-    private class HierarchyTypeSelection extends TypeSelectionExtension {
-
-        private IJavaProject mJavaProject;
-        private IType mReferenceType;
-        private Button mProjectOnly;
-        private boolean mUseProjectOnly;
-
-        public HierarchyTypeSelection(IProject project, String referenceClass)
-                throws JavaModelException {
-            mJavaProject = JavaCore.create(project);
-            mReferenceType = mJavaProject.findType(referenceClass);
-        }
-
-        @Override
-        public ITypeInfoFilterExtension getFilterExtension() {
-            return new ITypeInfoFilterExtension() {
-                public boolean select(ITypeInfoRequestor typeInfoRequestor) {
-
-                    boolean projectOnly = mUseProjectOnly;
-
-                    String packageName = typeInfoRequestor.getPackageName();
-                    String typeName = typeInfoRequestor.getTypeName();
-                    String enclosingType = typeInfoRequestor.getEnclosingName();
-
-                    // build the full class name.
-                    StringBuilder sb = new StringBuilder(packageName);
-                    sb.append('.');
-                    if (enclosingType.length() > 0) {
-                        sb.append(enclosingType);
-                        sb.append('.');
-                    }
-                    sb.append(typeName);
-
-                    String className = sb.toString();
-
-                    try {
-                        IType type = mJavaProject.findType(className);
-
-                        if (type == null) {
-                            return false;
-                        }
-
-                        // don't display abstract classes
-                        if ((type.getFlags() & Flags.AccAbstract) != 0) {
-                            return false;
-                        }
-
-                        // if project-only is selected, make sure the package fragment is
-                        // an actual source (thus "from this project").
-                        if (projectOnly) {
-                            IPackageFragment frag = type.getPackageFragment();
-                            if (frag == null || frag.getKind() != IPackageFragmentRoot.K_SOURCE) {
-                                return false;
-                            }
-                        }
-
-                        // get the type hierarchy and reference type is one of the super classes.
-                        ITypeHierarchy hierarchy = type.newSupertypeHierarchy(
-                                new NullProgressMonitor());
-
-                        IType[] supertypes = hierarchy.getAllSupertypes(type);
-                        int n = supertypes.length;
-                        for (int i = 0; i < n; i++) {
-                            IType st = supertypes[i];
-                            if (mReferenceType.equals(st)) {
-                                return true;
-                            }
-                        }
-                    } catch (JavaModelException e) {
-                    }
-
-                    return false;
-                }
-            };
-        }
-
-        @Override
-        public Control createContentArea(Composite parent) {
-
-            mProjectOnly = new Button(parent, SWT.CHECK);
-            mProjectOnly.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mProjectOnly.setText(String.format("Display classes from sources of project '%s' only",
-                    mJavaProject.getProject().getName()));
-
-            mUseProjectOnly = mDefaultToProjectOnly;
-            mProjectOnly.setSelection(mUseProjectOnly);
-
-            mProjectOnly.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    super.widgetSelected(e);
-                    mUseProjectOnly = mProjectOnly.getSelection();
-                    getTypeSelectionComponent().triggerSearch();
-                }
-            });
-
-            return super.createContentArea(parent);
-        }
-    }
-
-    /**
-     * Classes which implement this interface provide a method processing newly created classes.
-     */
-    public static interface IPostTypeCreationAction {
-        /**
-         * Sent to process a newly created class.
-         * @param newType the IType representing the newly created class.
-         */
-        public void processNewType(IType newType);
-    }
-
-    /**
-     * Creates a {@link UiClassAttributeNode} object that will display ui to select or create
-     * classes.
-     * @param referenceClass The allowed supertype of the classes that are to be selected
-     * or created. Can be null.
-     * @param postCreationAction a {@link IPostTypeCreationAction} object handling post creation
-     * modification of the class.
-     * @param mandatory indicates if the class value is mandatory
-     * @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node.
-     * @param defaultToProjectOnly When true display classes of this project only by default.
-     *         When false any class path will be considered. The user can always toggle this.
-     */
-    public UiClassAttributeNode(String referenceClass, IPostTypeCreationAction postCreationAction,
-            boolean mandatory, AttributeDescriptor attributeDescriptor, UiElementNode uiParent,
-            boolean defaultToProjectOnly) {
-        super(attributeDescriptor, uiParent);
-
-        mReferenceClass = referenceClass;
-        mPostCreationAction = postCreationAction;
-        mMandatory = mandatory;
-        mDefaultToProjectOnly = defaultToProjectOnly;
-    }
-
-    /* (non-java doc)
-     * Creates a label widget and an associated text field.
-     * <p/>
-     * As most other parts of the android manifest editor, this assumes the
-     * parent uses a table layout with 2 columns.
-     */
-    @Override
-    public void createUiControl(final Composite parent, IManagedForm managedForm) {
-        setManagedForm(managedForm);
-        FormToolkit toolkit = managedForm.getToolkit();
-        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-
-        StringBuilder label = new StringBuilder();
-        label.append("<form><p><a href='unused'>");
-        label.append(desc.getUiName());
-        label.append("</a></p></form>");
-        FormText formText = SectionHelper.createFormText(parent, toolkit, true /* isHtml */,
-                label.toString(), true /* setupLayoutData */);
-        formText.addHyperlinkListener(new HyperlinkAdapter() {
-            @Override
-            public void linkActivated(HyperlinkEvent e) {
-                super.linkActivated(e);
-                handleLabelClick();
-            }
-        });
-        formText.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
-        SectionHelper.addControlTooltip(formText, desc.getTooltip());
-
-        Composite composite = toolkit.createComposite(parent);
-        composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
-        GridLayout gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        composite.setLayout(gl);
-        // Fixes missing text borders under GTK... also requires adding a 1-pixel margin
-        // for the text field below
-        toolkit.paintBordersFor(composite);
-
-        final Text text = toolkit.createText(composite, getCurrentValue());
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalIndent = 1;  // Needed by the fixed composite borders under GTK
-        text.setLayoutData(gd);
-        Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
-
-        setTextWidget(text);
-
-        browseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                handleBrowseClick();
-            }
-        });
-    }
-
-    /* (non-java doc)
-     *
-     * Add a modify listener that will check the validity of the class
-     */
-    @Override
-    protected void onAddValidators(final Text text) {
-        ModifyListener listener = new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                try {
-                    String textValue = text.getText().trim();
-                    if (textValue.length() == 0) {
-                        if (mMandatory) {
-                            setErrorMessage("Value is mandatory", text);
-                        } else {
-                            setErrorMessage(null, text);
-                        }
-                        return;
-                    }
-                    // first we need the current java package.
-                    String javaPackage = getManifestPackage();
-
-                    // build the fully qualified name of the class
-                    String className = AndroidManifest.combinePackageAndClassName(
-                            javaPackage, textValue);
-
-                    // only test the vilibility for activities.
-                    boolean testVisibility = AndroidConstants.CLASS_ACTIVITY.equals(
-                            mReferenceClass);
-
-                    // test the class
-                    setErrorMessage(BaseProjectHelper.testClassForManifest(
-                            BaseProjectHelper.getJavaProject(getProject()), className,
-                            mReferenceClass, testVisibility), text);
-                } catch (CoreException ce) {
-                    setErrorMessage(ce.getMessage(), text);
-                }
-            }
-        };
-
-        text.addModifyListener(listener);
-
-        // Make sure the validator removes its message(s) when the widget is disposed
-        text.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                // we don't want to use setErrorMessage, because we don't want to reset
-                // the error flag in the UiAttributeNode
-                getManagedForm().getMessageManager().removeMessage(text, text);
-            }
-        });
-
-        // Finally call the validator once to make sure the initial value is processed
-        listener.modifyText(null);
-    }
-
-    private void handleBrowseClick() {
-        Text text = getTextWidget();
-
-        // we need to get the project of the manifest.
-        IProject project = getProject();
-        if (project != null) {
-
-            // Create a search scope including only the source folder of the current
-            // project.
-            IPackageFragmentRoot[] packageFragmentRoots = getPackageFragmentRoots(project,
-                    true /*include_containers*/);
-            IJavaSearchScope scope = SearchEngine.createJavaSearchScope(
-                    packageFragmentRoots,
-                    false);
-
-            try {
-                SelectionDialog dlg = JavaUI.createTypeDialog(text.getShell(),
-                    PlatformUI.getWorkbench().getProgressService(),
-                    scope,
-                    IJavaElementSearchConstants.CONSIDER_CLASSES,  // style
-                    false, // no multiple selection
-                    "**",  //$NON-NLS-1$ //filter
-                    new HierarchyTypeSelection(project, mReferenceClass));
-                dlg.setMessage(String.format("Select class name for element %1$s:",
-                        getUiParent().getBreadcrumbTrailDescription(false /* include_root */)));
-                if (dlg instanceof ITypeSelectionComponent) {
-                    ((ITypeSelectionComponent)dlg).triggerSearch();
-                }
-
-                if (dlg.open() == Window.OK) {
-                    Object[] results = dlg.getResult();
-                    if (results.length == 1) {
-                        handleNewType((IType)results[0]);
-                    }
-                }
-            } catch (JavaModelException e1) {
-                AdtPlugin.log(e1, "UiClassAttributeNode HandleBrowser failed");
-            }
-        }
-    }
-
-    private void handleLabelClick() {
-        // get the current value
-        String className = getTextWidget().getText().trim();
-
-        // get the package name from the manifest.
-        String packageName = getManifestPackage();
-
-        if (className.length() == 0) {
-            createNewClass(packageName, null /* className */);
-        } else {
-            // build back the fully qualified class name.
-            String fullClassName = className;
-            if (className.startsWith(".")) { //$NON-NLS-1$
-                fullClassName = packageName + className;
-            } else {
-                String[] segments = className.split(AndroidConstants.RE_DOT);
-                if (segments.length == 1) {
-                    fullClassName = packageName + "." + className; //$NON-NLS-1$
-                }
-            }
-
-            // in case the type is enclosed, we need to replace the $ with .
-            fullClassName = fullClassName.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS2$
-
-            // now we try to find the file that contains this class and we open it in the editor.
-            IProject project = getProject();
-            IJavaProject javaProject = JavaCore.create(project);
-
-            try {
-                IType result = javaProject.findType(fullClassName);
-                if (result != null) {
-                    JavaUI.openInEditor(result);
-                } else {
-                    // split the last segment from the fullClassname
-                    int index = fullClassName.lastIndexOf('.');
-                    if (index != -1) {
-                        createNewClass(fullClassName.substring(0, index),
-                                fullClassName.substring(index+1));
-                    } else {
-                        createNewClass(packageName, className);
-                    }
-                }
-            } catch (JavaModelException e) {
-                AdtPlugin.log(e, "UiClassAttributeNode HandleLabel failed");
-            } catch (PartInitException e) {
-                AdtPlugin.log(e, "UiClassAttributeNode HandleLabel failed");
-            }
-        }
-    }
-
-    private IProject getProject() {
-        UiElementNode uiNode = getUiParent();
-        AndroidEditor editor = uiNode.getEditor();
-        IEditorInput input = editor.getEditorInput();
-        if (input instanceof IFileEditorInput) {
-            // from the file editor we can get the IFile object, and from it, the IProject.
-            IFile file = ((IFileEditorInput)input).getFile();
-            return file.getProject();
-        }
-
-        return null;
-    }
-
-
-    /**
-     * Returns the current value of the /manifest/package attribute.
-     * @return the package or an empty string if not found
-     */
-    private String getManifestPackage() {
-        // get the root uiNode to get the 'package' attribute value.
-        UiElementNode rootNode = getUiParent().getUiRoot();
-
-        Element xmlElement = (Element) rootNode.getXmlNode();
-
-        if (xmlElement != null) {
-            return xmlElement.getAttribute(AndroidManifestDescriptors.PACKAGE_ATTR);
-        }
-        return ""; //$NON-NLS-1$
-    }
-
-
-    /**
-     * Computes and return the {@link IPackageFragmentRoot}s corresponding to the source folders of
-     * the specified project.
-     * @param project the project
-     * @param include_containers True to include containers
-     * @return an array of IPackageFragmentRoot.
-     */
-    private IPackageFragmentRoot[] getPackageFragmentRoots(IProject project,
-            boolean include_containers) {
-        ArrayList<IPackageFragmentRoot> result = new ArrayList<IPackageFragmentRoot>();
-        try {
-            IJavaProject javaProject = JavaCore.create(project);
-            IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
-            for (int i = 0; i < roots.length; i++) {
-                IClasspathEntry entry = roots[i].getRawClasspathEntry();
-                if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE ||
-                        (include_containers &&
-                                entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER)) {
-                    result.add(roots[i]);
-                }
-            }
-        } catch (JavaModelException e) {
-        }
-
-        return result.toArray(new IPackageFragmentRoot[result.size()]);
-    }
-
-    private void handleNewType(IType type) {
-        Text text = getTextWidget();
-
-        // get the fully qualified name with $ to properly detect the enclosing types.
-        String name = type.getFullyQualifiedName('$');
-
-        String packageValue = getManifestPackage();
-
-        // check if the class doesn't start with the package.
-        if (packageValue.length() > 0 && name.startsWith(packageValue)) {
-            // if it does, we remove the package and the first dot.
-            name = name.substring(packageValue.length() + 1);
-
-            // look for how many segments we have left.
-            // if one, just write it that way.
-            // if more than one, write it with a leading dot.
-            String[] packages = name.split(AndroidConstants.RE_DOT);
-            if (packages.length == 1) {
-                text.setText(name);
-            } else {
-                text.setText("." + name); //$NON-NLS-1$
-            }
-        } else {
-            text.setText(name);
-        }
-    }
-
-    private void createNewClass(String packageName, String className) {
-        // create the wizard page for the class creation, and configure it
-        NewClassWizardPage page = new NewClassWizardPage();
-
-        // set the parent class
-        page.setSuperClass(mReferenceClass, true /* canBeModified */);
-
-        // get the source folders as java elements.
-        IPackageFragmentRoot[] roots = getPackageFragmentRoots(getProject(),
-                true /*include_containers*/);
-
-        IPackageFragmentRoot currentRoot = null;
-        IPackageFragment currentFragment = null;
-        int packageMatchCount = -1;
-
-        for (IPackageFragmentRoot root : roots) {
-            // Get the java element for the package.
-            // This method is said to always return a IPackageFragment even if the
-            // underlying folder doesn't exist...
-            IPackageFragment fragment = root.getPackageFragment(packageName);
-            if (fragment != null && fragment.exists()) {
-                // we have a perfect match! we use it.
-                currentRoot = root;
-                currentFragment = fragment;
-                packageMatchCount = -1;
-                break;
-            } else {
-                // we don't have a match. we look for the fragment with the best match
-                // (ie the closest parent package we can find)
-                try {
-                    IJavaElement[] children;
-                    children = root.getChildren();
-                    for (IJavaElement child : children) {
-                        if (child instanceof IPackageFragment) {
-                            fragment = (IPackageFragment)child;
-                            if (packageName.startsWith(fragment.getElementName())) {
-                                // its a match. get the number of segments
-                                String[] segments = fragment.getElementName().split("\\."); //$NON-NLS-1$
-                                if (segments.length > packageMatchCount) {
-                                    packageMatchCount = segments.length;
-                                    currentFragment = fragment;
-                                    currentRoot = root;
-                                }
-                            }
-                        }
-                    }
-                } catch (JavaModelException e) {
-                    // Couldn't get the children: we just ignore this package root.
-                }
-            }
-        }
-
-        ArrayList<IPackageFragment> createdFragments = null;
-
-        if (currentRoot != null) {
-            // if we have a perfect match, we set it and we're done.
-            if (packageMatchCount == -1) {
-                page.setPackageFragmentRoot(currentRoot, true /* canBeModified*/);
-                page.setPackageFragment(currentFragment, true /* canBeModified */);
-            } else {
-                // we have a partial match.
-                // create the package. We have to start with the first segment so that we
-                // know what to delete in case of a cancel.
-                try {
-                    createdFragments = new ArrayList<IPackageFragment>();
-
-                    int totalCount = packageName.split("\\.").length; //$NON-NLS-1$
-                    int count = 0;
-                    int index = -1;
-                    // skip the matching packages
-                    while (count < packageMatchCount) {
-                        index = packageName.indexOf('.', index+1);
-                        count++;
-                    }
-
-                    // create the rest of the segments, except for the last one as indexOf will
-                    // return -1;
-                    while (count < totalCount - 1) {
-                        index = packageName.indexOf('.', index+1);
-                        count++;
-                        createdFragments.add(currentRoot.createPackageFragment(
-                                packageName.substring(0, index),
-                                true /* force*/, new NullProgressMonitor()));
-                    }
-
-                    // create the last package
-                    createdFragments.add(currentRoot.createPackageFragment(
-                            packageName, true /* force*/, new NullProgressMonitor()));
-
-                    // set the root and fragment in the Wizard page
-                    page.setPackageFragmentRoot(currentRoot, true /* canBeModified*/);
-                    page.setPackageFragment(createdFragments.get(createdFragments.size()-1),
-                            true /* canBeModified */);
-                } catch (JavaModelException e) {
-                    // if we can't create the packages, there's a problem. we revert to the default
-                    // package
-                    for (IPackageFragmentRoot root : roots) {
-                        // Get the java element for the package.
-                        // This method is said to always return a IPackageFragment even if the
-                        // underlying folder doesn't exist...
-                        IPackageFragment fragment = root.getPackageFragment(packageName);
-                        if (fragment != null && fragment.exists()) {
-                            page.setPackageFragmentRoot(root, true /* canBeModified*/);
-                            page.setPackageFragment(fragment, true /* canBeModified */);
-                            break;
-                        }
-                    }
-                }
-            }
-        } else if (roots.length > 0) {
-            // if we haven't found a valid fragment, we set the root to the first source folder.
-            page.setPackageFragmentRoot(roots[0], true /* canBeModified*/);
-        }
-
-        // if we have a starting class name we use it
-        if (className != null) {
-            page.setTypeName(className, true /* canBeModified*/);
-        }
-
-        // create the action that will open it the wizard.
-        OpenNewClassWizardAction action = new OpenNewClassWizardAction();
-        action.setConfiguredWizardPage(page);
-        action.run();
-        IJavaElement element = action.getCreatedElement();
-
-        if (element != null) {
-            if (element.getElementType() == IJavaElement.TYPE) {
-
-                IType type = (IType)element;
-
-                if (mPostCreationAction != null) {
-                    mPostCreationAction.processNewType(type);
-                }
-
-                handleNewType(type);
-            }
-        } else {
-            // lets delete the packages we created just for this.
-            // we need to start with the leaf and go up
-            if (createdFragments != null) {
-                try {
-                    for (int i = createdFragments.size() - 1 ; i >= 0 ; i--) {
-                        createdFragments.get(i).delete(true /* force*/, new NullProgressMonitor());
-                    }
-                } catch (JavaModelException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    /**
-     * Sets the error messages. If message is <code>null</code>, the message is removed.
-     * @param message the message to set, or <code>null</code> to remove the current message
-     * @param textWidget the {@link Text} widget associated to the message.
-     */
-    private final void setErrorMessage(String message, Text textWidget) {
-        if (message != null) {
-            setHasError(true);
-            getManagedForm().getMessageManager().addMessage(textWidget, message, null /* data */,
-                    IMessageProvider.ERROR, textWidget);
-        } else {
-            setHasError(false);
-            getManagedForm().getMessageManager().removeMessage(textWidget, textWidget);
-        }
-    }
-
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        // TODO: compute a list of existing classes for content assist completion
-        return null;
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestElementNode.java
deleted file mode 100644
index 5dc8544..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestElementNode.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.model;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.ManifestElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.sdklib.SdkConstants;
-
-import org.w3c.dom.Element;
-
-/**
- * Represents an XML node that can be modified by the user interface in the XML editor.
- * <p/>
- * Each tree viewer used in the application page's parts needs to keep a model representing
- * each underlying node in the tree. This interface represents the base type for such a node.
- * <p/>
- * Each node acts as an intermediary model between the actual XML model (the real data support)
- * and the tree viewers or the corresponding page parts.
- * <p/>
- * Element nodes don't contain data per se. Their data is contained in their attributes
- * as well as their children's attributes, see {@link UiAttributeNode}.
- * <p/>
- * The structure of a given {@link UiElementNode} is declared by a corresponding
- * {@link ElementDescriptor}.
- */
-public final class UiManifestElementNode extends UiElementNode {
-
-    /**
-     * Creates a new {@link UiElementNode} described by a given {@link ElementDescriptor}.
-     *
-     * @param elementDescriptor The {@link ElementDescriptor} for the XML node. Cannot be null.
-     */
-    public UiManifestElementNode(ManifestElementDescriptor elementDescriptor) {
-        super(elementDescriptor);
-    }
-
-    /**
-     * Computes a short string describing the UI node suitable for tree views.
-     * Uses the element's attribute "android:name" if present, or the "android:label" one
-     * followed by the element's name.
-     *
-     * @return A short string describing the UI node suitable for tree views.
-     */
-    @Override
-    public String getShortDescription() {
-        AndroidTargetData target = getAndroidTarget();
-        AndroidManifestDescriptors manifestDescriptors = null;
-        if (target != null) {
-            manifestDescriptors = target.getManifestDescriptors();
-        }
-
-        if (manifestDescriptors != null &&
-                getXmlNode() != null &&
-                getXmlNode() instanceof Element &&
-                getXmlNode().hasAttributes()) {
-
-
-            // Application and Manifest nodes have a special treatment: they are unique nodes
-            // so we don't bother trying to differentiate their strings and we fall back to
-            // just using the UI name below.
-            ElementDescriptor desc = getDescriptor();
-            if (desc != manifestDescriptors.getManifestElement() &&
-                    desc != manifestDescriptors.getApplicationElement()) {
-                Element elem = (Element) getXmlNode();
-                String attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
-                                                  AndroidManifestDescriptors.ANDROID_NAME_ATTR);
-                if (attr == null || attr.length() == 0) {
-                    attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
-                                               AndroidManifestDescriptors.ANDROID_LABEL_ATTR);
-                }
-                if (attr != null && attr.length() > 0) {
-                    return String.format("%1$s (%2$s)", attr, getDescriptor().getUiName());
-                }
-            }
-        }
-
-        return String.format("%1$s", getDescriptor().getUiName());
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java
deleted file mode 100755
index 5687ece..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.model;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.actions.NewProjectAction;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.ElementListSelectionDialog;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.eclipse.ui.part.FileEditorInput;
-
-import java.util.TreeSet;
-
-/**
- * Represents an XML attribute to select an exisintg manifest package, that can be modified using
- * a simple text field or a dialog to choose an existing package.
- * <p/>
- * See {@link UiTextAttributeNode} for more information.
- */
-public class UiManifestPkgAttrNode extends UiTextAttributeNode {
-
-    /**
-     * Creates a {@link UiManifestPkgAttrNode} object that will display ui to select or create
-     * a manifest package.
-     * @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node.
-     */
-    public UiManifestPkgAttrNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-
-    /* (non-java doc)
-     * Creates a label widget and an associated text field.
-     * <p/>
-     * As most other parts of the android manifest editor, this assumes the
-     * parent uses a table layout with 2 columns.
-     */
-    @Override
-    public void createUiControl(final Composite parent, final IManagedForm managedForm) {
-        setManagedForm(managedForm);
-        FormToolkit toolkit = managedForm.getToolkit();
-        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-
-        StringBuilder label = new StringBuilder();
-        label.append("<form><p><a href='unused'>");  //$NON-NLS-1$
-        label.append(desc.getUiName());
-        label.append("</a></p></form>");  //$NON-NLS-1$
-        FormText formText = SectionHelper.createFormText(parent, toolkit, true /* isHtml */,
-                label.toString(), true /* setupLayoutData */);
-        formText.addHyperlinkListener(new HyperlinkAdapter() {
-            @Override
-            public void linkActivated(HyperlinkEvent e) {
-                super.linkActivated(e);
-                doLabelClick();
-            }
-        });
-        formText.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
-        SectionHelper.addControlTooltip(formText, desc.getTooltip());
-        
-        Composite composite = toolkit.createComposite(parent);
-        composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
-        GridLayout gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        composite.setLayout(gl);
-        // Fixes missing text borders under GTK... also requires adding a 1-pixel margin
-        // for the text field below
-        toolkit.paintBordersFor(composite);
-        
-        final Text text = toolkit.createText(composite, getCurrentValue());
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalIndent = 1;  // Needed by the fixed composite borders under GTK
-        text.setLayoutData(gd);
-
-        setTextWidget(text);
-
-        Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
-        
-        browseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                doBrowseClick();
-            }
-        });
-        
-    }
-    
-    /* (non-java doc)
-     * Adds a validator to the text field that calls managedForm.getMessageManager().
-     */
-    @Override
-    protected void onAddValidators(final Text text) {
-        ModifyListener listener = new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                String package_name = text.getText();
-                if (package_name.indexOf('.') < 1) {
-                    getManagedForm().getMessageManager().addMessage(text,
-                            "Package name should contain at least two identifiers.",
-                            null /* data */, IMessageProvider.ERROR, text);
-                } else {
-                    getManagedForm().getMessageManager().removeMessage(text, text);
-                }
-            }
-        };
-
-        text.addModifyListener(listener);
-
-        // Make sure the validator removes its message(s) when the widget is disposed
-        text.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                getManagedForm().getMessageManager().removeMessage(text, text);
-            }
-        });
-
-        // Finally call the validator once to make sure the initial value is processed
-        listener.modifyText(null);
-    }
-
-    /**
-     * Handles response to the Browse button by creating a Package dialog.
-     * */
-    private void doBrowseClick() {
-        
-        // Display the list of AndroidManifest packages in a selection dialog
-        ElementListSelectionDialog dialog = new ElementListSelectionDialog(
-                getTextWidget().getShell(),
-                new ILabelProvider() {
-                    public Image getImage(Object element) {
-                        return null;
-                    }
-
-                    public String getText(Object element) {
-                        return element.toString();
-                    }
-
-                    public void addListener(ILabelProviderListener listener) {
-                    }
-
-                    public void dispose() {
-                    }
-
-                    public boolean isLabelProperty(Object element, String property) {
-                        return false;
-                    }
-
-                    public void removeListener(ILabelProviderListener listener) {
-                    }
-                });
-
-        dialog.setTitle("Android Manifest Package Selection");
-        dialog.setMessage("Select the Android Manifest package to target.");
-
-        dialog.setElements(getPossibleValues(null));
-
-        // open the dialog and use the object selected if OK was clicked, or null otherwise
-        if (dialog.open() == Window.OK) {
-            String result = (String) dialog.getFirstResult();
-            if (result != null && result.length() > 0) {
-                getTextWidget().setText(result);
-            }
-        }
-    }
-
-    /**
-     * Handles response to the Label hyper link being activated.
-     */
-    private void doLabelClick() {
-        // get the current package name
-        String package_name = getTextWidget().getText().trim();
-        
-        if (package_name.length() == 0) {
-            createNewProject();
-        } else {
-            displayExistingManifest(package_name);
-        }
-    }
-
-    /**
-     * When the label is clicked and there's already a package name, this method
-     * attempts to find the project matching the android package name and it attempts
-     * to open the manifest editor.
-     * 
-     * @param package_name The android package name to find. Must not be null.
-     */
-    private void displayExistingManifest(String package_name) {
-
-        // Look for the first project that uses this package name
-        for (IJavaProject project : BaseProjectHelper.getAndroidProjects()) {
-            // check that there is indeed a manifest file.
-            IFile manifestFile = AndroidManifestParser.getManifest(project.getProject());
-            if (manifestFile == null) {
-                // no file? skip this project.
-                continue;
-            }
-
-            AndroidManifestParser parser = null;
-            try {
-                parser = AndroidManifestParser.parseForData(manifestFile);
-            } catch (CoreException e) {
-                // ignore, handled below.
-            }
-            if (parser == null) {
-                // skip this project.
-                continue;
-            }
-
-            if (package_name.equals(parser.getPackage())) {
-                // Found the project. 
-
-                IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-                if (win != null) {
-                    IWorkbenchPage page = win.getActivePage();
-                    if (page != null) {
-                        try {
-                            page.openEditor(
-                                    new FileEditorInput(manifestFile),
-                                    ManifestEditor.ID,
-                                    true, /* activate */
-                                    IWorkbenchPage.MATCH_INPUT);
-                        } catch (PartInitException e) {
-                            AdtPlugin.log(e,
-                                    "Opening editor failed for %s",  //$NON-NLS-1$
-                                    manifestFile.getFullPath());
-                        }
-                    }
-                }
-
-                // We found the project; even if we failed there's no need to keep looking.
-                return;
-            }
-        }
-    }
-
-    /**
-     * Displays the New Project Wizard to create a new project.
-     * If one is successfully created, use the Android Package name.
-     */
-    private void createNewProject() {
-
-        NewProjectAction npwAction = new NewProjectAction();
-        npwAction.run(null /*action*/);
-        if (npwAction.getDialogResult() == Dialog.OK) {
-            NewProjectWizard npw = (NewProjectWizard) npwAction.getWizard();
-            String name = npw.getPackageName();
-            if (name != null && name.length() > 0) {
-                getTextWidget().setText(name);
-            }
-        }
-    }
-
-    /**
-     * Returns all the possible android package names that could be used.
-     * The prefix is not used.
-     * 
-     * {@inheritDoc}
-     */
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        TreeSet<String> packages = new TreeSet<String>();
-
-        for (IJavaProject project : BaseProjectHelper.getAndroidProjects()) {
-            // check that there is indeed a manifest file.
-            IFile manifestFile = AndroidManifestParser.getManifest(project.getProject());
-            if (manifestFile == null) {
-                // no file? skip this project.
-                continue;
-            }
-
-            AndroidManifestParser parser = null;
-            try {
-                parser = AndroidManifestParser.parseForData(manifestFile);
-            } catch (CoreException e) {
-                // ignore, handled below.
-            }
-            if (parser == null) {
-                // skip this project.
-                continue;
-            }
-
-            packages.add(parser.getPackage());
-        }
-
-        return packages.toArray(new String[packages.size()]);
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java
deleted file mode 100644
index d345d32..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.model;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.ui.JavaUI;
-import org.eclipse.jdt.ui.actions.OpenNewPackageWizardAction;
-import org.eclipse.jdt.ui.actions.ShowInPackageViewAction;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.IWorkbenchPartSite;
-import org.eclipse.ui.dialogs.SelectionDialog;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-
-import java.util.ArrayList;
-
-/**
- * Represents an XML attribute for a package, that can be modified using a simple text field or
- * a dialog to choose an existing package. Also, there's a link to create a new package.
- * <p/>
- * See {@link UiTextAttributeNode} for more information.
- */
-public class UiPackageAttributeNode extends UiTextAttributeNode {
-
-    /**
-     * Creates a {@link UiPackageAttributeNode} object that will display ui to select or create
-     * a package.
-     * @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node.
-     */
-    public UiPackageAttributeNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-
-    /* (non-java doc)
-     * Creates a label widget and an associated text field.
-     * <p/>
-     * As most other parts of the android manifest editor, this assumes the
-     * parent uses a table layout with 2 columns.
-     */
-    @Override
-    public void createUiControl(final Composite parent, final IManagedForm managedForm) {
-        setManagedForm(managedForm);
-        FormToolkit toolkit = managedForm.getToolkit();
-        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-
-        StringBuilder label = new StringBuilder();
-        label.append("<form><p><a href='unused'>");  //$NON-NLS-1$
-        label.append(desc.getUiName());
-        label.append("</a></p></form>");  //$NON-NLS-1$
-        FormText formText = SectionHelper.createFormText(parent, toolkit, true /* isHtml */,
-                label.toString(), true /* setupLayoutData */);
-        formText.addHyperlinkListener(new HyperlinkAdapter() {
-            @Override
-            public void linkActivated(HyperlinkEvent e) {
-                super.linkActivated(e);
-                doLabelClick();
-            }
-        });
-        formText.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
-        SectionHelper.addControlTooltip(formText, desc.getTooltip());
-        
-        Composite composite = toolkit.createComposite(parent);
-        composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
-        GridLayout gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        composite.setLayout(gl);
-        // Fixes missing text borders under GTK... also requires adding a 1-pixel margin
-        // for the text field below
-        toolkit.paintBordersFor(composite);
-        
-        final Text text = toolkit.createText(composite, getCurrentValue());
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalIndent = 1;  // Needed by the fixed composite borders under GTK
-        text.setLayoutData(gd);
-
-        setTextWidget(text);
-
-        Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
-        
-        browseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                doBrowseClick();
-            }
-        });
-        
-    }
-    
-    /* (non-java doc)
-     * Adds a validator to the text field that calls managedForm.getMessageManager().
-     */
-    @Override
-    protected void onAddValidators(final Text text) {
-        ModifyListener listener = new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                String package_name = text.getText();
-                if (package_name.indexOf('.') < 1) {
-                    getManagedForm().getMessageManager().addMessage(text,
-                            "Package name should contain at least two identifiers.",
-                            null /* data */, IMessageProvider.ERROR, text);
-                } else {
-                    getManagedForm().getMessageManager().removeMessage(text, text);
-                }
-            }
-        };
-
-        text.addModifyListener(listener);
-
-        // Make sure the validator removes its message(s) when the widget is disposed
-        text.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                getManagedForm().getMessageManager().removeMessage(text, text);
-            }
-        });
-
-        // Finally call the validator once to make sure the initial value is processed
-        listener.modifyText(null);
-    }
-
-    /**
-     * Handles response to the Browse button by creating a Package dialog.
-     * */
-    private void doBrowseClick() {
-        Text text = getTextWidget();
-        
-        // we need to get the project of the manifest.
-        IProject project = getProject();
-        if (project != null) {
-            
-            try {
-                SelectionDialog dlg = JavaUI.createPackageDialog(text.getShell(),
-                        JavaCore.create(project), 0);
-                dlg.setTitle("Select Android Package");
-                dlg.setMessage("Select the package for the Android project.");
-                SelectionDialog.setDefaultImage(AdtPlugin.getAndroidLogo());
-
-                if (dlg.open() == Window.OK) {
-                    Object[] results = dlg.getResult();
-                    if (results.length == 1) {
-                        setPackageTextField((IPackageFragment)results[0]);
-                    }
-                }
-            } catch (JavaModelException e1) {
-            }
-        }
-    }
-
-    /**
-     * Handles response to the Label hyper link being activated.
-     */
-    private void doLabelClick() {
-        // get the current package name
-        String package_name = getTextWidget().getText().trim();
-        
-        if (package_name.length() == 0) {
-            createNewPackage();
-        } else {
-            // Try to select the package in the Package Explorer for the current
-            // project and the current editor's site.
-
-            IProject project = getProject();
-            if (project == null) {
-                AdtPlugin.log(IStatus.ERROR, "Failed to get project for UiPackageAttribute"); //$NON-NLS-1$
-                return;
-            }
-
-            IWorkbenchPartSite site = getUiParent().getEditor().getSite();
-            if (site == null) {
-                AdtPlugin.log(IStatus.ERROR, "Failed to get editor site for UiPackageAttribute"); //$NON-NLS-1$
-                return;
-            }
-
-            for (IPackageFragmentRoot root : getPackageFragmentRoots(project)) {
-                IPackageFragment fragment = root.getPackageFragment(package_name);
-                if (fragment != null && fragment.exists()) {
-                    ShowInPackageViewAction action = new ShowInPackageViewAction(site);
-                    action.run(fragment);
-                    // This action's run() doesn't provide the status (although internally it could)
-                    // so we just assume it worked.
-                    return;
-                }
-            }
-        }
-    }
-
-    /**
-     * Utility method that returns the project for the current file being edited.
-     * 
-     * @return The IProject for the current file being edited or null.
-     */
-    private IProject getProject() {
-        UiElementNode uiNode = getUiParent();
-        AndroidEditor editor = uiNode.getEditor();
-        IEditorInput input = editor.getEditorInput();
-        if (input instanceof IFileEditorInput) {
-            // from the file editor we can get the IFile object, and from it, the IProject.
-            IFile file = ((IFileEditorInput)input).getFile();
-            return file.getProject();
-        }
-        
-        return null;
-    }
-
-    /**
-     * Utility method that computes and returns the list of {@link IPackageFragmentRoot}
-     * corresponding to the source folder of the specified project.
-     * 
-     * @param project the project
-     * @return an array of IPackageFragmentRoot. Can be empty but not null.
-     */
-    private IPackageFragmentRoot[] getPackageFragmentRoots(IProject project) {
-        ArrayList<IPackageFragmentRoot> result = new ArrayList<IPackageFragmentRoot>();
-        try {
-            IJavaProject javaProject = JavaCore.create(project);
-            IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
-            for (int i = 0; i < roots.length; i++) {
-                IClasspathEntry entry = roots[i].getRawClasspathEntry();
-                if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
-                    result.add(roots[i]);
-                }
-            }
-        } catch (JavaModelException e) {
-        }
-
-        return result.toArray(new IPackageFragmentRoot[result.size()]);
-    }
-    
-    /**
-     * Utility method that sets the package's text field to the package fragment's name.
-     * */
-    private void setPackageTextField(IPackageFragment type) {
-        Text text = getTextWidget();
-
-        String name = type.getElementName();
-        
-        text.setText(name);
-    }
-    
-
-    /**
-     * Displays and handles a "Create Package Wizard".
-     * 
-     * This is invoked by doLabelClick() when clicking on the hyperlink label with an
-     * empty package text field.  
-     */
-    private void createNewPackage() {
-        OpenNewPackageWizardAction action = new OpenNewPackageWizardAction();
-
-        IProject project = getProject();
-        action.setSelection(new StructuredSelection(project));
-        action.run();
-
-        IJavaElement element = action.getCreatedElement();
-        if (element != null &&
-                element.exists() &&
-                element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
-            setPackageTextField((IPackageFragment) element);
-        }
-    }
-    
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        // TODO: compute a list of existing packages for content assist completion
-        return null;
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationAttributesPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationAttributesPart.java
deleted file mode 100644
index c9f82dd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationAttributesPart.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.ui.UiElementPart;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * Application's attributes section part for Application page.
- * <p/>
- * This part is displayed at the top of the application page and displays all the possible
- * attributes of an application node in the AndroidManifest (icon, class name, label, etc.)
- */
-final class ApplicationAttributesPart extends UiElementPart {
-
-    /** Listen to changes to the UI node for <application> and updates the UI */
-    private AppNodeUpdateListener mAppNodeUpdateListener;
-    /** ManagedForm needed to create the UI controls */ 
-    private IManagedForm mManagedForm;
-
-    public ApplicationAttributesPart(Composite body, FormToolkit toolkit, ManifestEditor editor,
-            UiElementNode applicationUiNode) {
-        super(body, toolkit, editor, applicationUiNode,
-                "Application Attributes", // section title
-                "Defines the attributes specific to the application.", // section description
-                Section.TWISTIE | Section.EXPANDED);
-    }
-    
-    /**
-     * Changes and refreshes the Application UI node handle by the this part.
-     */
-    @Override
-    public void setUiElementNode(UiElementNode uiElementNode) {
-        super.setUiElementNode(uiElementNode);
-
-        createUiAttributes(mManagedForm);
-    }
-
-    /* (non-java doc)
-     * Create the controls to edit the attributes for the given ElementDescriptor.
-     * <p/>
-     * This MUST not be called by the constructor. Instead it must be called from
-     * <code>initialize</code> (i.e. right after the form part is added to the managed form.)
-     * <p/>
-     * Derived classes can override this if necessary.
-     * 
-     * @param managedForm The owner managed form
-     */
-    @Override
-    protected void createFormControls(final IManagedForm managedForm) {
-        mManagedForm = managedForm; 
-        setTable(createTableLayout(managedForm.getToolkit(), 4 /* numColumns */));
-
-        mAppNodeUpdateListener = new AppNodeUpdateListener();
-        getUiElementNode().addUpdateListener(mAppNodeUpdateListener);
-
-        createUiAttributes(mManagedForm);
-    }
-    
-    @Override
-    public void dispose() {
-        super.dispose();
-        if (getUiElementNode() != null && mAppNodeUpdateListener != null) {
-            getUiElementNode().removeUpdateListener(mAppNodeUpdateListener);
-            mAppNodeUpdateListener = null;
-        }
-    }
-
-    @Override
-    protected void createUiAttributes(IManagedForm managedForm) {
-        Composite table = getTable();
-        if (table == null || managedForm == null) {
-            return;
-        }
-        
-        // Remove any old UI controls 
-        for (Control c : table.getChildren()) {
-            c.dispose();
-        }
-        
-        UiElementNode uiElementNode = getUiElementNode(); 
-        AttributeDescriptor[] attr_desc_list = uiElementNode.getAttributeDescriptors();
-
-        // Display the attributes in 2 columns:
-        // attr 0 | attr 4 
-        // attr 1 | attr 5
-        // attr 2 | attr 6
-        // attr 3 | attr 7
-        // that is we have to fill the grid in order 0, 4, 1, 5, 2, 6, 3, 7
-        // thus index = i/2 + (i is odd * n/2)
-        int n = attr_desc_list.length;
-        int n2 = (int) Math.ceil(n / 2.0);
-        for (int i = 0; i < n; i++) {
-            AttributeDescriptor attr_desc = attr_desc_list[i / 2 + (i & 1) * n2];
-            if (attr_desc instanceof XmlnsAttributeDescriptor) {
-                // Do not show hidden attributes
-                continue;
-            }
-
-            UiAttributeNode ui_attr = uiElementNode.findUiAttribute(attr_desc);
-            if (ui_attr != null) {
-                ui_attr.createUiControl(table, managedForm);
-            } else {
-                // The XML has an extra attribute which wasn't declared in
-                // AndroidManifestDescriptors. This is not a problem, we just ignore it.
-                AdtPlugin.log(IStatus.WARNING,
-                        "Attribute %1$s not declared in node %2$s, ignored.", //$NON-NLS-1$
-                        attr_desc.getXmlLocalName(),
-                        uiElementNode.getDescriptor().getXmlName());
-            }
-        }
-        
-        if (n == 0) {
-            createLabel(table, managedForm.getToolkit(),
-                    "No attributes to display, waiting for SDK to finish loading...",
-                    null /* tooltip */ );
-        }
-
-        // Initialize the enabled/disabled state
-        if (mAppNodeUpdateListener != null) {
-            mAppNodeUpdateListener.uiElementNodeUpdated(uiElementNode, null /* state, not used */);
-        }
-        
-        // Tell the section that the layout has changed.
-        layoutChanged();
-    }
-
-    /**
-     * This listener synchronizes the UI with the actual presence of the application XML node.
-     */
-    private class AppNodeUpdateListener implements IUiUpdateListener {        
-        public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
-            // The UiElementNode for the application XML node always exists, even
-            // if there is no corresponding XML node in the XML file.
-            //
-            // We enable the UI here if the XML node is not null.
-            Composite table = getTable();
-            boolean exists = (ui_node.getXmlNode() != null);
-            if (table != null && table.getEnabled() != exists) {
-                table.setEnabled(exists);
-                for (Control c : table.getChildren()) {
-                    c.setEnabled(exists);
-                }
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationPage.java
deleted file mode 100644
index 3862a1e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationPage.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-
-/**
- * Page for "Application" settings, part of the AndroidManifest form editor.
- * <p/>
- * Useful reference:
- * <a href="http://www.eclipse.org/articles/Article-Forms/article.html">
- *   http://www.eclipse.org/articles/Article-Forms/article.html</a>
- */
-public final class ApplicationPage extends FormPage {
-    /** Page id used for switching tabs programmatically */
-    public final static String PAGE_ID = "application_page"; //$NON-NLS-1$
-
-    /** Container editor */
-    ManifestEditor mEditor;
-    /** The Application Toogle part */
-    private ApplicationToggle mTooglePart;
-    /** The Application Attributes part */ 
-    private ApplicationAttributesPart mAttrPart;
-    /** The tree view block */
-    private UiTreeBlock mTreeBlock;
-
-    public ApplicationPage(ManifestEditor editor) {
-        super(editor, PAGE_ID, "Application"); // tab's label, keep it short
-        mEditor = editor;
-    }
-
-    /**
-     * Creates the content in the form hosted in this page.
-     * 
-     * @param managedForm the form hosted in this page.
-     */
-    @Override
-    protected void createFormContent(IManagedForm managedForm) {
-        super.createFormContent(managedForm);
-        ScrolledForm form = managedForm.getForm();
-        form.setText("Android Manifest Application");
-        form.setImage(AdtPlugin.getAndroidLogo());
-
-        UiElementNode appUiNode = getUiApplicationNode();
-
-        Composite body = form.getBody();
-        FormToolkit toolkit = managedForm.getToolkit();
-        
-        // We usually prefer to have a ColumnLayout here. However
-        // MasterDetailsBlock.createContent() below will reset the body's layout to a grid layout.
-        mTooglePart = new ApplicationToggle(body, toolkit, mEditor, appUiNode);
-        mTooglePart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-        managedForm.addPart(mTooglePart);
-        mAttrPart = new ApplicationAttributesPart(body, toolkit, mEditor, appUiNode);
-        mAttrPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-        managedForm.addPart(mAttrPart);
-
-        mTreeBlock = new UiTreeBlock(mEditor, appUiNode,
-                false /* autoCreateRoot */,
-                null /* element filters */,
-                "Application Nodes",
-                "List of all elements in the application");
-        mTreeBlock.createContent(managedForm);
-    }
-
-    /**
-     * Retrieves the application UI node. Since this is a mandatory node, it *always*
-     * exists, even if there is no matching XML node.
-     */
-    private UiElementNode getUiApplicationNode() {
-        AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
-        if (manifestDescriptor != null) {
-            ElementDescriptor desc = manifestDescriptor.getApplicationElement();
-            return mEditor.getUiRootNode().findUiChildNode(desc.getXmlName());
-        } else {
-            // return the ui root node, as a dummy application root node.
-            return mEditor.getUiRootNode();
-        }
-    }
-
-    /**
-     * Changes and refreshes the Application UI node handled by the sub parts.
-     */
-    public void refreshUiApplicationNode() {
-        UiElementNode appUiNode = getUiApplicationNode();
-        if (mTooglePart != null) {
-            mTooglePart.setUiElementNode(appUiNode);
-        }
-        if (mAttrPart != null) {
-            mAttrPart.setUiElementNode(appUiNode);
-        }
-        if (mTreeBlock != null) {
-            mTreeBlock.changeRootAndDescriptors(appUiNode,
-                    null /* element filters */,
-                    true /* refresh */);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationToggle.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationToggle.java
deleted file mode 100644
index 76a0442..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationToggle.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.ui.UiElementPart;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener.UiUpdateState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
-/**
- * Appllication Toogle section part for application page.
- */
-final class ApplicationToggle extends UiElementPart {
-    
-    /** Checkbox indicating whether an application node is present */ 
-    private Button mCheckbox;
-    /** Listen to changes to the UI node for <application> and updates the checkbox */
-    private AppNodeUpdateListener mAppNodeUpdateListener;
-    /** Internal flag to know where we're programmatically modifying the checkbox and we want to
-     *  avoid triggering the checkbox's callback. */
-    public boolean mInternalModification;
-    private FormText mTooltipFormText;
-
-    public ApplicationToggle(Composite body, FormToolkit toolkit, ManifestEditor editor,
-            UiElementNode applicationUiNode) {
-        super(body, toolkit, editor, applicationUiNode,
-                "Application Toggle",
-                null, /* description */
-                Section.TWISTIE | Section.EXPANDED);
-    }
-    
-    @Override
-    public void dispose() {
-        super.dispose();
-        if (getUiElementNode() != null && mAppNodeUpdateListener != null) {
-            getUiElementNode().removeUpdateListener(mAppNodeUpdateListener);
-            mAppNodeUpdateListener = null;
-        }
-    }
-    
-    /**
-     * Changes and refreshes the Application UI node handle by the this part.
-     */
-    @Override
-    public void setUiElementNode(UiElementNode uiElementNode) {
-        super.setUiElementNode(uiElementNode);
-
-        updateTooltip();
-
-        // Set the state of the checkbox
-        mAppNodeUpdateListener.uiElementNodeUpdated(getUiElementNode(),
-                UiUpdateState.CHILDREN_CHANGED);
-    }
-
-    /**
-     * Create the controls to edit the attributes for the given ElementDescriptor.
-     * <p/>
-     * This MUST not be called by the constructor. Instead it must be called from
-     * <code>initialize</code> (i.e. right after the form part is added to the managed form.)
-     * 
-     * @param managedForm The owner managed form
-     */
-    @Override
-    protected void createFormControls(IManagedForm managedForm) {
-        FormToolkit toolkit = managedForm.getToolkit();
-        Composite table = createTableLayout(toolkit, 1 /* numColumns */);
-
-        mTooltipFormText = createFormText(table, toolkit, true, "<form></form>",
-                false /* setupLayoutData */);
-        updateTooltip();
-
-        mCheckbox = toolkit.createButton(table,
-                "Define an <application> tag in the AndroidManifest.xml",
-                SWT.CHECK);
-        mCheckbox.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP));
-        mCheckbox.setSelection(false);
-        mCheckbox.addSelectionListener(new CheckboxSelectionListener());
-
-        mAppNodeUpdateListener = new AppNodeUpdateListener();
-        getUiElementNode().addUpdateListener(mAppNodeUpdateListener);
-
-        // Initialize the state of the checkbox
-        mAppNodeUpdateListener.uiElementNodeUpdated(getUiElementNode(),
-                UiUpdateState.CHILDREN_CHANGED);
-        
-        // Tell the section that the layout has changed.
-        layoutChanged();
-    }
-
-    /**
-     * Updates the application tooltip in the form text.
-     * If there is no tooltip, the form text is hidden. 
-     */
-    private void updateTooltip() {
-        boolean isVisible = false;
-
-        String tooltip = getUiElementNode().getDescriptor().getTooltip();
-        if (tooltip != null) {
-            tooltip = DescriptorsUtils.formatFormText(tooltip,
-                    getUiElementNode().getDescriptor(),
-                    Sdk.getCurrent().getDocumentationBaseUrl());
-    
-            mTooltipFormText.setText(tooltip, true /* parseTags */, true /* expandURLs */);
-            mTooltipFormText.setImage(DescriptorsUtils.IMAGE_KEY, AdtPlugin.getAndroidLogo());
-            mTooltipFormText.addHyperlinkListener(getEditor().createHyperlinkListener());
-            isVisible = true;
-        }
-        
-        mTooltipFormText.setVisible(isVisible);
-    }
-
-    /**
-     * This listener synchronizes the XML application node when the checkbox
-     * is changed by the user.
-     */
-    private class CheckboxSelectionListener extends SelectionAdapter {
-        private Node mUndoXmlNode;
-        private Node mUndoXmlParent;
-        private Node mUndoXmlNextNode;
-        private Node mUndoXmlNextElement;
-        private Document mUndoXmlDocument;
-
-        @Override
-        public void widgetSelected(SelectionEvent e) {
-            super.widgetSelected(e);
-            if (!mInternalModification && getUiElementNode() != null) {
-                getUiElementNode().getEditor().wrapUndoRecording(
-                        mCheckbox.getSelection()
-                            ? "Create or restore Application node"
-                            : "Remove Application node",
-                        new Runnable() {
-                            public void run() {
-                                getUiElementNode().getEditor().editXmlModel(new Runnable() {
-                                    public void run() {
-                                        if (mCheckbox.getSelection()) {
-                                            // The user wants an <application> node.
-                                            // Either restore a previous one
-                                            // or create a full new one.
-                                            boolean create = true;
-                                            if (mUndoXmlNode != null) {
-                                                create = !restoreApplicationNode();
-                                            }
-                                            if (create) {
-                                                getUiElementNode().createXmlNode();
-                                            }
-                                        } else {
-                                            // Users no longer wants the <application> node.
-                                            removeApplicationNode();
-                                        }
-                                    }
-                                });
-                            }
-                });
-            }
-        }
-
-        /**
-         * Restore a previously "saved" application node.
-         * 
-         * @return True if the node could be restored, false otherwise.
-         */
-        private boolean restoreApplicationNode() {
-            if (mUndoXmlDocument == null || mUndoXmlNode == null) {
-                return false;
-            }
-
-            // Validate node references...
-            mUndoXmlParent = validateNode(mUndoXmlDocument, mUndoXmlParent);
-            mUndoXmlNextNode = validateNode(mUndoXmlDocument, mUndoXmlNextNode);
-            mUndoXmlNextElement = validateNode(mUndoXmlDocument, mUndoXmlNextElement);
-
-            if (mUndoXmlParent == null){
-                // If the parent node doesn't exist, try to find a new manifest node.
-                // If it doesn't exist, create it.
-                mUndoXmlParent = getUiElementNode().getUiParent().prepareCommit();
-                mUndoXmlNextNode = null;
-                mUndoXmlNextElement = null;
-            }
-
-            boolean success = false;
-            if (mUndoXmlParent != null) {
-                // If the parent is still around, reuse the same node.
-
-                // Ideally we want to insert the node before what used to be its next sibling.
-                // If that's not possible, we try to insert it before its next sibling element.
-                // If that's not possible either, it will be inserted at the end of the parent's.
-                Node next = mUndoXmlNextNode;
-                if (next == null) {
-                    next = mUndoXmlNextElement;
-                }
-                mUndoXmlParent.insertBefore(mUndoXmlNode, next);
-                if (next == null) {
-                    Text sep = mUndoXmlDocument.createTextNode("\n");  //$NON-NLS-1$
-                    mUndoXmlParent.insertBefore(sep, null);  // insert separator before end tag
-                }
-                success = true;
-            } 
-
-            // Remove internal references to avoid using them twice
-            mUndoXmlParent = null;
-            mUndoXmlNextNode = null;
-            mUndoXmlNextElement = null;
-            mUndoXmlNode = null;
-            mUndoXmlDocument = null;
-            return success;
-        }
-
-        /**
-         * Validates that the given xml_node is still either the root node or one of its
-         * direct descendants. 
-         * 
-         * @param root_node The root of the node hierarchy to examine.
-         * @param xml_node The XML node to find.
-         * @return Returns xml_node if it is, otherwise returns null.
-         */
-        private Node validateNode(Node root_node, Node xml_node) {
-            if (root_node == xml_node) {
-                return xml_node;
-            } else {
-                for (Node node = root_node.getFirstChild(); node != null;
-                        node = node.getNextSibling()) {
-                    if (root_node == xml_node || validateNode(node, xml_node) != null) {
-                        return xml_node;
-                    }
-                }
-            }
-            return null;
-        }
-
-        /**
-         * Removes the <application> node from the hierarchy.
-         * Before doing that, we try to remember where it was so that we can put it back
-         * in the same place.
-         */
-        private void removeApplicationNode() {
-            // Make sure the node actually exists...
-            Node xml_node = getUiElementNode().getXmlNode();
-            if (xml_node == null) {
-                return;
-            }
-
-            // Save its parent, next sibling and next element
-            mUndoXmlDocument = xml_node.getOwnerDocument();
-            mUndoXmlParent = xml_node.getParentNode();
-            mUndoXmlNextNode = xml_node.getNextSibling();
-            mUndoXmlNextElement = mUndoXmlNextNode;
-            while (mUndoXmlNextElement != null &&
-                    mUndoXmlNextElement.getNodeType() != Node.ELEMENT_NODE) {
-                mUndoXmlNextElement = mUndoXmlNextElement.getNextSibling();
-            }
-
-            // Actually remove the node from the hierarchy and keep it here.
-            // The returned node looses its parents/siblings pointers.
-            mUndoXmlNode = getUiElementNode().deleteXmlNode();
-        }
-    }
-
-    /**
-     * This listener synchronizes the UI (i.e. the checkbox) with the
-     * actual presence of the application XML node.
-     */
-    private class AppNodeUpdateListener implements IUiUpdateListener {        
-        public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
-            // The UiElementNode for the application XML node always exists, even
-            // if there is no corresponding XML node in the XML file.
-            //
-            // To update the checkbox to reflect the actual state, we just need
-            // to check if the XML node is null.
-            try {
-                mInternalModification = true;
-                boolean exists = ui_node.getXmlNode() != null;
-                if (mCheckbox.getSelection() != exists) {
-                    mCheckbox.setSelection(exists);
-                }
-            } finally {
-                mInternalModification = false;
-            }
-            
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/InstrumentationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/InstrumentationPage.java
deleted file mode 100644
index 41063d5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/InstrumentationPage.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-/**
- * Page for instrumentation settings, part of the AndroidManifest form editor.
- */
-public final class InstrumentationPage extends FormPage {
-    /** Page id used for switching tabs programmatically */
-    public final static String PAGE_ID = "instrumentation_page"; //$NON-NLS-1$
-
-    /** Container editor */
-    ManifestEditor mEditor;
-
-    private UiTreeBlock mTreeBlock;
-
-    public InstrumentationPage(ManifestEditor editor) {
-        super(editor, PAGE_ID, "Instrumentation");  // tab's label, keep it short
-        mEditor = editor;
-    }
-
-    /**
-     * Creates the content in the form hosted in this page.
-     * 
-     * @param managedForm the form hosted in this page.
-     */
-    @Override
-    protected void createFormContent(IManagedForm managedForm) {
-        super.createFormContent(managedForm);
-        ScrolledForm form = managedForm.getForm();
-        form.setText("Android Manifest Instrumentation");
-        form.setImage(AdtPlugin.getAndroidLogo());
-
-        UiElementNode manifest = mEditor.getUiRootNode();
-        AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
-
-        ElementDescriptor[] descriptorFilters = null;
-        if (manifestDescriptor != null) {
-            descriptorFilters = new ElementDescriptor[] {
-                    manifestDescriptor.getInstrumentationElement(),
-            };
-        }
-
-        mTreeBlock = new UiTreeBlock(mEditor, manifest,
-                true /* autoCreateRoot */,
-                descriptorFilters,
-                "Instrumentation",
-                "List of instrumentations defined in the manifest");
-        mTreeBlock.createContent(managedForm);
-    }
-    
-    /**
-     * Changes and refreshes the Application UI node handled by the sub parts.
-     */
-    public void refreshUiNode() {
-        if (mTreeBlock != null) {
-            UiElementNode manifest = mEditor.getUiRootNode();
-            AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
-
-            mTreeBlock.changeRootAndDescriptors(manifest,
-                    new ElementDescriptor[] {
-                        manifestDescriptor.getInstrumentationElement()
-                    },
-                    true /* refresh */);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewExportPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewExportPart.java
deleted file mode 100644
index ec947c5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewExportPart.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.adt.internal.project.ExportHelper;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.part.FileEditorInput;
-
-/**
- * Export section part for overview page.
- */
-final class OverviewExportPart extends ManifestSectionPart {
-
-    private final OverviewPage mOverviewPage;
-
-    public OverviewExportPart(OverviewPage overviewPage, Composite body, FormToolkit toolkit, ManifestEditor editor) {
-        super(body, toolkit, Section.TWISTIE | Section.EXPANDED, true /* description */);
-        mOverviewPage = overviewPage;
-        Section section = getSection();
-        section.setText("Exporting");
-        section.setDescription("To export the application for distribution, you have the following options:");
-
-        Composite table = createTableLayout(toolkit, 2 /* numColumns */);
-        
-        StringBuffer buf = new StringBuffer();
-        buf.append("<form><li><a href=\"wizard\">"); //$NON-NLS-1$
-        buf.append("Use the Export Wizard");
-        buf.append("</a>"); //$NON-NLS-1$
-        buf.append(" to export and sign an APK");
-        buf.append("</li>"); //$NON-NLS-1$
-        buf.append("<li><a href=\"manual\">"); //$NON-NLS-1$
-        buf.append("Export an unsigned APK");
-        buf.append("</a>"); //$NON-NLS-1$
-        buf.append(" and sign it manually");
-        buf.append("</li></form>"); //$NON-NLS-1$
-
-        FormText text = createFormText(table, toolkit, true, buf.toString(),
-                false /* setupLayoutData */);
-        text.addHyperlinkListener(new HyperlinkAdapter() {
-            @Override
-            public void linkActivated(HyperlinkEvent e) {
-                // get the project from the editor
-                IEditorInput input = mOverviewPage.mEditor.getEditorInput();
-                if (input instanceof FileEditorInput) {
-                    FileEditorInput fileInput = (FileEditorInput)input;
-                    IFile file = fileInput.getFile();
-                    IProject project = file.getProject();
-                    
-                    if ("manual".equals(e.data)) { //$NON-NLS-1$
-                        // now we can export an unsigned apk for the project.
-                        ExportHelper.exportProject(project);
-                    } else {
-                        // call the export wizard
-                        ExportHelper.startExportWizard(project);
-                    }
-                }
-            }
-        });
-        
-        layoutChanged();
-    }        
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewInfoPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewInfoPart.java
deleted file mode 100644
index 98f2f9c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewInfoPart.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.ui.UiElementPart;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * Generic info section part for overview page: it displays all the attributes from
- * the manifest element.
- */
-final class OverviewInfoPart extends UiElementPart {
-
-    private IManagedForm mManagedForm;
-
-    public OverviewInfoPart(Composite body, FormToolkit toolkit, ManifestEditor editor) {
-        super(body, toolkit, editor,
-                getManifestUiNode(editor),  // uiElementNode
-                "Manifest General Attributes", // section title
-                "Defines general information about the AndroidManifest.xml", // section description
-                Section.TWISTIE | Section.EXPANDED);
-    }
-
-    /**
-     * Retrieves the UiElementNode that this part will edit. The node must exist
-     * and can't be null, by design, because it's a mandatory node.
-     */
-    private static UiElementNode getManifestUiNode(ManifestEditor editor) {
-        AndroidManifestDescriptors manifestDescriptors = editor.getManifestDescriptors();
-        if (manifestDescriptors != null) {
-            ElementDescriptor desc = manifestDescriptors.getManifestElement();
-            if (editor.getUiRootNode().getDescriptor() == desc) {
-                return editor.getUiRootNode();
-            } else {
-                return editor.getUiRootNode().findUiChildNode(desc.getXmlName());
-            }
-        }
-        
-        // No manifest descriptor: we have a dummy UiRootNode, so we return that.
-        // The editor will be reloaded once we have the proper descriptors anyway.
-        return editor.getUiRootNode();
-    }
-
-    /**
-     * Overridden in order to capture the current managed form.
-     * 
-     * {@inheritDoc}
-     */
-    @Override
-    protected void createFormControls(final IManagedForm managedForm) {
-        mManagedForm = managedForm; 
-        super.createFormControls(managedForm);
-    }
-
-    /**
-     * Removes any existing Attribute UI widgets and recreate them if the SDK has changed.
-     * <p/>
-     * This is called by {@link OverviewPage#refreshUiApplicationNode()} when the
-     * SDK has changed.
-     */
-    public void onSdkChanged() {
-        setUiElementNode(getManifestUiNode(getEditor()));
-        createUiAttributes(mManagedForm);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewLinksPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewLinksPart.java
deleted file mode 100644
index daf0885..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewLinksPart.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * Links section part for overview page.
- */
-final class OverviewLinksPart extends ManifestSectionPart {
-
-    private final ManifestEditor mEditor;
-    private FormText mFormText;
-
-    public OverviewLinksPart(Composite body, FormToolkit toolkit, ManifestEditor editor) {
-        super(body, toolkit, Section.TWISTIE | Section.EXPANDED, true /* description */);
-        mEditor = editor;
-        Section section = getSection();
-        section.setText("Links");
-        section.setDescription("The content of the Android Manifest is made up of three sections. You can also edit the XML directly.");
-
-        Composite table = createTableLayout(toolkit, 2 /* numColumns */);
-        
-        StringBuffer buf = new StringBuffer();
-        buf.append(String.format("<form><li style=\"image\" value=\"app_img\"><a href=\"page:%1$s\">", // $NON-NLS-1$
-                ApplicationPage.PAGE_ID));
-        buf.append("Application");
-        buf.append("</a>");  //$NON-NLS-1$
-        buf.append(": Activities, intent filters, providers, services and receivers.");
-        buf.append("</li>"); //$NON-NLS-1$
-
-        buf.append(String.format("<li style=\"image\" value=\"perm_img\"><a href=\"page:%1$s\">", // $NON-NLS-1$
-                PermissionPage.PAGE_ID));
-        buf.append("Permission");
-        buf.append("</a>"); //$NON-NLS-1$
-        buf.append(": Permissions defined and permissions used.");
-        buf.append("</li>"); //$NON-NLS-1$
-
-        buf.append(String.format("<li style=\"image\" value=\"inst_img\"><a href=\"page:%1$s\">", // $NON-NLS-1$
-                InstrumentationPage.PAGE_ID));
-        buf.append("Instrumentation");
-        buf.append("</a>"); //$NON-NLS-1$
-        buf.append(": Instrumentation defined.");
-        buf.append("</li>"); //$NON-NLS-1$
-
-        buf.append(String.format("<li style=\"image\" value=\"android_img\"><a href=\"page:%1$s\">", // $NON-NLS-1$
-                ManifestEditor.TEXT_EDITOR_ID));
-        buf.append("XML Source");
-        buf.append("</a>"); //$NON-NLS-1$
-        buf.append(": Directly edit the AndroidManifest.xml file.");
-        buf.append("</li>"); //$NON-NLS-1$
-
-        buf.append("<li style=\"image\" value=\"android_img\">"); // $NON-NLS-1$
-        buf.append("<a href=\"http://code.google.com/android/devel/bblocks-manifest.html\">Documentation</a>: Documentation from the Android SDK for AndroidManifest.xml."); // $NON-NLS-1$
-        buf.append("</li>"); //$NON-NLS-1$
-        buf.append("</form>"); //$NON-NLS-1$
-
-        mFormText = createFormText(table, toolkit, true, buf.toString(),
-                false /* setupLayoutData */);
-        
-        AndroidManifestDescriptors manifestDescriptor = editor.getManifestDescriptors();
-
-        Image androidLogo = AdtPlugin.getAndroidLogo();
-        mFormText.setImage("android_img", androidLogo); //$NON-NLS-1$
-        
-        if (manifestDescriptor != null) {
-            mFormText.setImage("app_img", getIcon(manifestDescriptor.getApplicationElement())); //$NON-NLS-1$
-            mFormText.setImage("perm_img", getIcon(manifestDescriptor.getPermissionElement())); //$NON-NLS-1$
-            mFormText.setImage("inst_img", getIcon(manifestDescriptor.getInstrumentationElement())); //$NON-NLS-1$
-        } else {
-            mFormText.setImage("app_img", androidLogo); //$NON-NLS-1$
-            mFormText.setImage("perm_img", androidLogo); //$NON-NLS-1$
-            mFormText.setImage("inst_img", androidLogo); //$NON-NLS-1$
-        }
-        mFormText.addHyperlinkListener(editor.createHyperlinkListener());
-    }
-    
-    /**
-     * Update the UI with information from the new descriptors.
-     * <p/>At this point, this only refreshes the icons.
-     * <p/>
-     * This is called by {@link OverviewPage#refreshUiApplicationNode()} when the
-     * SDK has changed.
-     */
-    public void onSdkChanged() {
-        AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
-        if (manifestDescriptor != null) {
-            mFormText.setImage("app_img", getIcon(manifestDescriptor.getApplicationElement())); //$NON-NLS-1$
-            mFormText.setImage("perm_img", getIcon(manifestDescriptor.getPermissionElement())); //$NON-NLS-1$
-            mFormText.setImage("inst_img", getIcon(manifestDescriptor.getInstrumentationElement())); //$NON-NLS-1$
-        }
-    }
-    
-    private Image getIcon(ElementDescriptor desc) {
-        if (desc != null && desc.getIcon() != null) {
-            return desc.getIcon();
-        }
-        
-        return AdtPlugin.getAndroidLogo();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewPage.java
deleted file mode 100644
index 24b8014..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewPage.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-
-
-/**
- * Page for overview settings, part of the AndroidManifest form editor.
- * <p/>
- * Useful reference:
- * <a href="http://www.eclipse.org/articles/Article-Forms/article.html">
- *   http://www.eclipse.org/articles/Article-Forms/article.html</a>
- */
-public final class OverviewPage extends FormPage {
-
-    /** Page id used for switching tabs programmatically */
-    final static String PAGE_ID = "overview_page"; //$NON-NLS-1$
-    
-    /** Container editor */
-    ManifestEditor mEditor;
-    /** Overview part (attributes for manifest) */
-    private OverviewInfoPart mOverviewPart;
-    /** Overview link part */
-    private OverviewLinksPart mOverviewLinkPart;
-
-    private UiTreeBlock mTreeBlock;
-    
-    public OverviewPage(ManifestEditor editor) {
-        super(editor, PAGE_ID, "Manifest");  // tab's label, user visible, keep it short
-        mEditor = editor;
-    }
-
-    /**
-     * Creates the content in the form hosted in this page.
-     * 
-     * @param managedForm the form hosted in this page.
-     */
-    @Override
-    protected void createFormContent(IManagedForm managedForm) {
-        super.createFormContent(managedForm);
-        ScrolledForm form = managedForm.getForm();
-        form.setText("Android Manifest");
-        form.setImage(AdtPlugin.getAndroidLogo());
-        
-        Composite body = form.getBody();
-        FormToolkit toolkit = managedForm.getToolkit();
-        
-        // Usually we would set a ColumnLayout on body here. However the presence of the
-        // UiTreeBlock forces a GridLayout with one column so we comply with it.
-
-        mOverviewPart = new OverviewInfoPart(body, toolkit, mEditor);
-        mOverviewPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-        managedForm.addPart(mOverviewPart);
-        
-        newManifestExtrasPart(managedForm);
-        
-        OverviewExportPart exportPart = new OverviewExportPart(this, body, toolkit, mEditor);
-        exportPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-        managedForm.addPart(exportPart);
-        
-        mOverviewLinkPart = new OverviewLinksPart(body, toolkit, mEditor);
-        mOverviewLinkPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-        managedForm.addPart(mOverviewLinkPart);
-    }
-
-    private void newManifestExtrasPart(IManagedForm managedForm) {
-        UiElementNode manifest = mEditor.getUiRootNode();
-        mTreeBlock = new UiTreeBlock(mEditor, manifest,
-                true /* autoCreateRoot */,
-                computeManifestExtraFilters(),
-                "Manifest Extras",
-                "Extra manifest elements");
-        mTreeBlock.createContent(managedForm);
-    }
-
-    /**
-     * Changes and refreshes the Application UI node handle by the sub parts.
-     */
-    public void refreshUiApplicationNode() {
-        if (mOverviewPart != null) {
-            mOverviewPart.onSdkChanged();
-        }
-        
-        if (mOverviewLinkPart != null) {
-            mOverviewLinkPart.onSdkChanged();
-        }
-
-        if (mTreeBlock != null) {
-            UiElementNode manifest = mEditor.getUiRootNode();
-            mTreeBlock.changeRootAndDescriptors(manifest,
-                    computeManifestExtraFilters(),
-                    true /* refresh */);
-        }
-    }
-    
-    private ElementDescriptor[] computeManifestExtraFilters() {
-        UiElementNode manifest = mEditor.getUiRootNode();
-        AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
-
-        if (manifestDescriptor == null) {
-            return null;
-        }
-
-        // get the elements we want to exclude
-        HashSet<ElementDescriptor> excludes = new HashSet<ElementDescriptor>();
-        excludes.add(manifestDescriptor.getApplicationElement());
-        excludes.add(manifestDescriptor.getInstrumentationElement());
-        excludes.add(manifestDescriptor.getPermissionElement());
-        excludes.add(manifestDescriptor.getPermissionGroupElement());
-        excludes.add(manifestDescriptor.getPermissionTreeElement());
-        excludes.add(manifestDescriptor.getUsesPermissionElement());
-
-        // walk through the known children of the manifest descriptor and keep what's not excluded
-        ArrayList<ElementDescriptor> descriptorFilters = new ArrayList<ElementDescriptor>();
-        for (ElementDescriptor child : manifest.getDescriptor().getChildren()) {
-            if (!excludes.contains(child)) {
-                descriptorFilters.add(child);
-            }
-        }
-
-        if (descriptorFilters.size() == 0) {
-            return null;
-        }
-        return descriptorFilters.toArray(new ElementDescriptor[descriptorFilters.size()]);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/PermissionPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/PermissionPage.java
deleted file mode 100644
index 8f3e7ff..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/PermissionPage.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-/**
- * Page for permissions settings, part of the AndroidManifest form editor.
- * <p/>
- * Useful reference:
- * <a href="http://www.eclipse.org/articles/Article-Forms/article.html">
- *   http://www.eclipse.org/articles/Article-Forms/article.html</a>
- */
-public final class PermissionPage extends FormPage {
-    /** Page id used for switching tabs programmatically */
-    public final static String PAGE_ID = "permission_page"; //$NON-NLS-1$
-
-    /** Container editor */
-    ManifestEditor mEditor;
-
-    private UiTreeBlock mTreeBlock;
-
-    public PermissionPage(ManifestEditor editor) {
-        super(editor, PAGE_ID, "Permissions");  // tab label, keep it short
-        mEditor = editor;
-    }
-
-    /**
-     * Creates the content in the form hosted in this page.
-     * 
-     * @param managedForm the form hosted in this page.
-     */
-    @Override
-    protected void createFormContent(IManagedForm managedForm) {
-        super.createFormContent(managedForm);
-        ScrolledForm form = managedForm.getForm();
-        form.setText("Android Manifest Permissions");
-        form.setImage(AdtPlugin.getAndroidLogo());
-
-        UiElementNode manifest = mEditor.getUiRootNode();
-        AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
-        
-        ElementDescriptor[] descriptorFilters = null;
-        if (manifestDescriptor != null) {
-            descriptorFilters = new ElementDescriptor[] {
-                    manifestDescriptor.getPermissionElement(),
-                    manifestDescriptor.getUsesPermissionElement(),
-                    manifestDescriptor.getPermissionGroupElement(),
-                    manifestDescriptor.getPermissionTreeElement()
-            };
-        }
-        mTreeBlock = new UiTreeBlock(mEditor, manifest,
-                true /* autoCreateRoot */,
-                descriptorFilters,
-                "Permissions",
-                "List of permissions defined and used by the manifest");
-        mTreeBlock.createContent(managedForm);
-    }
-
-    /**
-     * Changes and refreshes the Application UI node handled by the sub parts.
-     */
-    public void refreshUiNode() {
-        if (mTreeBlock != null) {
-            UiElementNode manifest = mEditor.getUiRootNode();
-            AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
-
-            mTreeBlock.changeRootAndDescriptors(manifest,
-                    new ElementDescriptor[] {
-                        manifestDescriptor.getPermissionElement(),
-                        manifestDescriptor.getUsesPermissionElement(),
-                        manifestDescriptor.getPermissionGroupElement(),
-                        manifestDescriptor.getPermissionTreeElement()
-                    },
-                    true /* refresh */);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuContentAssist.java
deleted file mode 100644
index 59068e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuContentAssist.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.menu;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-/**
- * Content Assist Processor for /res/menu XML files
- */
-class MenuContentAssist extends AndroidContentAssist {
-
-    /**
-     * Constructor for LayoutContentAssist 
-     */
-    public MenuContentAssist() {
-        super(AndroidTargetData.DESCRIPTOR_MENU);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuEditor.java
deleted file mode 100644
index 33a5d3d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuEditor.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.menu;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.sdklib.xml.AndroidXPathFactory;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.FileEditorInput;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Multi-page form editor for /res/menu XML files. 
- */
-public class MenuEditor extends AndroidEditor {
-
-    public static final String ID = AndroidConstants.EDITORS_NAMESPACE + ".menu.MenuEditor"; //$NON-NLS-1$
-
-    /** Root node of the UI element hierarchy */
-    private UiElementNode mUiRootNode;
-
-    /**
-     * Creates the form editor for resources XML files.
-     */
-    public MenuEditor() {
-        super();
-    }
-
-    /**
-     * Returns the root node of the UI element hierarchy, which here is
-     * the "menu" node.
-     */
-    @Override
-    public UiElementNode getUiRootNode() {
-        return mUiRootNode;
-    }
-
-    // ---- Base Class Overrides ----
-
-    /**
-     * Returns whether the "save as" operation is supported by this editor.
-     * <p/>
-     * Save-As is a valid operation for the ManifestEditor since it acts on a
-     * single source file. 
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public boolean isSaveAsAllowed() {
-        return true;
-    }
-
-    /**
-     * Create the various form pages.
-     */
-    @Override
-    protected void createFormPages() {
-        try {
-            addPage(new MenuTreePage(this));
-        } catch (PartInitException e) {
-            AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$
-        }
-        
-     }
-
-    /* (non-java doc)
-     * Change the tab/title name to include the project name.
-     */
-    @Override
-    protected void setInput(IEditorInput input) {
-        super.setInput(input);
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput) input;
-            IFile file = fileInput.getFile();
-            setPartName(String.format("%1$s", file.getName()));
-        }
-    }
-    
-    /**
-     * Processes the new XML Model, which XML root node is given.
-     * 
-     * @param xml_doc The XML document, if available, or null if none exists.
-     */
-    @Override
-    protected void xmlModelChanged(Document xml_doc) {
-        // init the ui root on demand
-        initUiRootNode(false /*force*/);
-
-        mUiRootNode.setXmlDocument(xml_doc);
-        if (xml_doc != null) {
-            ElementDescriptor root_desc = mUiRootNode.getDescriptor();
-            try {
-                XPath xpath = AndroidXPathFactory.newXPath();
-                Node node = (Node) xpath.evaluate("/" + root_desc.getXmlName(),  //$NON-NLS-1$
-                        xml_doc,
-                        XPathConstants.NODE);
-                if (node == null && root_desc.isMandatory()) {
-                    // Create the root element if it doesn't exist yet (for empty new documents)
-                    node = mUiRootNode.createXmlNode();
-                }
-
-                // Refresh the manifest UI node and all its descendants 
-                mUiRootNode.loadFromXmlNode(node);
-                
-                // TODO ? startMonitoringMarkers();
-            } catch (XPathExpressionException e) {
-                AdtPlugin.log(e, "XPath error when trying to find '%s' element in XML.", //$NON-NLS-1$
-                        root_desc.getXmlName());
-            }
-        }
-        
-        super.xmlModelChanged(xml_doc);
-    }
-    
-    /**
-     * Creates the initial UI Root Node, including the known mandatory elements.
-     * @param force if true, a new UiRootNode is recreated even if it already exists.
-     */
-    @Override
-    protected void initUiRootNode(boolean force) {
-        // The root UI node is always created, even if there's no corresponding XML node.
-        if (mUiRootNode == null || force) {
-            Document doc = null;
-            if (mUiRootNode != null) {
-                doc = mUiRootNode.getXmlDocument();
-            }
-            
-            // get the target data from the opened file (and its project)
-            AndroidTargetData data = getTargetData();
-
-            ElementDescriptor desc;
-            if (data == null) {
-                desc = new ElementDescriptor("temp", null /*children*/);
-            } else {
-                desc = data.getMenuDescriptors().getDescriptor();
-            }
-
-            mUiRootNode = desc.createUiNode();
-            mUiRootNode.setEditor(this);
-
-            onDescriptorsChanged(doc);
-        }
-    }
-
-    // ---- Local Methods ----
-
-    /**
-     * Reloads the UI manifest node from the XML, and calls the pages to update.
-     */
-    private void onDescriptorsChanged(Document document) {
-        if (document != null) {
-            mUiRootNode.loadFromXmlNode(document);
-        } else {
-            mUiRootNode.reloadFromXmlNode(mUiRootNode.getXmlNode());
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuSourceViewerConfig.java
deleted file mode 100644
index a2489a9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuSourceViewerConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.menu;
-
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidSourceViewerConfig;
-
-/**
- * Source Viewer Configuration that calls in MenuContentAssist.
- */
-public class MenuSourceViewerConfig extends AndroidSourceViewerConfig {
-
-    public MenuSourceViewerConfig() {
-        super(new MenuContentAssist());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuTreePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuTreePage.java
deleted file mode 100644
index c324802..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuTreePage.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.menu;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-/**
- * Page for the menu form editor.
- */
-public final class MenuTreePage extends FormPage {
-    /** Page id used for switching tabs programmatically */
-    public final static String PAGE_ID = "layout_tree_page"; //$NON-NLS-1$
-
-    /** Container editor */
-    MenuEditor mEditor;
-
-    public MenuTreePage(MenuEditor editor) {
-        super(editor, PAGE_ID, "Layout");  // tab's label, keep it short
-        mEditor = editor;
-    }
-
-    /**
-     * Creates the content in the form hosted in this page.
-     * 
-     * @param managedForm the form hosted in this page.
-     */
-    @Override
-    protected void createFormContent(IManagedForm managedForm) {
-        super.createFormContent(managedForm);
-        ScrolledForm form = managedForm.getForm();
-        form.setText("Android Menu");
-        form.setImage(AdtPlugin.getAndroidLogo());
-
-        UiElementNode rootNode = mEditor.getUiRootNode();
-        UiTreeBlock block = new UiTreeBlock(mEditor, rootNode,
-                true /* autoCreateRoot */,
-                null /* no element filters */,
-                "Menu Elements",
-                "List of all menu elements in this XML file.");
-        block.createContent(managedForm);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java
deleted file mode 100644
index a4763f7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.menu.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo;
-import com.android.sdklib.SdkConstants;
-
-import java.util.ArrayList;
-import java.util.Map;
-
-
-/**
- * Complete description of the menu structure.
- */
-public final class MenuDescriptors implements IDescriptorProvider {
-
-    public static final String MENU_ROOT_ELEMENT = "menu"; //$NON-NLS-1$
-
-    /** The root element descriptor. */
-    private ElementDescriptor mDescriptor = null;
-
-    /** @return the root descriptor. */
-    public ElementDescriptor getDescriptor() {
-        return mDescriptor;
-    }
-    
-    public ElementDescriptor[] getRootElementDescriptors() {
-        return mDescriptor.getChildren();
-    }
-    
-    /**
-     * Updates the document descriptor.
-     * <p/>
-     * It first computes the new children of the descriptor and then updates them
-     * all at once.
-     * 
-     * @param styleMap The map style => attributes from the attrs.xml file
-     */
-    public synchronized void updateDescriptors(Map<String, DeclareStyleableInfo> styleMap) {
-
-        // There are 3 elements: menu, item and group.
-        // The root element MUST be a menu.
-        // A top menu can contain items or group:
-        //  - top groups can contain top items
-        //  - top items can contain sub-menus
-        // A sub menu can contains sub items or sub groups:
-        //  - sub groups can contain sub items
-        //  - sub items cannot contain anything
-        
-        if (mDescriptor == null) {
-            mDescriptor = createElement(styleMap,
-                MENU_ROOT_ELEMENT, // xmlName
-                "Menu", // uiName,
-                null, // TODO SDK URL
-                null, // extraAttribute
-                null, // childrenElements,
-                true /* mandatory */);
-        }
-
-        // -- sub menu can have sub_items, sub_groups but not sub_menus
-
-        ElementDescriptor sub_item = createElement(styleMap,
-                "item", // xmlName //$NON-NLS-1$
-                "Item", // uiName,
-                null, // TODO SDK URL
-                null, // extraAttribute
-                null, // childrenElements,
-                false /* mandatory */);
-
-        ElementDescriptor sub_group = createElement(styleMap,
-                "group", // xmlName //$NON-NLS-1$
-                "Group", // uiName,
-                null, // TODO SDK URL
-                null, // extraAttribute
-                new ElementDescriptor[] { sub_item }, // childrenElements,
-                false /* mandatory */);
-
-        ElementDescriptor sub_menu = createElement(styleMap,
-                MENU_ROOT_ELEMENT, // xmlName //$NON-NLS-1$
-                "Sub-Menu", // uiName,
-                null, // TODO SDK URL
-                null, // extraAttribute
-                new ElementDescriptor[] { sub_item, sub_group }, // childrenElements,
-                true /* mandatory */);
-
-        // -- top menu can have all top groups and top items (which can have sub menus)
-
-        ElementDescriptor top_item = createElement(styleMap,
-                "item", // xmlName //$NON-NLS-1$
-                "Item", // uiName,
-                null, // TODO SDK URL
-                null, // extraAttribute
-                new ElementDescriptor[] { sub_menu }, // childrenElements,
-                false /* mandatory */);
-
-        ElementDescriptor top_group = createElement(styleMap,
-                "group", // xmlName //$NON-NLS-1$
-                "Group", // uiName,
-                null, // TODO SDK URL
-                null, // extraAttribute
-                new ElementDescriptor[] { top_item }, // childrenElements,
-                false /* mandatory */);
-
-        XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor("android", //$NON-NLS-1$
-                SdkConstants.NS_RESOURCES); 
-
-        updateElement(mDescriptor, styleMap, "Menu", xmlns); //$NON-NLS-1$
-        mDescriptor.setChildren(new ElementDescriptor[] { top_item, top_group });
-    }
-
-    /**
-     * Returns a new ElementDescriptor constructed from the information given here
-     * and the javadoc & attributes extracted from the style map if any.
-     */
-    private ElementDescriptor createElement(
-            Map<String, DeclareStyleableInfo> styleMap, 
-            String xmlName, String uiName, String sdkUrl,
-            AttributeDescriptor extraAttribute,
-            ElementDescriptor[] childrenElements, boolean mandatory) {
-
-        ElementDescriptor element = new ElementDescriptor(xmlName, uiName, null, sdkUrl,
-                null, childrenElements, mandatory);
-
-        return updateElement(element, styleMap,
-                getStyleName(xmlName),
-                extraAttribute);
-    }
-    
-    /**
-     * Updates an ElementDescriptor with the javadoc & attributes extracted from the style
-     * map if any.
-     */
-    private ElementDescriptor updateElement(ElementDescriptor element,
-            Map<String, DeclareStyleableInfo> styleMap,
-            String styleName,
-            AttributeDescriptor extraAttribute) {
-        ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>();
-
-        DeclareStyleableInfo style = styleMap != null ? styleMap.get(styleName) : null;
-        if (style != null) {
-            DescriptorsUtils.appendAttributes(descs,
-                    null,   // elementName
-                    SdkConstants.NS_RESOURCES,
-                    style.getAttributes(),
-                    null,   // requiredAttributes
-                    null);  // overrides
-            element.setTooltip(style.getJavaDoc());
-        }
-
-        if (extraAttribute != null) {
-            descs.add(extraAttribute);
-        }
-
-        element.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()]));
-        return element;
-    }
-
-    /**
-     * Returns the style name (i.e. the <declare-styleable> name found in attrs.xml)
-     * for a given XML element name.
-     * <p/>
-     * The rule is that all elements have for style name:
-     * - their xml name capitalized
-     * - a "Menu" prefix, except for <menu> itself which is just "Menu".
-     */
-    private String getStyleName(String xmlName) {
-        String styleName = DescriptorsUtils.capitalize(xmlName);
-
-        // This is NOT the UI Name but the expected internal style name
-        final String MENU_STYLE_BASE_NAME = "Menu"; //$NON-NLS-1$
-        
-        if (!styleName.equals(MENU_STYLE_BASE_NAME)) {        
-            styleName = MENU_STYLE_BASE_NAME + styleName;
-        }
-        return styleName;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java
deleted file mode 100644
index d8b497f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-/**
- * Content Assist Processor for /res/values and /res/drawable XML files
- */
-class ResourcesContentAssist extends AndroidContentAssist {
-
-    /**
-     * Constructor for ResourcesContentAssist 
-     */
-    public ResourcesContentAssist() {
-        super(AndroidTargetData.DESCRIPTOR_RESOURCES);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesEditor.java
deleted file mode 100644
index a48b712..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesEditor.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.sdklib.xml.AndroidXPathFactory;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.FileEditorInput;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Multi-page form editor for /res/values and /res/drawable XML files. 
- */
-public class ResourcesEditor extends AndroidEditor {
-
-    public static final String ID = AndroidConstants.EDITORS_NAMESPACE + ".resources.ResourcesEditor"; //$NON-NLS-1$
-
-    /** Root node of the UI element hierarchy */
-    private UiElementNode mUiResourcesNode;
-
-
-    /**
-     * Creates the form editor for resources XML files.
-     */
-    public ResourcesEditor() {
-        super();
-    }
-
-    /**
-     * Returns the root node of the UI element hierarchy, which
-     * here is the "resources" node.
-     */
-    @Override
-    public UiElementNode getUiRootNode() {
-        return mUiResourcesNode;
-    }
-    
-    // ---- Base Class Overrides ----
-
-    /**
-     * Returns whether the "save as" operation is supported by this editor.
-     * <p/>
-     * Save-As is a valid operation for the ManifestEditor since it acts on a
-     * single source file. 
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public boolean isSaveAsAllowed() {
-        return true;
-    }
-
-    /**
-     * Create the various form pages.
-     */
-    @Override
-    protected void createFormPages() {
-        try {
-            addPage(new ResourcesTreePage(this));
-        } catch (PartInitException e) {
-            AdtPlugin.log(IStatus.ERROR, "Error creating nested page"); //$NON-NLS-1$
-            AdtPlugin.getDefault().getLog().log(e.getStatus());
-        }
-     }
-
-    /* (non-java doc)
-     * Change the tab/title name to include the project name.
-     */
-    @Override
-    protected void setInput(IEditorInput input) {
-        super.setInput(input);
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput) input;
-            IFile file = fileInput.getFile();
-            setPartName(String.format("%1$s",
-                    file.getName()));
-        }
-    }
-    
-    /**
-     * Processes the new XML Model, which XML root node is given.
-     * 
-     * @param xml_doc The XML document, if available, or null if none exists.
-     */
-    @Override
-    protected void xmlModelChanged(Document xml_doc) {
-        // init the ui root on demand
-        initUiRootNode(false /*force*/);
-
-        mUiResourcesNode.setXmlDocument(xml_doc);
-        if (xml_doc != null) {
-            ElementDescriptor resources_desc =
-                    ResourcesDescriptors.getInstance().getElementDescriptor();
-            try {
-                XPath xpath = AndroidXPathFactory.newXPath();
-                Node node = (Node) xpath.evaluate("/" + resources_desc.getXmlName(),  //$NON-NLS-1$
-                        xml_doc,
-                        XPathConstants.NODE);
-                assert node != null && node.getNodeName().equals(resources_desc.getXmlName());
-
-                // Refresh the manifest UI node and all its descendants 
-                mUiResourcesNode.loadFromXmlNode(node);
-            } catch (XPathExpressionException e) {
-                AdtPlugin.log(e, "XPath error when trying to find '%s' element in XML.", //$NON-NLS-1$
-                        resources_desc.getXmlName());
-            }
-        }
-        
-        super.xmlModelChanged(xml_doc);
-    }
-    
-    /**
-     * Creates the initial UI Root Node, including the known mandatory elements.
-     * @param force if true, a new UiRootNode is recreated even if it already exists.
-     */
-    @Override
-    protected void initUiRootNode(boolean force) {
-        // The manifest UI node is always created, even if there's no corresponding XML node.
-        if (mUiResourcesNode == null || force) {
-            ElementDescriptor resources_desc =
-                    ResourcesDescriptors.getInstance().getElementDescriptor();   
-            mUiResourcesNode = resources_desc.createUiNode();
-            mUiResourcesNode.setEditor(this);
-            
-            onDescriptorsChanged();
-        }
-    }
-
-    // ---- Local Methods ----
-
-    private void onDescriptorsChanged() {
-        // nothing to be done, as the descriptor are static for now.
-        // FIXME Update when the descriptors are not static
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesSourceViewerConfig.java
deleted file mode 100644
index a0294b1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesSourceViewerConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources;
-
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidSourceViewerConfig;
-
-/**
- * Source Viewer Configuration that calls in ResourcesContentAssist.
- */
-public class ResourcesSourceViewerConfig extends AndroidSourceViewerConfig {
-
-    public ResourcesSourceViewerConfig() {
-        super(new ResourcesContentAssist());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesTreePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesTreePage.java
deleted file mode 100644
index eac593a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesTreePage.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-import org.eclipse.ui.part.FileEditorInput;
-
-/**
- * Page for instrumentation settings, part of the AndroidManifest form editor.
- */
-public final class ResourcesTreePage extends FormPage {
-    /** Page id used for switching tabs programmatically */
-    public final static String PAGE_ID = "res_tree_page"; //$NON-NLS-1$
-
-    /** Container editor */
-    ResourcesEditor mEditor;
-
-    public ResourcesTreePage(ResourcesEditor editor) {
-        super(editor, PAGE_ID, "Resources");  // tab's label, keep it short
-        mEditor = editor;
-    }
-
-    /**
-     * Creates the content in the form hosted in this page.
-     * 
-     * @param managedForm the form hosted in this page.
-     */
-    @Override
-    protected void createFormContent(IManagedForm managedForm) {
-        super.createFormContent(managedForm);
-        ScrolledForm form = managedForm.getForm();
-        
-        String configText = null;
-        IEditorInput input = mEditor.getEditorInput();
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput)input;
-            IFile iFile = fileInput.getFile();
-            
-            ResourceFolder resFolder = ResourceManager.getInstance().getResourceFolder(iFile);
-            if (resFolder != null) {
-                configText = resFolder.getConfiguration().toDisplayString();
-            }
-        }
-        
-        if (configText != null) {
-            form.setText(String.format("Android Resources (%1$s)", configText));
-        } else {
-            form.setText("Android Resources");
-        }
-
-        form.setImage(AdtPlugin.getAndroidLogo());
-
-        UiElementNode resources = mEditor.getUiRootNode();
-        UiTreeBlock block = new UiTreeBlock(mEditor, resources,
-                true /* autoCreateRoot */,
-                null /* no element filters */,
-                "Resources Elements",
-                "List of all resources elements in this XML file.");
-        block.createContent(managedForm);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ColorValueDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ColorValueDescriptor.java
deleted file mode 100644
index d9be9ca..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ColorValueDescriptor.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextValueDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.resources.uimodel.UiColorValueNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode;
-
-/**
- * Describes a Color XML element value displayed by an {@link UiColorValueNode}.
- */
-public final class ColorValueDescriptor extends TextValueDescriptor {
-
-    public ColorValueDescriptor(String uiName, String tooltip) {
-        super(uiName, tooltip);
-    }
-    
-    /**
-     * @return A new {@link UiResourceAttributeNode} linked to this theme descriptor.
-     */
-    @Override
-    public UiAttributeNode createUiNode(UiElementNode uiParent) {
-        return new UiColorValueNode(this, uiParent);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ItemElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ItemElementDescriptor.java
deleted file mode 100644
index 143bf8f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ItemElementDescriptor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.resources.uimodel.UiItemElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-/**
- * {@link ItemElementDescriptor} is a special version of {@link ElementDescriptor} that
- * uses a specialized {@link UiItemElementNode} for display.
- */
-public class ItemElementDescriptor extends ElementDescriptor {
-
-    /**
-     * Constructs a new {@link ItemElementDescriptor} based on its XML name, UI name,
-     * tooltip, SDK url, attributes list, children list and mandatory.
-     * 
-     * @param xml_name The XML element node name. Case sensitive.
-     * @param ui_name The XML element name for the user interface, typically capitalized.
-     * @param tooltip An optional tooltip. Can be null or empty.
-     * @param sdk_url An optional SKD URL. Can be null or empty.
-     * @param attributes The list of allowed attributes. Can be null or empty.
-     * @param children The list of allowed children. Can be null or empty.
-     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
-     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
-     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
-     *  ceases to exist.
-     */
-    public ItemElementDescriptor(String xml_name, String ui_name,
-            String tooltip, String sdk_url, AttributeDescriptor[] attributes,
-            ElementDescriptor[] children, boolean mandatory) {
-        super(xml_name, ui_name, tooltip, sdk_url, attributes, children, mandatory);
-    }
-
-    @Override
-    public UiElementNode createUiNode() {
-        return new UiItemElementNode(this);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java
deleted file mode 100644
index 8fa8a94..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.FlagAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ListAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextValueDescriptor;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-
-
-/**
- * Complete description of the structure for resources XML files (under res/values/)
- */
-public class ResourcesDescriptors implements IDescriptorProvider {
-
-    // Public attributes names, attributes descriptors and elements descriptors
-
-    public static final String ROOT_ELEMENT = "resources";  //$NON-NLS-1$
-
-    public static final String NAME_ATTR = "name"; //$NON-NLS-1$
-    public static final String TYPE_ATTR = "type"; //$NON-NLS-1$
-
-    private static final ResourcesDescriptors sThis = new ResourcesDescriptors();
-
-    /** The {@link ElementDescriptor} for the root Resources element. */
-    public final ElementDescriptor mResourcesElement;
-
-    public static ResourcesDescriptors getInstance() {
-        return sThis;
-    }
-    
-    /*
-     * @see com.android.ide.eclipse.editors.descriptors.IDescriptorProvider#getRootElementDescriptors()
-     */
-    public ElementDescriptor[] getRootElementDescriptors() {
-        return new ElementDescriptor[] { mResourcesElement };
-    }
-    
-    public ElementDescriptor getDescriptor() {
-        return mResourcesElement;
-    }
-    
-    public ElementDescriptor getElementDescriptor() {
-        return mResourcesElement;
-    }
-    
-    private ResourcesDescriptors() {
-
-        // Common attributes used in many placed
-
-        // Elements
-
-         ElementDescriptor color_element = new ElementDescriptor(
-                "color", //$NON-NLS-1$
-                "Color", 
-                "A @color@ value specifies an RGB value with an alpha channel, which can be used in various places such as specifying a solid color for a Drawable or the color to use for text.  It always begins with a # character and then is followed by the alpha-red-green-blue information in one of the following formats: #RGB, #ARGB, #RRGGBB or #AARRGGBB.",
-                "http://code.google.com/android/reference/available-resources.html#colorvals",  //$NON-NLS-1$
-                new AttributeDescriptor[] {
-                        new TextAttributeDescriptor(NAME_ATTR,
-                                "Name*",
-                                null /* nsUri */,
-                                "The mandatory name used in referring to this color."),
-                        new ColorValueDescriptor(
-                                "Value*",
-                                "A mandatory color value.")
-                },
-                null,  // no child nodes
-                false /* not mandatory */);
-
-         ElementDescriptor string_element = new ElementDescriptor(
-                "string", //$NON-NLS-1$
-                "String", 
-                "@Strings@, with optional simple formatting, can be stored and retrieved as resources. You can add formatting to your string by using three standard HTML tags: b, i, and u. If you use an apostrophe or a quote in your string, you must either escape it or enclose the whole string in the other kind of enclosing quotes.",
-                "http://code.google.com/android/reference/available-resources.html#stringresources",  //$NON-NLS-1$
-                new AttributeDescriptor[] {
-                        new TextAttributeDescriptor(NAME_ATTR,
-                                "Name*",
-                                null /* nsUri */,
-                                "The mandatory name used in referring to this string."),
-                        new TextValueDescriptor(
-                                "Value*",
-                                "A mandatory string value.")
-                },
-                null,  // no child nodes
-                false /* not mandatory */);
-
-         ElementDescriptor item_element = new ItemElementDescriptor(
-                 "item", //$NON-NLS-1$
-                 "Item", 
-                 null,  // TODO find javadoc
-                 null,  // TODO find link to javadoc
-                 new AttributeDescriptor[] {
-                         new TextAttributeDescriptor(NAME_ATTR,
-                                 "Name*",
-                                 null /* nsUri */,
-                                 "The mandatory name used in referring to this resource."),
-                         new ListAttributeDescriptor(TYPE_ATTR,
-                                 "Type*",
-                                 null /* nsUri */,
-                                 "The mandatory type of this resource.",
-                                 ResourceType.getNames()
-                         ),
-                         new FlagAttributeDescriptor("format",
-                                 "Format",
-                                 null /* nsUri */,
-                                 "The optional format of this resource.",
-                                 new String[] {
-                                     "boolean",     //$NON-NLS-1$
-                                     "color",       //$NON-NLS-1$
-                                     "dimension",   //$NON-NLS-1$
-                                     "float",       //$NON-NLS-1$
-                                     "fraction",    //$NON-NLS-1$
-                                     "integer",     //$NON-NLS-1$
-                                     "reference",   //$NON-NLS-1$
-                                     "string"       //$NON-NLS-1$
-                         }),
-                         new TextValueDescriptor(
-                                 "Value",
-                                 "A standard string, hex color value, or reference to any other resource type.")
-                 },
-                 null,  // no child nodes
-                 false /* not mandatory */);
-
-         ElementDescriptor drawable_element = new ElementDescriptor(
-                "drawable", //$NON-NLS-1$
-                "Drawable", 
-                "A @drawable@ defines a rectangle of color. Android accepts color values written in various web-style formats -- a hexadecimal constant in any of the following forms: #RGB, #ARGB, #RRGGBB, #AARRGGBB. Zero in the alpha channel means transparent. The default value is opaque.",
-                "http://code.google.com/android/reference/available-resources.html#colordrawableresources",  //$NON-NLS-1$
-                new AttributeDescriptor[] {
-                        new TextAttributeDescriptor(NAME_ATTR,
-                                "Name*",
-                                null /* nsUri */,
-                                "The mandatory name used in referring to this drawable."),
-                        new TextValueDescriptor(
-                                "Value*",
-                                "A mandatory color value in the form #RGB, #ARGB, #RRGGBB or #AARRGGBB.")
-                },
-                null,  // no child nodes
-                false /* not mandatory */);
-
-         ElementDescriptor dimen_element = new ElementDescriptor(
-                "dimen", //$NON-NLS-1$
-                "Dimension", 
-                "You can create common dimensions to use for various screen elements by defining @dimension@ values in XML. A dimension resource is a number followed by a unit of measurement. Supported units are px (pixels), in (inches), mm (millimeters), pt (points at 72 DPI), dp (density-independent pixels) and sp (scale-independent pixels)",
-                "http://code.google.com/android/reference/available-resources.html#dimension",  //$NON-NLS-1$
-                new AttributeDescriptor[] {
-                        new TextAttributeDescriptor(NAME_ATTR,
-                                "Name*",
-                                null /* nsUri */,
-                                "The mandatory name used in referring to this dimension."),
-                        new TextValueDescriptor(
-                                "Value*",
-                                "A mandatory dimension value is a number followed by a unit of measurement. For example: 10px, 2in, 5sp.")
-                },
-                null,  // no child nodes
-                false /* not mandatory */);
-
-         ElementDescriptor style_element = new ElementDescriptor(
-                "style", //$NON-NLS-1$
-                "Style/Theme", 
-                "Both @styles and themes@ are defined in a style block containing one or more string or numerical values (typically color values), or references to other resources (drawables and so on).",
-                "http://code.google.com/android/reference/available-resources.html#stylesandthemes",  //$NON-NLS-1$
-                new AttributeDescriptor[] {
-                        new TextAttributeDescriptor(NAME_ATTR,
-                                "Name*",
-                                null /* nsUri */,
-                                "The mandatory name used in referring to this theme."),
-                        new TextAttributeDescriptor("parent", // $NON-NLS-1$
-                                "Parent",
-                                null /* nsUri */,
-                                "An optional parent theme. All values from the specified theme will be inherited into this theme. Any values with identical names that you specify will override inherited values."),
-                },
-                new ElementDescriptor[] {
-                    new ElementDescriptor(
-                        "item", //$NON-NLS-1$
-                        "Item", 
-                        "A value to use in this @theme@. It can be a standard string, a hex color value, or a reference to any other resource type.",
-                        "http://code.google.com/android/reference/available-resources.html#stylesandthemes",  //$NON-NLS-1$
-                        new AttributeDescriptor[] {
-                            new TextAttributeDescriptor(NAME_ATTR,
-                                "Name*",
-                                null /* nsUri */,
-                                "The mandatory name used in referring to this item."),
-                            new TextValueDescriptor(
-                                "Value*",
-                                "A mandatory standard string, hex color value, or reference to any other resource type.")
-                        },
-                        null,  // no child nodes
-                        false /* not mandatory */)
-                },
-                false /* not mandatory */);
-
-         ElementDescriptor string_array_element = new ElementDescriptor(
-                 "string-array", //$NON-NLS-1$
-                 "String Array",
-                 "An array of strings. Strings are added as underlying item elements to the array.",
-                 null, // tooltips
-                 new AttributeDescriptor[] {
-                         new TextAttributeDescriptor(NAME_ATTR,
-                                 "Name*",
-                                 null /* nsUri */,
-                                 "The mandatory name used in referring to this string array."),
-                 },
-                 new ElementDescriptor[] {
-                     new ElementDescriptor(
-                         "item", //$NON-NLS-1$
-                         "Item", 
-                         "A string value to use in this string array.",
-                         null, // tooltip
-                         new AttributeDescriptor[] {
-                             new TextValueDescriptor(
-                                 "Value*",
-                                 "A mandatory string.")
-                         },
-                         null,  // no child nodes
-                         false /* not mandatory */)
-                 },
-                 false /* not mandatory */);
-
-         ElementDescriptor integer_array_element = new ElementDescriptor(
-                 "integer-array", //$NON-NLS-1$
-                 "Integer Array",
-                 "An array of integers. Integers are added as underlying item elements to the array.",
-                 null, // tooltips
-                 new AttributeDescriptor[] {
-                         new TextAttributeDescriptor(NAME_ATTR,
-                                 "Name*",
-                                 null /* nsUri */,
-                                 "The mandatory name used in referring to this integer array."),
-                 },
-                 new ElementDescriptor[] {
-                     new ElementDescriptor(
-                         "item", //$NON-NLS-1$
-                         "Item", 
-                         "An integer value to use in this integer array.",
-                         null, // tooltip
-                         new AttributeDescriptor[] {
-                             new TextValueDescriptor(
-                                 "Value*",
-                                 "A mandatory integer.")
-                         },
-                         null,  // no child nodes
-                         false /* not mandatory */)
-                 },
-                 false /* not mandatory */);
-
-         mResourcesElement = new ElementDescriptor(
-                        ROOT_ELEMENT,
-                        "Resources", 
-                        null,
-                        "http://code.google.com/android/reference/available-resources.html",  //$NON-NLS-1$
-                        null,  // no attributes
-                        new ElementDescriptor[] {
-                                string_element,
-                                color_element,
-                                dimen_element,
-                                drawable_element,
-                                style_element,
-                                item_element,
-                                string_array_element,
-                                integer_array_element,
-                        },
-                        true /* mandatory */);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiColorValueNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiColorValueNode.java
deleted file mode 100644
index e788e0b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiColorValueNode.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextValueDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextValueNode;
-
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.regex.Pattern;
-
-/**
- * Displays and edits a color XML element value with a custom validator.
- * <p/>
- * See {@link UiAttributeNode} for more information.
- */
-public class UiColorValueNode extends UiTextValueNode {
-
-    /** Accepted RGBA formats are one of #RGB, #ARGB, #RRGGBB or #AARRGGBB. */
-    private static final Pattern RGBA_REGEXP = Pattern.compile(
-            "#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})"); //$NON-NLS-1$
-    
-    public UiColorValueNode(TextValueDescriptor attributeDescriptor, UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-
-    /* (non-java doc)
-     * 
-     * Add a modify listener that will check colors have the proper format,
-     * that is one of #RGB, #ARGB, #RRGGBB or #AARRGGBB.
-     */
-    @Override
-    protected void onAddValidators(final Text text) {
-        ModifyListener listener = new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                String color = text.getText();
-                if (RGBA_REGEXP.matcher(color).matches()) {
-                    getManagedForm().getMessageManager().removeMessage(text, text);
-                } else {
-                    getManagedForm().getMessageManager().addMessage(text,
-                            "Accepted color formats are one of #RGB, #ARGB, #RRGGBB or #AARRGGBB.",
-                            null /* data */, IMessageProvider.ERROR, text);
-                }
-            }
-        };
-
-        text.addModifyListener(listener);
-
-        // Make sure the validator removes its message(s) when the widget is disposed
-        text.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                getManagedForm().getMessageManager().removeMessage(text, text);
-            }
-        });
-
-        // Finally call the validator once to make sure the initial value is processed
-        listener.modifyText(null);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiItemElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiItemElementNode.java
deleted file mode 100644
index 1bb0f58..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiItemElementNode.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ItemElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * {@link UiItemElementNode} is apecial version of {@link UiElementNode} that 
- * customizes the element display to include the item type attribute if present.
- */
-public class UiItemElementNode extends UiElementNode {
-
-    /**
-     * Creates a new {@link UiElementNode} described by a given {@link ItemElementDescriptor}.
-     * 
-     * @param elementDescriptor The {@link ItemElementDescriptor} for the XML node. Cannot be null.
-     */
-    public UiItemElementNode(ItemElementDescriptor elementDescriptor) {
-        super(elementDescriptor);
-    }
-
-    @Override
-    public String getShortDescription() {
-        Node xmlNode = getXmlNode();
-        if (xmlNode != null && xmlNode instanceof Element && xmlNode.hasAttributes()) {
-
-            Element elem = (Element) xmlNode;
-            String type = elem.getAttribute(ResourcesDescriptors.TYPE_ATTR);
-            String name = elem.getAttribute(ResourcesDescriptors.NAME_ATTR);
-            if (type != null && name != null && type.length() > 0 && name.length() > 0) {
-                type = DescriptorsUtils.capitalize(type);
-                return String.format("%1$s (%2$s %3$s)", name, type, getDescriptor().getUiName());
-            }
-        }
-
-        return super.getShortDescription();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/EditableDialogCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/EditableDialogCellEditor.java
deleted file mode 100644
index 0a600f7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/EditableDialogCellEditor.java
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.jface.viewers.DialogCellEditor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusAdapter;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Text;
-
-import java.text.MessageFormat;
-
-/**
- * Custom DialogCellEditor, replacing the Label with an editable {@link Text} widget.
- * <p/>Also set the button to {@link SWT#FLAT} to make sure it looks good on MacOS X.
- * <p/>Most of the code comes from TextCellEditor.
- */
-public abstract class EditableDialogCellEditor extends DialogCellEditor {
-    
-    private Text text; 
-    
-    private ModifyListener modifyListener;
-
-    /**
-     * State information for updating action enablement
-     */
-    private boolean isSelection = false;
-
-    private boolean isDeleteable = false;
-
-    private boolean isSelectable = false;
-    
-    EditableDialogCellEditor(Composite parent) {
-        super(parent);
-    }
-
-    /*
-     * Re-implement this method only to properly set the style in the button, or it won't look
-     * good in MacOS X
-     */
-    @Override
-    protected Button createButton(Composite parent) {
-        Button result = new Button(parent, SWT.DOWN | SWT.FLAT);
-        result.setText("..."); //$NON-NLS-1$
-        return result;
-    }
-
-    
-    @Override
-    protected Control createContents(Composite cell) {
-        text = new Text(cell, SWT.SINGLE);
-        text.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetDefaultSelected(SelectionEvent e) {
-                handleDefaultSelection(e);
-            }
-        });
-        text.addKeyListener(new KeyAdapter() {
-            // hook key pressed - see PR 14201  
-            @Override
-            public void keyPressed(KeyEvent e) {
-                keyReleaseOccured(e);
-
-                // as a result of processing the above call, clients may have
-                // disposed this cell editor
-                if ((getControl() == null) || getControl().isDisposed()) {
-                    return;
-                }
-                checkSelection(); // see explanation below
-                checkDeleteable();
-                checkSelectable();
-            }
-        });
-        text.addTraverseListener(new TraverseListener() {
-            public void keyTraversed(TraverseEvent e) {
-                if (e.detail == SWT.TRAVERSE_ESCAPE
-                        || e.detail == SWT.TRAVERSE_RETURN) {
-                    e.doit = false;
-                }
-            }
-        });
-        // We really want a selection listener but it is not supported so we
-        // use a key listener and a mouse listener to know when selection changes
-        // may have occurred
-        text.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mouseUp(MouseEvent e) {
-                checkSelection();
-                checkDeleteable();
-                checkSelectable();
-            }
-        });
-        text.addFocusListener(new FocusAdapter() {
-            @Override
-            public void focusLost(FocusEvent e) {
-                EditableDialogCellEditor.this.focusLost();
-            }
-        });
-        text.setFont(cell.getFont());
-        text.setBackground(cell.getBackground());
-        text.setText("");//$NON-NLS-1$
-        text.addModifyListener(getModifyListener());
-        return text;
-    }
-
-   /**
-     * Checks to see if the "deletable" state (can delete/
-     * nothing to delete) has changed and if so fire an
-     * enablement changed notification.
-     */
-    private void checkDeleteable() {
-        boolean oldIsDeleteable = isDeleteable;
-        isDeleteable = isDeleteEnabled();
-        if (oldIsDeleteable != isDeleteable) {
-            fireEnablementChanged(DELETE);
-        }
-    }
-
-    /**
-     * Checks to see if the "selectable" state (can select)
-     * has changed and if so fire an enablement changed notification.
-     */
-    private void checkSelectable() {
-        boolean oldIsSelectable = isSelectable;
-        isSelectable = isSelectAllEnabled();
-        if (oldIsSelectable != isSelectable) {
-            fireEnablementChanged(SELECT_ALL);
-        }
-    }
-
-    /**
-     * Checks to see if the selection state (selection /
-     * no selection) has changed and if so fire an
-     * enablement changed notification.
-     */
-    private void checkSelection() {
-        boolean oldIsSelection = isSelection;
-        isSelection = text.getSelectionCount() > 0;
-        if (oldIsSelection != isSelection) {
-            fireEnablementChanged(COPY);
-            fireEnablementChanged(CUT);
-        }
-    }
-
-    /* (non-Javadoc)
-     * Method declared on CellEditor.
-     */
-    @Override
-    protected void doSetFocus() {
-        if (text != null) {
-            text.selectAll();
-            text.setFocus();
-            checkSelection();
-            checkDeleteable();
-            checkSelectable();
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.jface.viewers.DialogCellEditor#updateContents(java.lang.Object)
-     */
-    @Override
-    protected void updateContents(Object value) {
-        Assert.isTrue(text != null && (value == null || (value instanceof String)));
-        if (value != null) {
-            text.removeModifyListener(getModifyListener());
-            text.setText((String) value);
-            text.addModifyListener(getModifyListener());
-        }
-    }
-    
-    /**
-     * The <code>TextCellEditor</code> implementation of
-     * this <code>CellEditor</code> framework method returns
-     * the text string.
-     *
-     * @return the text string
-     */
-    @Override
-    protected Object doGetValue() {
-        return text.getText();
-    }
-
-
-    /**
-     * Processes a modify event that occurred in this text cell editor.
-     * This framework method performs validation and sets the error message
-     * accordingly, and then reports a change via <code>fireEditorValueChanged</code>.
-     * Subclasses should call this method at appropriate times. Subclasses
-     * may extend or reimplement.
-     *
-     * @param e the SWT modify event
-     */
-    protected void editOccured(ModifyEvent e) {
-        String value = text.getText();
-        if (value == null) {
-            value = "";//$NON-NLS-1$
-        }
-        Object typedValue = value;
-        boolean oldValidState = isValueValid();
-        boolean newValidState = isCorrect(typedValue);
-
-        if (!newValidState) {
-            // try to insert the current value into the error message.
-            setErrorMessage(MessageFormat.format(getErrorMessage(),
-                    new Object[] { value }));
-        }
-        valueChanged(oldValidState, newValidState);
-    }
-
-    /**
-     * Return the modify listener.
-     */
-    private ModifyListener getModifyListener() {
-        if (modifyListener == null) {
-            modifyListener = new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    editOccured(e);
-                }
-            };
-        }
-        return modifyListener;
-    }
-
-    /**
-     * Handles a default selection event from the text control by applying the editor
-     * value and deactivating this cell editor.
-     * 
-     * @param event the selection event
-     * 
-     * @since 3.0
-     */
-    protected void handleDefaultSelection(SelectionEvent event) {
-        // same with enter-key handling code in keyReleaseOccured(e);
-        fireApplyEditorValue();
-        deactivate();
-    }
-
-    /**
-     * The <code>TextCellEditor</code>  implementation of this 
-     * <code>CellEditor</code> method returns <code>true</code> if 
-     * the current selection is not empty.
-     */
-    @Override
-    public boolean isCopyEnabled() {
-        if (text == null || text.isDisposed()) {
-            return false;
-        }
-        return text.getSelectionCount() > 0;
-    }
-
-    /**
-     * The <code>TextCellEditor</code>  implementation of this 
-     * <code>CellEditor</code> method returns <code>true</code> if 
-     * the current selection is not empty.
-     */
-    @Override
-    public boolean isCutEnabled() {
-        if (text == null || text.isDisposed()) {
-            return false;
-        }
-        return text.getSelectionCount() > 0;
-    }
-
-    /**
-     * The <code>TextCellEditor</code>  implementation of this 
-     * <code>CellEditor</code> method returns <code>true</code>
-     * if there is a selection or if the caret is not positioned 
-     * at the end of the text.
-     */
-    @Override
-    public boolean isDeleteEnabled() {
-        if (text == null || text.isDisposed()) {
-            return false;
-        }
-        return text.getSelectionCount() > 0
-                || text.getCaretPosition() < text.getCharCount();
-    }
-
-    /**
-     * The <code>TextCellEditor</code>  implementation of this 
-     * <code>CellEditor</code> method always returns <code>true</code>.
-     */
-    @Override
-    public boolean isPasteEnabled() {
-        if (text == null || text.isDisposed()) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Check if save all is enabled
-     * @return true if it is 
-     */
-    public boolean isSaveAllEnabled() {
-        if (text == null || text.isDisposed()) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Returns <code>true</code> if this cell editor is
-     * able to perform the select all action.
-     * <p>
-     * This default implementation always returns 
-     * <code>false</code>.
-     * </p>
-     * <p>
-     * Subclasses may override
-     * </p>
-     * @return <code>true</code> if select all is possible,
-     *  <code>false</code> otherwise
-     */
-    @Override
-    public boolean isSelectAllEnabled() {
-        if (text == null || text.isDisposed()) {
-            return false;
-        }
-        return text.getCharCount() > 0;
-    }
-
-    /**
-     * Processes a key release event that occurred in this cell editor.
-     * <p>
-     * The <code>TextCellEditor</code> implementation of this framework method 
-     * ignores when the RETURN key is pressed since this is handled in 
-     * <code>handleDefaultSelection</code>.
-     * An exception is made for Ctrl+Enter for multi-line texts, since
-     * a default selection event is not sent in this case. 
-     * </p>
-     *
-     * @param keyEvent the key event
-     */
-    @Override
-    protected void keyReleaseOccured(KeyEvent keyEvent) {
-        if (keyEvent.character == '\r') { // Return key
-            // Enter is handled in handleDefaultSelection.
-            // Do not apply the editor value in response to an Enter key event
-            // since this can be received from the IME when the intent is -not-
-            // to apply the value.  
-            // See bug 39074 [CellEditors] [DBCS] canna input mode fires bogus event from Text Control
-            //
-            // An exception is made for Ctrl+Enter for multi-line texts, since
-            // a default selection event is not sent in this case. 
-            if (text != null && !text.isDisposed()
-                    && (text.getStyle() & SWT.MULTI) != 0) {
-                if ((keyEvent.stateMask & SWT.CTRL) != 0) {
-                    super.keyReleaseOccured(keyEvent);
-                }
-            }
-            return;
-        }
-        super.keyReleaseOccured(keyEvent);
-    }
-
-    /**
-     * The <code>TextCellEditor</code> implementation of this
-     * <code>CellEditor</code> method copies the
-     * current selection to the clipboard. 
-     */
-    @Override
-    public void performCopy() {
-        text.copy();
-    }
-
-    /**
-     * The <code>TextCellEditor</code> implementation of this
-     * <code>CellEditor</code> method cuts the
-     * current selection to the clipboard. 
-     */
-    @Override
-    public void performCut() {
-        text.cut();
-        checkSelection();
-        checkDeleteable();
-        checkSelectable();
-    }
-
-    /**
-     * The <code>TextCellEditor</code> implementation of this
-     * <code>CellEditor</code> method deletes the
-     * current selection or, if there is no selection,
-     * the character next character from the current position. 
-     */
-    @Override
-    public void performDelete() {
-        if (text.getSelectionCount() > 0) {
-            // remove the contents of the current selection
-            text.insert(""); //$NON-NLS-1$
-        } else {
-            // remove the next character
-            int pos = text.getCaretPosition();
-            if (pos < text.getCharCount()) {
-                text.setSelection(pos, pos + 1);
-                text.insert(""); //$NON-NLS-1$
-            }
-        }
-        checkSelection();
-        checkDeleteable();
-        checkSelectable();
-    }
-
-    /**
-     * The <code>TextCellEditor</code> implementation of this
-     * <code>CellEditor</code> method pastes the
-     * the clipboard contents over the current selection. 
-     */
-    @Override
-    public void performPaste() {
-        text.paste();
-        checkSelection();
-        checkDeleteable();
-        checkSelectable();
-    }
-
-    /**
-     * The <code>TextCellEditor</code> implementation of this
-     * <code>CellEditor</code> method selects all of the
-     * current text. 
-     */
-    @Override
-    public void performSelectAll() {
-        text.selectAll();
-        checkSelection();
-        checkDeleteable();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ErrorImageComposite.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ErrorImageComposite.java
deleted file mode 100644
index a70cf90..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ErrorImageComposite.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import org.eclipse.jface.resource.CompositeImageDescriptor;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.DecorationOverlayIcon;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * ImageDescriptor that adds a error marker.
- * Based on {@link DecorationOverlayIcon} only available in Eclipse 3.3
- */
-public class ErrorImageComposite extends CompositeImageDescriptor {
-
-    private Image mBaseImage;
-    private ImageDescriptor mErrorImageDescriptor;
-    private Point mSize;
-
-    public ErrorImageComposite(Image baseImage) {
-        mBaseImage = baseImage;
-        mErrorImageDescriptor = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
-                ISharedImages.IMG_OBJS_ERROR_TSK);
-        mSize = new Point(baseImage.getBounds().width, baseImage.getBounds().height);
-    }
-    
-    @Override
-    protected void drawCompositeImage(int width, int height) {
-        ImageData baseData = mBaseImage.getImageData();
-        drawImage(baseData, 0, 0);
-
-        ImageData overlayData = mErrorImageDescriptor.getImageData();
-        if (overlayData.width == baseData.width && baseData.height == baseData.height) {
-            overlayData = overlayData.scaledTo(14, 14);
-            drawImage(overlayData, -3, mSize.y - overlayData.height + 3);
-        } else {
-            drawImage(overlayData, 0, mSize.y - overlayData.height);
-        }
-    }
-
-    @Override
-    protected Point getSize() {
-        return mSize;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/FlagValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/FlagValueCellEditor.java
deleted file mode 100644
index 2a1bc36..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/FlagValueCellEditor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiFlagAttributeNode;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/**
- * DialogCellEditor able to receive a {@link UiFlagAttributeNode} in the {@link #setValue(Object)}
- * method.
- * <p/>The dialog box opened is the same as the one in the ui created by
- * {@link UiFlagAttributeNode#createUiControl(Composite, org.eclipse.ui.forms.IManagedForm)}
- */
-public class FlagValueCellEditor extends EditableDialogCellEditor {
-    
-    private UiFlagAttributeNode mUiFlagAttribute;
-
-    public FlagValueCellEditor(Composite parent) {
-        super(parent);
-    }
-    
-    @Override
-    protected Object openDialogBox(Control cellEditorWindow) {
-        if (mUiFlagAttribute != null) {
-            String currentValue = (String)getValue();
-            return mUiFlagAttribute.showDialog(cellEditorWindow.getShell(), currentValue);
-        }
-        
-        return null;
-    }
-    
-    @Override
-    protected void doSetValue(Object value) {
-        if (value instanceof UiFlagAttributeNode) {
-            mUiFlagAttribute = (UiFlagAttributeNode)value;
-            super.doSetValue(mUiFlagAttribute.getCurrentValue());
-            return;
-        }
-        
-        super.doSetValue(value);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ListValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ListValueCellEditor.java
deleted file mode 100644
index 0c780a8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ListValueCellEditor.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
-
-import org.eclipse.jface.viewers.ComboBoxCellEditor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CCombo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/**
- * ComboBoxCellEditor able to receive a {@link UiListAttributeNode} in the {@link #setValue(Object)}
- * method, and returning a {@link String} in {@link #getValue()} instead of an {@link Integer}.
- */
-public class ListValueCellEditor extends ComboBoxCellEditor {
-    private String[] mItems;
-    private CCombo mCombo;
-    
-    public ListValueCellEditor(Composite parent) {
-        super(parent, new String[0], SWT.DROP_DOWN);
-    }
-    
-    @Override
-    protected Control createControl(Composite parent) {
-        mCombo = (CCombo) super.createControl(parent);
-        return mCombo;
-    }
-    
-    @Override
-    protected void doSetValue(Object value) {
-        if (value instanceof UiListAttributeNode) {
-            UiListAttributeNode uiListAttribute = (UiListAttributeNode)value;
-            
-            // set the possible values in the combo
-            String[] items = uiListAttribute.getPossibleValues(null);
-            mItems = new String[items.length];
-            System.arraycopy(items, 0, mItems, 0, items.length);
-            setItems(mItems);
-            
-            // now edit the current value of the attribute
-            String attrValue = uiListAttribute.getCurrentValue();
-            mCombo.setText(attrValue);
-            
-            return;
-        }
-        
-        // default behavior
-        super.doSetValue(value);
-    }
-    
-    @Override
-    protected Object doGetValue() {
-        String comboText = mCombo.getText();
-        if (comboText == null) {
-            return ""; //$NON-NLS-1$
-        }
-        return comboText;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ResourceValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ResourceValueCellEditor.java
deleted file mode 100644
index 8efe294..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ResourceValueCellEditor.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiFlagAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/**
- * DialogCellEditor able to receive a {@link UiFlagAttributeNode} in the {@link #setValue(Object)}
- * method.
- * <p/>The dialog box opened is the same as the one in the ui created by
- * {@link UiFlagAttributeNode#createUiControl(Composite, org.eclipse.ui.forms.IManagedForm)}
- */
-public class ResourceValueCellEditor extends EditableDialogCellEditor {
-
-    private UiResourceAttributeNode mUiResourceAttribute;
-
-    public ResourceValueCellEditor(Composite parent) {
-        super(parent);
-    }
-
-    @Override
-    protected Object openDialogBox(Control cellEditorWindow) {
-        if (mUiResourceAttribute != null) {
-            String currentValue = (String)getValue();
-            return mUiResourceAttribute.showDialog(cellEditorWindow.getShell(), currentValue);
-        }
-        
-        return null;
-    }
-    
-    @Override
-    protected void doSetValue(Object value) {
-        if (value instanceof UiResourceAttributeNode) {
-            mUiResourceAttribute = (UiResourceAttributeNode)value;
-            super.doSetValue(mUiResourceAttribute.getCurrentValue());
-            return;
-        }
-        
-        super.doSetValue(value);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java
deleted file mode 100644
index 69c21e6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-
-import org.eclipse.jface.text.DefaultInformationControl;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseTrackListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.SectionPart;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.eclipse.ui.forms.widgets.TableWrapLayout;
-
-import java.lang.reflect.Method;
-
-/**
- * Helper for the AndroidManifest form editor.
- * 
- * Helps create a new SectionPart with sensible default parameters,
- * create default layout or add typical widgets.
- * 
- * IMPORTANT: This is NOT a generic class. It makes a lot of assumptions on the
- * UI as used by the form editor for the AndroidManifest.
- * 
- * TODO: Consider moving to a common package.
- */
-public final class SectionHelper {
-
-    /**
-     * Utility class that derives from SectionPart, constructs the Section with
-     * sensible defaults (with a title and a description) and provide some shorthand
-     * methods for creating typically UI (label and text, form text.)
-     */
-    static public class ManifestSectionPart extends SectionPart {
-
-        /**
-         * Construct a SectionPart that uses a title bar and a description.
-         * It's up to the caller to call setText() and setDescription().
-         * <p/>
-         * The section style includes a description and a title bar by default.
-         * 
-         * @param body The parent (e.g. FormPage body)
-         * @param toolkit Form Toolkit
-         */
-        public ManifestSectionPart(Composite body, FormToolkit toolkit) {
-            this(body, toolkit, 0, false);
-        }
-
-        /**
-         * Construct a SectionPart that uses a title bar and a description.
-         * It's up to the caller to call setText() and setDescription().
-         * <p/>
-         * The section style includes a description and a title bar by default.
-         * You can add extra styles, like Section.TWISTIE.
-         * 
-         * @param body The parent (e.g. FormPage body).
-         * @param toolkit Form Toolkit.
-         * @param extra_style Extra styles (on top of description and title bar).
-         * @param use_description True if the Section.DESCRIPTION style should be added.
-         */
-        public ManifestSectionPart(Composite body, FormToolkit toolkit,
-                int extra_style, boolean use_description) {
-            super(body, toolkit, extra_style |
-                    Section.TITLE_BAR |
-                    (use_description ? Section.DESCRIPTION : 0));
-        }
-
-        // Create non-static methods of helpers just for convenience
-        
-        /**
-         * Creates a new composite with a TableWrapLayout set with a given number of columns.
-         * 
-         * If the parent composite is a Section, the new composite is set as a client.
-         * 
-         * @param toolkit Form Toolkit
-         * @param numColumns Desired number of columns.
-         * @return The new composite.
-         */
-        public Composite createTableLayout(FormToolkit toolkit, int numColumns) {
-            return SectionHelper.createTableLayout(getSection(), toolkit, numColumns);
-        }
-
-        /**
-         * Creates a label widget.
-         * If the parent layout if a TableWrapLayout, maximize it to span over all columns.
-         * 
-         * @param parent The parent (e.g. composite from CreateTableLayout())
-         * @param toolkit Form Toolkit
-         * @param label The string for the label.
-         * @param tooltip An optional tooltip for the label and text. Can be null.
-         * @return The new created label 
-         */
-        public Label createLabel(Composite parent, FormToolkit toolkit, String label,
-                String tooltip) {
-            return SectionHelper.createLabel(parent, toolkit, label, tooltip);
-        }
-
-        /**
-         * Creates two widgets: a label and a text field.
-         * 
-         * This expects the parent composite to have a TableWrapLayout with 2 columns.
-         * 
-         * @param parent The parent (e.g. composite from CreateTableLayout())
-         * @param toolkit Form Toolkit
-         * @param label The string for the label.
-         * @param value The initial value of the text field. Can be null.
-         * @param tooltip An optional tooltip for the label and text. Can be null.
-         * @return The new created Text field (the label is not returned) 
-         */
-        public Text createLabelAndText(Composite parent, FormToolkit toolkit, String label,
-                String value, String tooltip) {
-            return SectionHelper.createLabelAndText(parent, toolkit, label, value, tooltip);
-        }
-
-        /**
-         * Creates a FormText widget.
-         * 
-         * This expects the parent composite to have a TableWrapLayout with 2 columns.
-         * 
-         * @param parent The parent (e.g. composite from CreateTableLayout())
-         * @param toolkit Form Toolkit
-         * @param isHtml True if the form text will contain HTML that must be interpreted as
-         *               rich text (i.e. parse tags & expand URLs).
-         * @param label The string for the label.
-         * @param setupLayoutData indicates whether the created form text receives a TableWrapData
-         * through the setLayoutData method. In some case, creating it will make the table parent
-         * huge, which we don't want.
-         * @return The new created FormText.
-         */
-        public FormText createFormText(Composite parent, FormToolkit toolkit, boolean isHtml,
-                String label, boolean setupLayoutData) {
-            return SectionHelper.createFormText(parent, toolkit, isHtml, label, setupLayoutData);
-        }
-
-        /**
-         * Forces the section to recompute its layout and redraw.
-         * This is needed after the content of the section has been changed at runtime.
-         */
-        public void layoutChanged() {
-            Section section = getSection();
-
-            // Calls getSection().reflow(), which is the same that Section calls
-            // when the expandable state is changed and the height changes.
-            // Since this is protected, some reflection is needed to invoke it.
-            try {
-                Method reflow;
-                reflow = section.getClass().getDeclaredMethod("reflow", (Class<?>[])null);
-                reflow.setAccessible(true);
-                reflow.invoke(section);
-            } catch (Exception e) {
-                AdtPlugin.log(e, "Error when invoking Section.reflow");
-            }
-            
-            section.layout(true /* changed */, true /* all */);
-        }
-    }
-    
-    /**
-     * Creates a new composite with a TableWrapLayout set with a given number of columns.
-     * 
-     * If the parent composite is a Section, the new composite is set as a client.
-     * 
-     * @param composite The parent (e.g. a Section or SectionPart)
-     * @param toolkit Form Toolkit
-     * @param numColumns Desired number of columns.
-     * @return The new composite.
-     */
-    static public Composite createTableLayout(Composite composite, FormToolkit toolkit,
-            int numColumns) {
-        Composite table = toolkit.createComposite(composite);
-        TableWrapLayout layout = new TableWrapLayout();
-        layout.numColumns = numColumns;
-        table.setLayout(layout);
-        toolkit.paintBordersFor(table);
-        if (composite instanceof Section) {
-            ((Section) composite).setClient(table);
-        }
-        return table;
-    }
-
-    /**
-     * Creates a new composite with a GridLayout set with a given number of columns.
-     * 
-     * If the parent composite is a Section, the new composite is set as a client.
-     * 
-     * @param composite The parent (e.g. a Section or SectionPart)
-     * @param toolkit Form Toolkit
-     * @param numColumns Desired number of columns.
-     * @return The new composite.
-     */
-    static public Composite createGridLayout(Composite composite, FormToolkit toolkit,
-            int numColumns) {
-        Composite grid = toolkit.createComposite(composite);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = numColumns;
-        grid.setLayout(layout);
-        toolkit.paintBordersFor(grid);
-        if (composite instanceof Section) {
-            ((Section) composite).setClient(grid);
-        }
-        return grid;
-    }
-
-    /**
-     * Creates two widgets: a label and a text field.
-     * 
-     * This expects the parent composite to have a TableWrapLayout with 2 columns.
-     * 
-     * @param parent The parent (e.g. composite from CreateTableLayout())
-     * @param toolkit Form Toolkit
-     * @param label_text The string for the label.
-     * @param value The initial value of the text field. Can be null.
-     * @param tooltip An optional tooltip for the label and text. Can be null.
-     * @return The new created Text field (the label is not returned) 
-     */
-    static public Text createLabelAndText(Composite parent, FormToolkit toolkit, String label_text,
-            String value, String tooltip) {
-        Label label = toolkit.createLabel(parent, label_text);
-        label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
-        Text text = toolkit.createText(parent, value);
-        text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
-
-        addControlTooltip(label, tooltip);
-        return text;
-    }
-
-    /**
-     * Creates a label widget.
-     * If the parent layout if a TableWrapLayout, maximize it to span over all columns.
-     * 
-     * @param parent The parent (e.g. composite from CreateTableLayout())
-     * @param toolkit Form Toolkit
-     * @param label_text The string for the label.
-     * @param tooltip An optional tooltip for the label and text. Can be null.
-     * @return The new created label 
-     */
-    static public Label createLabel(Composite parent, FormToolkit toolkit, String label_text,
-            String tooltip) {
-        Label label = toolkit.createLabel(parent, label_text);
-
-        TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB);
-        if (parent.getLayout() instanceof TableWrapLayout) {
-            twd.colspan = ((TableWrapLayout) parent.getLayout()).numColumns;
-        }
-        label.setLayoutData(twd);
-
-        addControlTooltip(label, tooltip);
-        return label;
-    }
-
-    /**
-     * Associates a tooltip with a control.
-     * 
-     * This mirrors the behavior from org.eclipse.pde.internal.ui.editor.text.PDETextHover
-     * 
-     * @param control The control to which associate the tooltip.
-     * @param tooltip The tooltip string. Can use \n for multi-lines. Will not display if null.
-     */
-    static public void addControlTooltip(final Control control, String tooltip) {
-        if (control == null || tooltip == null || tooltip.length() == 0) {
-            return;
-        }
-        
-        // Some kinds of controls already properly implement tooltip display. 
-        if (control instanceof Button) {
-            control.setToolTipText(tooltip);
-            return;
-        }
-
-        control.setToolTipText(null);
-
-        final DefaultInformationControl ic = new DefaultInformationControl(control.getShell());
-        ic.setInformation(tooltip);
-        Point sz = ic.computeSizeHint();
-        ic.setSize(sz.x, sz.y);
-        ic.setVisible(false); // initially hidden
-        
-        control.addMouseTrackListener(new MouseTrackListener() {
-            public void mouseEnter(MouseEvent e) {
-            }
-
-            public void mouseExit(MouseEvent e) {
-                ic.setVisible(false);
-            }
-
-            public void mouseHover(MouseEvent e) {
-                ic.setLocation(control.toDisplay(10, 25));  // same offset as in PDETextHover
-                ic.setVisible(true);
-            }
-        });
-    }
-
-    /**
-     * Creates a FormText widget.
-     * 
-     * This expects the parent composite to have a TableWrapLayout with 2 columns.
-     * 
-     * @param parent The parent (e.g. composite from CreateTableLayout())
-     * @param toolkit Form Toolkit
-     * @param isHtml True if the form text will contain HTML that must be interpreted as
-     *               rich text (i.e. parse tags & expand URLs).
-     * @param label The string for the label.
-     * @param setupLayoutData indicates whether the created form text receives a TableWrapData
-     * through the setLayoutData method. In some case, creating it will make the table parent
-     * huge, which we don't want.
-     * @return The new created FormText.
-     */
-    static public FormText createFormText(Composite parent, FormToolkit toolkit,
-            boolean isHtml, String label, boolean setupLayoutData) {
-        FormText text = toolkit.createFormText(parent, true /* track focus */);
-        if (setupLayoutData) {
-            TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB);
-            twd.maxWidth = AndroidEditor.TEXT_WIDTH_HINT;
-            if (parent.getLayout() instanceof TableWrapLayout) {
-                twd.colspan = ((TableWrapLayout) parent.getLayout()).numColumns;
-            }
-            text.setLayoutData(twd);
-        }
-        text.setWhitespaceNormalized(true);
-        text.setText(label, isHtml /* parseTags */, isHtml /* expandURLs */);
-        return text;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/TextValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/TextValueCellEditor.java
deleted file mode 100644
index 3750c34..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/TextValueCellEditor.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-
-import org.eclipse.jface.viewers.TextCellEditor;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * TextCellEditor able to receive a {@link UiAttributeNode} in the {@link #setValue(Object)}
- * method.
- */
-public class TextValueCellEditor extends TextCellEditor {
-    
-    public TextValueCellEditor(Composite parent) {
-        super(parent);
-    }
-
-    @Override
-    protected void doSetValue(Object value) {
-        if (value instanceof UiAttributeNode) {
-            super.doSetValue(((UiAttributeNode)value).getCurrentValue());
-            return;
-        }
-        
-        super.doSetValue(value);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/UiElementPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/UiElementPart.java
deleted file mode 100644
index 1ad9525..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/UiElementPart.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * Generic page's section part that displays all attributes of a given {@link UiElementNode}.
- * <p/>
- * This part is designed to be displayed in a page that has a table column layout.
- * It is linked to a specific {@link UiElementNode} and automatically displays all of its
- * attributes, manages its dirty state and commits the attributes when necessary.
- * <p/>
- * No derivation is needed unless the UI or workflow needs to be extended.
- */
-public class UiElementPart extends ManifestSectionPart {
-
-    /** A reference to the container editor */
-    private ManifestEditor mEditor;
-    /** The {@link UiElementNode} manipulated by this SectionPart. It can be null. */
-    private UiElementNode mUiElementNode;
-    /** Table that contains all the attributes */
-    private Composite mTable;
-
-    public UiElementPart(Composite body, FormToolkit toolkit, ManifestEditor editor,
-            UiElementNode uiElementNode, String sectionTitle, String sectionDescription,
-            int extra_style) {
-        super(body, toolkit, extra_style, sectionDescription != null);
-        mEditor = editor;
-        mUiElementNode = uiElementNode;
-        setupSection(sectionTitle, sectionDescription);
-
-        if (uiElementNode == null) {
-            // This is serious and should never happen. Instead of crashing, simply abort.
-            // There will be no UI, which will prevent further damage.
-            AdtPlugin.log(IStatus.ERROR, "Missing node to edit!"); //$NON-NLS-1$
-            return;
-        }
-    }
-
-    /**
-     * Returns the Editor associated with this part.
-     */
-    public ManifestEditor getEditor() {
-        return mEditor;
-    }
-    
-    /**
-     * Returns the {@link UiElementNode} associated with this part.
-     */
-    public UiElementNode getUiElementNode() {
-        return mUiElementNode;
-    }
-
-    /**
-     * Changes the element node handled by this part.
-     * 
-     * @param uiElementNode The new element node for the part. 
-     */
-    public void setUiElementNode(UiElementNode uiElementNode) {
-        mUiElementNode = uiElementNode;
-    }
-    
-    /**
-     * Initializes the form part.
-     * <p/>
-     * This is called by the owning managed form as soon as the part is added to the form,
-     * which happens right after the part is actually created.
-     */
-    @Override
-    public void initialize(IManagedForm form) {
-        super.initialize(form);
-        createFormControls(form);
-    }
-
-    /**
-     * Setup the section that contains this part.
-     * <p/>
-     * This is called by the constructor to set the section's title and description
-     * with parameters given in the constructor.
-     * <br/>
-     * Derived class override this if needed, however in most cases the default
-     * implementation should be enough.
-     * 
-     * @param sectionTitle The section part's title
-     * @param sectionDescription The section part's description
-     */
-    protected void setupSection(String sectionTitle, String sectionDescription) {
-        Section section = getSection();
-        section.setText(sectionTitle);
-        section.setDescription(sectionDescription);
-    }
-
-    /**
-     * Create the controls to edit the attributes for the given ElementDescriptor.
-     * <p/>
-     * This MUST not be called by the constructor. Instead it must be called from
-     * <code>initialize</code> (i.e. right after the form part is added to the managed form.)
-     * <p/>
-     * Derived classes can override this if necessary.
-     * 
-     * @param managedForm The owner managed form
-     */
-    protected void createFormControls(IManagedForm managedForm) {
-        setTable(createTableLayout(managedForm.getToolkit(), 2 /* numColumns */));
-
-        createUiAttributes(managedForm);
-    }
-
-    /**
-     * Sets the table where the attribute UI needs to be created.
-     */
-    protected void setTable(Composite table) {
-        mTable = table;
-    }
-
-    /**
-     * Returns the table where the attribute UI needs to be created.
-     */
-    protected Composite getTable() {
-        return mTable;
-    }
-
-    /**
-     * Add all the attribute UI widgets into the underlying table layout.
-     * 
-     * @param managedForm The owner managed form
-     */
-    protected void createUiAttributes(IManagedForm managedForm) {
-        Composite table = getTable();
-        if (table == null || managedForm == null) {
-            return;
-        }
-
-        // Remove any old UI controls 
-        for (Control c : table.getChildren()) {
-            c.dispose();
-        }
-
-        fillTable(table, managedForm);
-
-        // Tell the section that the layout has changed.
-        layoutChanged();
-    }
-
-    /**
-     * Actually fills the table. 
-     * This is called by {@link #createUiAttributes(IManagedForm)} to populate the new
-     * table. The default implementation is to use
-     * {@link #insertUiAttributes(UiElementNode, Composite, IManagedForm)} to actually
-     * place the attributes of the default {@link UiElementNode} in the table.
-     * <p/>
-     * Derived classes can override this to add controls in the table before or after.
-     * 
-     * @param table The table to fill. It must have 2 columns.
-     * @param managedForm The managed form for new controls.
-     */
-    protected void fillTable(Composite table, IManagedForm managedForm) {
-        int inserted = insertUiAttributes(mUiElementNode, table, managedForm);
-        
-        if (inserted == 0) {
-            createLabel(table, managedForm.getToolkit(),
-                    "No attributes to display, waiting for SDK to finish loading...",
-                    null /* tooltip */ );
-        }
-    }
-
-    /**
-     * Insert the UI attributes of the given {@link UiElementNode} in the given table.
-     * 
-     * @param uiNode The {@link UiElementNode} that contains the attributes to display.
-     *               Must not be null.
-     * @param table The table to fill. It must have 2 columns.
-     * @param managedForm The managed form for new controls.
-     * @return The number of UI attributes inserted. It is >= 0.
-     */
-    protected int insertUiAttributes(UiElementNode uiNode, Composite table, IManagedForm managedForm) {
-        if (uiNode == null || table == null || managedForm == null) {
-            return 0;
-        }
-
-        // To iterate over all attributes, we use the {@link ElementDescriptor} instead
-        // of the {@link UiElementNode} because the attributes' order is guaranteed in the
-        // descriptor but not in the node itself.
-        AttributeDescriptor[] attr_desc_list = uiNode.getAttributeDescriptors();
-        for (AttributeDescriptor attr_desc : attr_desc_list) {
-            if (attr_desc instanceof XmlnsAttributeDescriptor) {
-                // Do not show hidden attributes
-                continue;
-            }
-
-            UiAttributeNode ui_attr = uiNode.findUiAttribute(attr_desc);
-            if (ui_attr != null) {
-                ui_attr.createUiControl(table, managedForm);
-            } else {
-                // The XML has an extra attribute which wasn't declared in
-                // AndroidManifestDescriptors. This is not a problem, we just ignore it.
-                AdtPlugin.log(IStatus.WARNING,
-                        "Attribute %1$s not declared in node %2$s, ignored.", //$NON-NLS-1$
-                        attr_desc.getXmlLocalName(),
-                        uiNode.getDescriptor().getXmlName());
-            }
-        }
-        return attr_desc_list.length;
-    }
-
-    /**
-     * Tests whether the part is dirty i.e. its widgets have state that is
-     * newer than the data in the model.
-     * <p/>
-     * This is done by iterating over all attributes and updating the super's
-     * internal dirty flag. Stop once at least one attribute is dirty.
-     * 
-     * @return <code>true</code> if the part is dirty, <code>false</code>
-     *         otherwise.
-     */
-    @Override
-    public boolean isDirty() {
-        if (mUiElementNode != null && !super.isDirty()) {
-            for (UiAttributeNode ui_attr : mUiElementNode.getUiAttributes()) {
-                if (ui_attr.isDirty()) {
-                    markDirty();
-                    break;
-                }
-            }
-        }
-        return super.isDirty();
-    }
-    
-    /**
-     * If part is displaying information loaded from a model, this method
-     * instructs it to commit the new (modified) data back into the model.
-     * 
-     * @param onSave
-     *            indicates if commit is called during 'save' operation or for
-     *            some other reason (for example, if form is contained in a
-     *            wizard or a multi-page editor and the user is about to leave
-     *            the page).
-     */
-    @Override
-    public void commit(boolean onSave) {
-        if (mUiElementNode != null) {
-            mEditor.editXmlModel(new Runnable() {
-                public void run() {
-                    for (UiAttributeNode ui_attr : mUiElementNode.getUiAttributes()) {
-                        ui_attr.commit();
-                    }
-                }
-            });
-        }
-
-        // We need to call super's commit after we synchronized the nodes to make sure we
-        // reset the dirty flag after all the side effects from committing have occurred.
-        super.commit(onSave);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/CopyCutAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/CopyCutAction.java
deleted file mode 100644
index e04256c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/CopyCutAction.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.apache.xml.serialize.Method;
-import org.apache.xml.serialize.OutputFormat;
-import org.apache.xml.serialize.XMLSerializer;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.xml.core.internal.document.NodeContainer;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Provides Cut and Copy actions for the tree nodes.
- */
-public class CopyCutAction extends Action {
-    private List<UiElementNode> mUiNodes;
-    private boolean mPerformCut;
-    private final AndroidEditor mEditor;
-    private final Clipboard mClipboard;
-    private final ICommitXml mXmlCommit;
-
-    /**
-     * Creates a new Copy or Cut action.
-     * 
-     * @param selected The UI node to cut or copy. It *must* have a non-null XML node.
-     * @param perform_cut True if the operation is cut, false if it is copy.
-     */
-    public CopyCutAction(AndroidEditor editor, Clipboard clipboard, ICommitXml xmlCommit,
-            UiElementNode selected, boolean perform_cut) {
-        this(editor, clipboard, xmlCommit, toList(selected), perform_cut);
-    }
-
-    /**
-     * Creates a new Copy or Cut action.
-     * 
-     * @param selected The UI nodes to cut or copy. They *must* have a non-null XML node.
-     *                 The list becomes owned by the {@link CopyCutAction}.
-     * @param perform_cut True if the operation is cut, false if it is copy.
-     */
-    public CopyCutAction(AndroidEditor editor, Clipboard clipboard, ICommitXml xmlCommit,
-            List<UiElementNode> selected, boolean perform_cut) {
-        super(perform_cut ? "Cut" : "Copy");
-        mEditor = editor;
-        mClipboard = clipboard;
-        mXmlCommit = xmlCommit;
-        
-        ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
-        if (perform_cut) {
-            setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
-            setHoverImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
-            setDisabledImageDescriptor(
-                    images.getImageDescriptor(ISharedImages.IMG_TOOL_CUT_DISABLED));
-        } else {
-            setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
-            setHoverImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
-            setDisabledImageDescriptor(
-                    images.getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED));
-        }
-
-        mUiNodes = selected;
-        mPerformCut = perform_cut;
-    }
-
-    /**
-     * Performs the cut or copy action.
-     * First an XML serializer is used to turn the existing XML node into a valid
-     * XML fragment, which is added as text to the clipboard.
-     */
-    @Override
-    public void run() {
-        super.run();
-        if (mUiNodes == null || mUiNodes.size() < 1) {
-            return;
-        }
-
-        // Commit the current pages first, to make sure the XML is in sync.
-        // Committing may change the XML structure.
-        if (mXmlCommit != null) {
-            mXmlCommit.commitPendingXmlChanges();
-        }
-
-        StringBuilder allText = new StringBuilder();
-        ArrayList<UiElementNode> nodesToCut = mPerformCut ? new ArrayList<UiElementNode>() : null;
-
-        for (UiElementNode uiNode : mUiNodes) {
-            try {            
-                Node xml_node = uiNode.getXmlNode();
-                if (xml_node == null) {
-                    return;
-                }
-                
-                String data = getXmlTextFromEditor(xml_node);
- 
-                // In the unlikely event that IStructuredDocument failed to extract the text
-                // directly from the editor, try to fall back on a direct XML serialization
-                // of the XML node. This uses the generic Node interface with no SSE tricks.
-                if (data == null) {
-                    data = getXmlTextFromSerialization(xml_node);
-                }
-                
-                if (data != null) {
-                    allText.append(data);
-                    if (mPerformCut) {
-                        // only remove notes to cut if we actually got some XML text from them
-                        nodesToCut.add(uiNode);
-                    }
-                }
-    
-            } catch (Exception e) {
-                AdtPlugin.log(e, "CopyCutAction failed for UI node %1$s", //$NON-NLS-1$
-                        uiNode.getBreadcrumbTrailDescription(true));
-            }
-        } // for uiNode
-
-        if (allText != null && allText.length() > 0) {
-            mClipboard.setContents(
-                    new Object[] { allText.toString() },
-                    new Transfer[] { TextTransfer.getInstance() });
-            if (mPerformCut) {
-                for (UiElementNode uiNode : nodesToCut) {
-                    uiNode.deleteXmlNode();
-                }
-            }
-        }
-    }
-
-    /** Get the data directly from the editor. */
-    private String getXmlTextFromEditor(Node xml_node) {
-        String data = null;
-        IStructuredModel model = mEditor.getModelForRead();
-        try {
-            IStructuredDocument sse_doc = mEditor.getStructuredDocument();
-            if (xml_node instanceof NodeContainer) {
-                // The easy way to get the source of an SSE XML node.
-                data = ((NodeContainer) xml_node).getSource();
-            } else  if (xml_node instanceof IndexedRegion && sse_doc != null) {
-                // Try harder.
-                IndexedRegion region = (IndexedRegion) xml_node;
-                int start = region.getStartOffset();
-                int end = region.getEndOffset();
-   
-                if (end > start) {
-                    data = sse_doc.get(start, end - start);
-                }
-            }
-        } catch (BadLocationException e) {
-            // the region offset was invalid. ignore.
-        } finally {
-            model.releaseFromRead();
-        }
-        return data;
-    }
-    
-    /**
-     * Direct XML serialization of the XML node.
-     * <p/>
-     * This uses the generic Node interface with no SSE tricks. It's however slower
-     * and doesn't respect formatting (since serialization is involved instead of reading
-     * the actual text buffer.)
-     */
-    private String getXmlTextFromSerialization(Node xml_node) throws IOException {
-        String data;
-        StringWriter sw = new StringWriter();
-        XMLSerializer serializer = new XMLSerializer(sw,
-                new OutputFormat(Method.XML,
-                        OutputFormat.Defaults.Encoding /* utf-8 */,
-                        true /* indent */));
-        // Serialize will throw an IOException if it fails.
-        serializer.serialize((Element) xml_node);
-        data = sw.toString();
-        return data;
-    }
-
-    /**
-     * Static helper class to wrap on node into a list for the constructors.
-     */
-    private static ArrayList<UiElementNode> toList(UiElementNode selected) {
-        ArrayList<UiElementNode> list = null;
-        if (selected != null) {
-            list = new ArrayList<UiElementNode>(1);
-            list.add(selected);
-        }
-        return list;
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/ICommitXml.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/ICommitXml.java
deleted file mode 100644
index 067d145..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/ICommitXml.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-/**
- * Interface for an object that can commit its changes to the underlying XML model
- */
-public interface ICommitXml {
-
-    /** Commits pending data to the underlying XML model. */
-    public void commitPendingXmlChanges();
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java
deleted file mode 100644
index 6fdb7aa..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.dialogs.AbstractElementListSelectionDialog;
-import org.eclipse.ui.dialogs.ISelectionStatusValidator;
-import org.eclipse.ui.part.FileEditorInput;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-
-/**
- * A selection dialog to select the type of the new element node to
- * create, either in the application node or the selected sub node.
- */
-public class NewItemSelectionDialog extends AbstractElementListSelectionDialog {
-
-    /** The UI node selected in the tree view before creating the new item selection dialog.
-     *  Can be null -- which means new items must be created in the root_node. */
-    private UiElementNode mSelectedUiNode;
-    /** The root node chosen by the user, either root_node or the one passed
-     *  to the constructor if not null */
-    private UiElementNode mChosenRootNode;
-    private UiElementNode mLocalRootNode;
-    /** The descriptor of the elements to be displayed as root in this tree view. All elements
-     *  of the same type in the root will be displayed. Can be null. */
-    private ElementDescriptor[] mDescriptorFilters;
-    /** The key for the {@link #setLastUsedXmlName(Object[])}. It corresponds to the full
-     * workspace path of the currently edited file, if this can be computed. This is computed
-     * by {@link #getLastUsedXmlName(UiElementNode)}, called from the constructor. */
-    private String mLastUsedKey;
-    /** A static map of known XML Names used for a given file. The map has full workspace
-     * paths as key and XML names as values. */
-    private static final Map<String, String> sLastUsedXmlName = new HashMap<String, String>();
-    /** The potential XML Name to initially select in the selection dialog. This is computed
-     * in the constructor and set by {@link #setInitialSelection(UiElementNode)}. */
-    private String mInitialXmlName;
-
-    /**
-     * Creates the new item selection dialog.
-     * 
-     * @param shell The parent shell for the list.
-     * @param labelProvider ILabelProvider for the list.
-     * @param descriptorFilters The element allows at the root of the tree. Can be null.
-     * @param ui_node The selected node, or null if none is selected.
-     * @param root_node The root of the Ui Tree, either the UiDocumentNode or a sub-node.
-     */
-    public NewItemSelectionDialog(Shell shell, ILabelProvider labelProvider,
-            ElementDescriptor[] descriptorFilters,
-            UiElementNode ui_node,
-            UiElementNode root_node) {
-        super(shell, labelProvider);
-        mDescriptorFilters = descriptorFilters;
-        mLocalRootNode = root_node;
-
-        // Only accept the UI node if it is not the UI root node and it can have children.
-        // If the node cannot have children, select its parent as a potential target.
-        if (ui_node != null && ui_node != mLocalRootNode) {
-            if (ui_node.getDescriptor().hasChildren()) {
-                mSelectedUiNode = ui_node;
-            } else {
-                UiElementNode parent = ui_node.getUiParent();
-                if (parent != null && parent != mLocalRootNode) {
-                    mSelectedUiNode = parent;
-                }
-            }
-        }
-        
-        setHelpAvailable(false);
-        setMultipleSelection(false);
-        
-        setValidator(new ISelectionStatusValidator() {
-            public IStatus validate(Object[] selection) {
-                if (selection.length == 1 && selection[0] instanceof ViewElementDescriptor) {
-                    return new Status(IStatus.OK, // severity
-                            AdtPlugin.PLUGIN_ID, //plugin id
-                            IStatus.OK, // code
-                            ((ViewElementDescriptor) selection[0]).getCanonicalClassName(), //msg 
-                            null); // exception
-                } else if (selection.length == 1 && selection[0] instanceof ElementDescriptor) {
-                    return new Status(IStatus.OK, // severity
-                            AdtPlugin.PLUGIN_ID, //plugin id
-                            IStatus.OK, // code
-                            "", //$NON-NLS-1$ // msg
-                            null); // exception
-                } else {
-                    return new Status(IStatus.ERROR, // severity
-                            AdtPlugin.PLUGIN_ID, //plugin id
-                            IStatus.ERROR, // code
-                            "Invalid selection", // msg, translatable 
-                            null); // exception
-                }
-            }
-        });
-        
-        // Determine the initial selection using a couple heuristics.
-        
-        // First check if we can get the last used node type for this file.
-        // The heuristic is that generally one keeps adding the same kind of items to the
-        // same file, so reusing the last used item type makes most sense.
-        String xmlName = getLastUsedXmlName(root_node);
-        if (xmlName == null) {
-            // Another heuristic is to find the most used item and default to that.
-            xmlName = getMostUsedXmlName(root_node);
-        }
-        if (xmlName == null) {
-            // Finally the last heuristic is to see if there's an item with a name
-            // similar to the edited file name.
-            xmlName = getLeafFileName(root_node);
-        }
-        // Set the potential name. Selecting the right item is done later by setInitialSelection().
-        mInitialXmlName = xmlName;
-    }
-
-    /**
-     * Returns a potential XML name based on the file name.
-     * The item name is marked with an asterisk to identify it as a partial match.
-     */
-    private String getLeafFileName(UiElementNode ui_node) {
-        if (ui_node != null) {
-            AndroidEditor editor = ui_node.getEditor();
-            if (editor != null) {
-                IEditorInput editorInput = editor.getEditorInput();
-                if (editorInput instanceof FileEditorInput) {
-                    IFile f = ((FileEditorInput) editorInput).getFile();
-                    if (f != null) {
-                        String leafName = f.getFullPath().removeFileExtension().lastSegment();
-                        return "*" + leafName; //$NON-NLS-1$
-                    }
-                }
-            }
-        }
-        
-        return null;
-    }
-
-    /**
-     * Given a potential non-null root node, this method looks for the currently edited
-     * file path and uses it as a key to retrieve the last used item for this file by this
-     * selection dialog. Returns null if nothing can be found, otherwise returns the string
-     * name of the item.
-     */
-    private String getLastUsedXmlName(UiElementNode ui_node) {
-        if (ui_node != null) {
-            AndroidEditor editor = ui_node.getEditor();
-            if (editor != null) {
-                IEditorInput editorInput = editor.getEditorInput();
-                if (editorInput instanceof FileEditorInput) {
-                    IFile f = ((FileEditorInput) editorInput).getFile();
-                    if (f != null) {
-                        mLastUsedKey = f.getFullPath().toPortableString();
-    
-                        return sLastUsedXmlName.get(mLastUsedKey);
-                    }
-                }
-            }
-        }
-        
-        return null;
-    }
-
-    /**
-     * Sets the last used item for this selection dialog for this file.
-     * @param objects The currently selected items. Only the first one is used if it is an
-     *                {@link ElementDescriptor}.
-     */
-    private void setLastUsedXmlName(Object[] objects) {
-        if (mLastUsedKey != null &&
-                objects != null &&
-                objects.length > 0 &&
-                objects[0] instanceof ElementDescriptor) {
-            ElementDescriptor desc = (ElementDescriptor) objects[0];
-            sLastUsedXmlName.put(mLastUsedKey, desc.getXmlName());
-        }
-    }
-
-    /**
-     * Returns the most used sub-element name, if any, or null.
-     */
-    private String getMostUsedXmlName(UiElementNode ui_node) {
-        if (ui_node != null) {
-            TreeMap<String, Integer> counts = new TreeMap<String, Integer>();
-            int max = -1;
-            
-            for (UiElementNode child : ui_node.getUiChildren()) {
-                String name = child.getDescriptor().getXmlName();
-                Integer i = counts.get(name);
-                int count = i == null ? 1 : i.intValue() + 1;
-                counts.put(name, count);
-                max = Math.max(max, count);
-            }
-
-            if (max > 0) {
-                // Find first key with this max and return it
-                for (Entry<String, Integer> entry : counts.entrySet()) {
-                    if (entry.getValue().intValue() == max) {
-                        return entry.getKey();
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @return The root node selected by the user, either root node or the
-     *         one passed to the constructor if not null.
-     */
-    public UiElementNode getChosenRootNode() {
-        return mChosenRootNode;
-    }
-
-    /**
-     * Internal helper to compute the result. Returns the selection from
-     * the list view, if any.
-     */
-    @Override
-    protected void computeResult() {
-        setResult(Arrays.asList(getSelectedElements()));
-        setLastUsedXmlName(getSelectedElements());
-    }
-
-    /**
-     * Creates the dialog area.
-     * 
-     * First add a radio area, which may be either 2 radio controls or
-     * just a message area if there's only one choice (the app root node).
-     * 
-     * Then uses the default from the AbstractElementListSelectionDialog
-     * which is to add both a filter text and a filtered list. Adding both
-     * is necessary (since the base class accesses both internal directly
-     * fields without checking for null pointers.) 
-     * 
-     * Finally sets the initial selection list.
-     */
-    @Override
-    protected Control createDialogArea(Composite parent) {
-        Composite contents = (Composite) super.createDialogArea(parent);
-
-        createRadioControl(contents);
-        createFilterText(contents);
-        createFilteredList(contents);
-
-        // Initialize the list state.
-        // This must be done after the filtered list as been created.
-        chooseNode(mChosenRootNode);
-        
-        // Set the initial selection
-        setInitialSelection(mChosenRootNode);
-        return contents;
-    }
-    
-    /**
-     * Tries to set the initial selection based on the {@link #mInitialXmlName} computed
-     * in the constructor. The selection is only set if there's an element descriptor
-     * that matches the same exact XML name. When {@link #mInitialXmlName} starts with an
-     * asterisk, it means to do a partial case-insensitive match on the start of the
-     * strings.
-     */
-    private void setInitialSelection(UiElementNode rootNode) {
-        ElementDescriptor initialElement = null;
-
-        if (mInitialXmlName != null && mInitialXmlName.length() > 0) {
-            String name = mInitialXmlName;
-            boolean partial = name.startsWith("*");   //$NON-NLS-1$
-            if (partial) {
-                name = name.substring(1).toLowerCase();
-            }
-            
-            for (ElementDescriptor desc : getAllowedDescriptors(rootNode)) {
-                if (!partial && desc.getXmlName().equals(name)) {
-                    initialElement = desc;
-                    break;
-                } else if (partial) {
-                    String name2 = desc.getXmlLocalName().toLowerCase();
-                    if (name.startsWith(name2) || name2.startsWith(name)) {
-                        initialElement = desc;
-                        break;
-                    }
-                }
-            }
-        }
-        
-        setSelection(initialElement == null ? null : new ElementDescriptor[] { initialElement });
-    }
-
-    /**
-     * Creates the message text widget and sets layout data.
-     * @param content the parent composite of the message area.
-     */
-    private Composite createRadioControl(Composite content) {
-        
-        if (mSelectedUiNode != null) {
-            Button radio1 = new Button(content, SWT.RADIO);
-            radio1.setText(String.format("Create a new element at the top level, in %1$s.",
-                    mLocalRootNode.getShortDescription()));
-
-            Button radio2 = new Button(content, SWT.RADIO);
-            radio2.setText(String.format("Create a new element in the selected element, %1$s.",
-                    mSelectedUiNode.getBreadcrumbTrailDescription(false /* include_root */)));
-
-            // Set the initial selection before adding the listeners
-            // (they can't be run till the filtered list has been created)
-            radio1.setSelection(false);
-            radio2.setSelection(true);
-            mChosenRootNode = mSelectedUiNode;
-            
-            radio1.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    super.widgetSelected(e);
-                    chooseNode(mLocalRootNode);
-                }
-            });
-            
-            radio2.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    super.widgetSelected(e);
-                    chooseNode(mSelectedUiNode);
-                }
-            });
-        } else {
-            setMessage(String.format("Create a new element at the top level, in %1$s.",
-                    mLocalRootNode.getShortDescription()));
-            createMessageArea(content);
-
-            mChosenRootNode = mLocalRootNode;
-        }
-         
-        return content;
-    }
-
-    /**
-     * Internal helper to remember the root node choosen by the user.
-     * It also sets the list view to the adequate list of children that can
-     * be added to the chosen root node.
-     * 
-     * If the chosen root node is mLocalRootNode and a descriptor filter was specified
-     * when creating the master-detail part, we use this as the set of nodes that
-     * can be created on the root node.
-     * 
-     * @param ui_node The chosen root node, either mLocalRootNode or
-     *                mSelectedUiNode.
-     */
-    private void chooseNode(UiElementNode ui_node) {
-        mChosenRootNode = ui_node;
-        setListElements(getAllowedDescriptors(ui_node));
-    }
-
-    /**
-     * Returns the list of {@link ElementDescriptor}s that can be added to the given
-     * UI node.
-     * 
-     * @param ui_node The UI node to which element should be added. Cannot be null.
-     * @return A non-null array of {@link ElementDescriptor}. The array might be empty.
-     */
-    private ElementDescriptor[] getAllowedDescriptors(UiElementNode ui_node) {
-        if (ui_node == mLocalRootNode && 
-                mDescriptorFilters != null &&
-                mDescriptorFilters.length != 0) {
-            return mDescriptorFilters;
-        } else {
-            return ui_node.getDescriptor().getChildren();
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/PasteAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/PasteAction.java
deleted file mode 100644
index 4de52c4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/PasteAction.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
-import org.eclipse.wst.xml.core.internal.document.NodeContainer;
-import org.w3c.dom.Node;
-
-
-/**
- * Provides Paste operation for the tree nodes
- */
-public class PasteAction extends Action {
-    private UiElementNode mUiNode;
-    private final AndroidEditor mEditor;
-    private final Clipboard mClipboard;
-
-    public PasteAction(AndroidEditor editor, Clipboard clipboard, UiElementNode ui_node) {
-        super("Paste");
-        mEditor = editor;
-        mClipboard = clipboard;
-
-        ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
-        setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
-        setHoverImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
-        setDisabledImageDescriptor(
-                images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
-
-        mUiNode = ui_node;
-    }
-
-    /**
-     * Performs the paste operation.
-     */
-    @Override
-    public void run() {
-        super.run();
-        
-        final String data = (String) mClipboard.getContents(TextTransfer.getInstance());
-        if (data != null) {
-            IStructuredModel model = mEditor.getModelForEdit();
-            try {
-                IStructuredDocument sse_doc = mEditor.getStructuredDocument();
-                if (sse_doc != null) {
-                    if (mUiNode.getDescriptor().hasChildren()) {
-                        // This UI Node can have children. The new XML is
-                        // inserted as the first child.
-                        
-                        if (mUiNode.getUiChildren().size() > 0) {
-                            // There's already at least one child, so insert right before it.
-                            Node xml_node = mUiNode.getUiChildren().get(0).getXmlNode();
-                            if (xml_node instanceof IndexedRegion) { // implies xml_node != null
-                                IndexedRegion region = (IndexedRegion) xml_node;
-                                sse_doc.replace(region.getStartOffset(), 0, data);
-                                return; // we're done, no need to try the other cases
-                            }                                
-                        }
-                        
-                        // If there's no first XML node child. Create one by
-                        // inserting at the end of the *start* tag.
-                        Node xml_node = mUiNode.getXmlNode();
-                        if (xml_node instanceof NodeContainer) {
-                            NodeContainer container = (NodeContainer) xml_node;
-                            IStructuredDocumentRegion start_tag =
-                                container.getStartStructuredDocumentRegion();
-                            if (start_tag != null) {
-                                sse_doc.replace(start_tag.getEndOffset(), 0, data);
-                                return; // we're done, no need to try the other case
-                            }
-                        }
-                    }
-                    
-                    // This UI Node doesn't accept children. The new XML is inserted as the
-                    // next sibling. This also serves as a fallback if all the previous
-                    // attempts failed. However, this is not possible if the current node
-                    // has for parent a document -- an XML document can only have one root,
-                    // with no siblings.
-                    if (!(mUiNode.getUiParent() instanceof UiDocumentNode)) {
-                        Node xml_node = mUiNode.getXmlNode();
-                        if (xml_node instanceof IndexedRegion) {
-                            IndexedRegion region = (IndexedRegion) xml_node;
-                            sse_doc.replace(region.getEndOffset(), 0, data);
-                        }
-                    }
-                }
-
-            } catch (BadLocationException e) {
-                AdtPlugin.log(e, "ParseAction failed for UI Node %2$s, content '%1$s'", //$NON-NLS-1$
-                        mUiNode.getBreadcrumbTrailDescription(true), data);
-            } finally {
-                model.releaseFromEdit();
-            }
-        }
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiActions.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiActions.java
deleted file mode 100644
index da6db1a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiActions.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * 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.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.swt.widgets.Shell;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.util.List;
-
-/**
- * Performs basic actions on an XML tree: add node, remove node, move up/down.
- */
-public abstract class UiActions implements ICommitXml {
-
-    public UiActions() {
-    }
-
-    //---------------------
-    // Actual implementations must override these to provide specific hooks
-
-    /** Returns the UiDocumentNode for the current model. */
-    abstract protected UiElementNode getRootNode();
-
-    /** Commits pending data before the XML model is modified. */
-    abstract public void commitPendingXmlChanges();
-
-    /**
-     * Utility method to select an outline item based on its model node
-     * 
-     * @param uiNode The node to select. Can be null (in which case nothing should happen)
-     */
-    abstract protected void selectUiNode(UiElementNode uiNode);
-
-    //---------------------
-
-    /**
-     * Called when the "Add..." button next to the tree view is selected.
-     * <p/>
-     * This simplified version of doAdd does not support descriptor filters and creates
-     * a new {@link UiModelTreeLabelProvider} for each call.
-     */
-    public void doAdd(UiElementNode uiNode, Shell shell) {
-        doAdd(uiNode, null /* descriptorFilters */, shell, new UiModelTreeLabelProvider());
-    }
-    
-    /**
-     * Called when the "Add..." button next to the tree view is selected.
-     * 
-     * Displays a selection dialog that lets the user select which kind of node
-     * to create, depending on the current selection.
-     */
-    public void doAdd(UiElementNode uiNode,
-            ElementDescriptor[] descriptorFilters,
-            Shell shell, ILabelProvider labelProvider) {
-        // If the root node is a document with already a root, use it as the root node
-        UiElementNode rootNode = getRootNode();
-        if (rootNode instanceof UiDocumentNode && rootNode.getUiChildren().size() > 0) {
-            rootNode = rootNode.getUiChildren().get(0);
-        }
-
-        NewItemSelectionDialog dlg = new NewItemSelectionDialog(
-                shell,
-                labelProvider,
-                descriptorFilters,
-                uiNode, rootNode);
-        dlg.open();
-        Object[] results = dlg.getResult();
-        if (results != null && results.length > 0) {
-            addElement(dlg.getChosenRootNode(), null, (ElementDescriptor) results[0],
-                    true /*updateLayout*/);
-        }
-    }
-
-    /**
-     * Adds a new XML element based on the {@link ElementDescriptor} to the given parent
-     * {@link UiElementNode}, and then select it.
-     * <p/>
-     * If the parent is a document root which already contains a root element, the inner
-     * root element is used as the actual parent. This ensure you can't create a broken
-     * XML file with more than one root element.
-     * <p/>
-     * If a sibling is given and that sibling has the same parent, the new node is added
-     * right after that sibling. Otherwise the new node is added at the end of the parent
-     * child list.
-     * 
-     * @param uiParent An existing UI node or null to add to the tree root
-     * @param uiSibling An existing UI node before which to insert the new node. Can be null.
-     * @param descriptor The descriptor of the element to add
-     * @param updateLayout True if layout attributes should be set
-     * @return The new {@link UiElementNode} or null.
-     */
-    public UiElementNode addElement(UiElementNode uiParent,
-            UiElementNode uiSibling,
-            ElementDescriptor descriptor,
-            boolean updateLayout) {
-        if (uiParent instanceof UiDocumentNode && uiParent.getUiChildren().size() > 0) {
-            uiParent = uiParent.getUiChildren().get(0);
-        }
-        if (uiSibling != null && uiSibling.getUiParent() != uiParent) {
-            uiSibling = null;
-        }
-
-        UiElementNode uiNew = addNewTreeElement(uiParent, uiSibling, descriptor, updateLayout);
-        selectUiNode(uiNew);
-        
-        return uiNew;
-    }
-
-    /**
-     * Called when the "Remove" button is selected.
-     * 
-     * If the tree has a selection, remove it.
-     * This simply deletes the XML node attached to the UI node: when the XML model fires the
-     * update event, the tree will get refreshed.
-     */
-    public void doRemove(final List<UiElementNode> nodes, Shell shell) {
-        
-        if (nodes == null || nodes.size() == 0) {
-            return;
-        }
-        
-        final int len = nodes.size();
-        
-        StringBuilder sb = new StringBuilder();
-        for (UiElementNode node : nodes) {
-            sb.append("\n- "); //$NON-NLS-1$
-            sb.append(node.getBreadcrumbTrailDescription(false /* include_root */));
-        }
-        
-        if (MessageDialog.openQuestion(shell,
-                len > 1 ? "Remove elements from Android XML"  // title
-                        : "Remove element from Android XML",
-                String.format("Do you really want to remove %1$s?", sb.toString()))) {
-            commitPendingXmlChanges();
-            getRootNode().getEditor().editXmlModel(new Runnable() {
-                public void run() {
-                    UiElementNode previous = null;
-                    UiElementNode parent = null;
-
-                    for (int i = len - 1; i >= 0; i--) {
-                        UiElementNode node = nodes.get(i);
-                        previous = node.getUiPreviousSibling();
-                        parent = node.getUiParent();
-                        
-                        // delete node
-                        node.deleteXmlNode();
-                    }
-                    
-                    // try to select the last previous sibling or the last parent
-                    if (previous != null) {
-                        selectUiNode(previous);
-                    } else if (parent != null) {
-                        selectUiNode(parent);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Called when the "Up" button is selected.
-     * <p/>
-     * If the tree has a selection, move it up, either in the child list or as the last child
-     * of the previous parent.
-     */
-    public void doUp(final List<UiElementNode> nodes) {
-        if (nodes == null || nodes.size() < 1) {
-            return;
-        }
-        
-        final Node[] select_xml_node = { null };
-        UiElementNode last_node = null;
-        UiElementNode search_root = null;
-        
-        for (int i = 0; i < nodes.size(); i++) {
-            final UiElementNode node = last_node = nodes.get(i);
-            
-            // the node will move either up to its parent or grand-parent
-            search_root = node.getUiParent();
-            if (search_root != null && search_root.getUiParent() != null) {
-                search_root = search_root.getUiParent();
-            }
-    
-            commitPendingXmlChanges();
-            getRootNode().getEditor().editXmlModel(new Runnable() {
-                public void run() {
-                    Node xml_node = node.getXmlNode();
-                    if (xml_node != null) {
-                        Node xml_parent = xml_node.getParentNode();
-                        if (xml_parent != null) {
-                            UiElementNode ui_prev = node.getUiPreviousSibling();
-                            if (ui_prev != null && ui_prev.getXmlNode() != null) {
-                                // This node is not the first one of the parent, so it can be
-                                // removed and then inserted before its previous sibling.
-                                // If the previous sibling can have children, though, then it
-                                // is inserted at the end of the children list.
-                                Node xml_prev = ui_prev.getXmlNode();
-                                if (ui_prev.getDescriptor().hasChildren()) {
-                                    xml_prev.appendChild(xml_parent.removeChild(xml_node));
-                                    select_xml_node[0] = xml_node;
-                                } else {
-                                    xml_parent.insertBefore(
-                                            xml_parent.removeChild(xml_node),
-                                            xml_prev);
-                                    select_xml_node[0] = xml_node;
-                                }
-                            } else if (!(xml_parent instanceof Document) &&
-                                    xml_parent.getParentNode() != null &&
-                                    !(xml_parent.getParentNode() instanceof Document)) {
-                                // If the node is the first one of the child list of its
-                                // parent, move it up in the hierarchy as previous sibling
-                                // to the parent. This is only possible if the parent of the
-                                // parent is not a document.
-                                Node grand_parent = xml_parent.getParentNode();
-                                grand_parent.insertBefore(xml_parent.removeChild(xml_node),
-                                        xml_parent);
-                                select_xml_node[0] = xml_node;
-                            }
-                        }
-                    }
-                }
-            });
-        }
-
-        if (select_xml_node[0] == null) {
-            // The XML node has not been moved, we can just select the same UI node
-            selectUiNode(last_node);
-        } else {
-            // The XML node has moved. At this point the UI model has been reloaded
-            // and the XML node has been affected to a new UI node. Find that new UI
-            // node and select it.
-            if (search_root == null) {
-                search_root = last_node.getUiRoot();
-            }
-            if (search_root != null) {
-                selectUiNode(search_root.findXmlNode(select_xml_node[0]));
-            }
-        }
-    }
-
-    /**
-     * Called when the "Down" button is selected.
-     * 
-     * If the tree has a selection, move it down, either in the same child list or as the
-     * first child of the next parent.
-     */
-    public void doDown(final List<UiElementNode> nodes) {
-        if (nodes == null || nodes.size() < 1) {
-            return;
-        }
-        
-        final Node[] select_xml_node = { null };
-        UiElementNode last_node = null;
-        UiElementNode search_root = null;
-
-        for (int i = nodes.size() - 1; i >= 0; i--) {
-            final UiElementNode node = last_node = nodes.get(i);
-            // the node will move either down to its parent or grand-parent
-            search_root = node.getUiParent();
-            if (search_root != null && search_root.getUiParent() != null) {
-                search_root = search_root.getUiParent();
-            }
-    
-            commitPendingXmlChanges();
-            getRootNode().getEditor().editXmlModel(new Runnable() {
-                public void run() {
-                    Node xml_node = node.getXmlNode();
-                    if (xml_node != null) {
-                        Node xml_parent = xml_node.getParentNode();
-                        if (xml_parent != null) {
-                            UiElementNode uiNext = node.getUiNextSibling();
-                            if (uiNext != null && uiNext.getXmlNode() != null) {
-                                // This node is not the last one of the parent, so it can be
-                                // removed and then inserted after its next sibling.
-                                // If the next sibling is a node that can have children, though,
-                                // then the node is inserted as the first child.
-                                Node xml_next = uiNext.getXmlNode();
-                                if (uiNext.getDescriptor().hasChildren()) {
-                                    // Note: insertBefore works as append if the ref node is
-                                    // null, i.e. when the node doesn't have children yet.
-                                    xml_next.insertBefore(xml_parent.removeChild(xml_node),
-                                            xml_next.getFirstChild());
-                                    select_xml_node[0] = xml_node;
-                                } else {
-                                    // Insert "before after next" ;-)
-                                    xml_parent.insertBefore(xml_parent.removeChild(xml_node),
-                                            xml_next.getNextSibling());
-                                    select_xml_node[0] = xml_node;
-                                }
-                            } else if (!(xml_parent instanceof Document) &&
-                                    xml_parent.getParentNode() != null &&
-                                    !(xml_parent.getParentNode() instanceof Document)) {
-                                // This node is the last node of its parent.
-                                // If neither the parent nor the grandparent is a document,
-                                // then the node can be insert right after the parent.
-                                Node grand_parent = xml_parent.getParentNode();
-                                grand_parent.insertBefore(xml_parent.removeChild(xml_node),
-                                        xml_parent.getNextSibling());
-                                select_xml_node[0] = xml_node;
-                            }
-                        }
-                    }
-                }
-            });
-        }
-
-        if (select_xml_node[0] == null) {
-            // The XML node has not been moved, we can just select the same UI node
-            selectUiNode(last_node);
-        } else {
-            // The XML node has moved. At this point the UI model has been reloaded
-            // and the XML node has been affected to a new UI node. Find that new UI
-            // node and select it.
-            if (search_root == null) {
-                search_root = last_node.getUiRoot();
-            }
-            if (search_root != null) {
-                selectUiNode(search_root.findXmlNode(select_xml_node[0]));
-            }
-        }
-    }
-
-    //---------------------
-    
-    /**
-     * Adds a new element of the given descriptor's type to the given UI parent node.
-     * 
-     * This actually creates the corresponding XML node in the XML model, which in turn
-     * will refresh the current tree view.
-     *  
-     * @param uiParent An existing UI node or null to add to the tree root
-     * @param uiSibling An existing UI node to insert right before. Can be null. 
-     * @param descriptor The descriptor of the element to add
-     * @param updateLayout True if layout attributes should be set
-     * @return The {@link UiElementNode} that has been added to the UI tree.
-     */
-    private UiElementNode addNewTreeElement(UiElementNode uiParent,
-            final UiElementNode uiSibling,
-            ElementDescriptor descriptor,
-            final boolean updateLayout) {
-        commitPendingXmlChanges();
-        
-        int index = 0;
-        for (UiElementNode uiChild : uiParent.getUiChildren()) {
-            if (uiChild == uiSibling) {
-                break;
-            }
-            index++;
-        }
-        
-        final UiElementNode uiNew = uiParent.insertNewUiChild(index, descriptor);
-        UiElementNode rootNode = getRootNode();
-
-        rootNode.getEditor().editXmlModel(new Runnable() {
-            public void run() {
-                DescriptorsUtils.setDefaultLayoutAttributes(uiNew, updateLayout);
-                Node xmlNode = uiNew.createXmlNode();
-            }
-        });
-        return uiNew;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java
deleted file mode 100644
index a8c3870..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ITreeSelection;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.ui.forms.IDetailsPage;
-import org.eclipse.ui.forms.IFormPart;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.events.ExpansionEvent;
-import org.eclipse.ui.forms.events.IExpansionListener;
-import org.eclipse.ui.forms.widgets.FormText;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.forms.widgets.SharedScrolledComposite;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.eclipse.ui.forms.widgets.TableWrapLayout;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-
-import java.util.Collection;
-import java.util.HashSet;
-
-/**
- * Details page for the {@link UiElementNode} nodes in the tree view.
- * <p/>
- * See IDetailsBase for more details.
- */
-class UiElementDetail implements IDetailsPage {
-
-    /** The master-detail part, composed of a main tree and an auxiliary detail part */
-    private ManifestSectionPart mMasterPart;
-
-    private Section mMasterSection;
-    private UiElementNode mCurrentUiElementNode;
-    private Composite mCurrentTable;
-    private boolean mIsDirty;
-
-    private IManagedForm mManagedForm;
-
-    private final UiTreeBlock mTree;
-    
-    public UiElementDetail(UiTreeBlock tree) {
-        mTree = tree;
-        mMasterPart = mTree.getMasterPart();
-        mManagedForm = mMasterPart.getManagedForm();
-    }
-    
-    /* (non-java doc)
-     * Initializes the part.
-     */
-    public void initialize(IManagedForm form) {
-        mManagedForm = form;
-    }
-
-    /* (non-java doc)
-     * Creates the contents of the page in the provided parent.
-     */
-    public void createContents(Composite parent) {
-        mMasterSection = createMasterSection(parent);
-    }
-
-    /* (non-java doc)
-     * Called when the provided part has changed selection state.
-     * <p/>
-     * Only reply when our master part originates the selection.
-     */
-    public void selectionChanged(IFormPart part, ISelection selection) {
-        if (part == mMasterPart &&
-                !selection.isEmpty() &&
-                selection instanceof ITreeSelection) {
-            ITreeSelection tree_selection = (ITreeSelection) selection;
-
-            Object first = tree_selection.getFirstElement();
-            if (first instanceof UiElementNode) {
-                UiElementNode ui_node = (UiElementNode) first;
-                createUiAttributeControls(mManagedForm, ui_node);
-            }
-        }
-    }
-
-    /* (non-java doc)
-     * Instructs it to commit the new (modified) data back into the model.
-     */
-    public void commit(boolean onSave) {
-        
-        IStructuredModel model = mTree.getEditor().getModelForEdit();
-        try {
-            // Notify the model we're about to change data...
-            model.aboutToChangeModel();
-
-            if (mCurrentUiElementNode != null) {
-                mCurrentUiElementNode.commit();
-            }
-            
-            // Finally reset the dirty flag if everything was saved properly
-            mIsDirty = false;
-        } catch (Exception e) {
-            AdtPlugin.log(e, "Detail node failed to commit XML attribute!"); //$NON-NLS-1$
-        } finally {
-            // Notify the model we're done modifying it. This must *always* be executed.
-            model.changedModel();
-            model.releaseFromEdit();
-        }
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-
-    /* (non-java doc)
-     * Returns true if the part has been modified with respect to the data
-     * loaded from the model.
-     */
-    public boolean isDirty() {
-        if (mCurrentUiElementNode != null && mCurrentUiElementNode.isDirty()) {
-            markDirty();
-        }
-        return mIsDirty;
-    }
-
-    public boolean isStale() {
-        // pass
-        return false;
-    }
-
-    /**
-     * Called by the master part when the tree is refreshed after the framework resources
-     * have been reloaded.
-     */
-    public void refresh() {
-        if (mCurrentTable != null) {
-            mCurrentTable.dispose();
-            mCurrentTable = null;
-        }
-        mCurrentUiElementNode = null;
-        mMasterSection.getParent().pack(true /* changed */);
-    }
-
-    public void setFocus() {
-        // pass
-    }
-
-    public boolean setFormInput(Object input) {
-        // pass
-        return false;
-    }
-
-    /**
-     * Creates a TableWrapLayout in the DetailsPage, which in turns contains a Section.
-     * 
-     * All the UI should be created in a layout which parent is the mSection itself.
-     * The hierarchy is:
-     * <pre>
-     * DetailPage
-     * + TableWrapLayout
-     *   + Section (with title/description && fill_grab horizontal)
-     *     + TableWrapLayout [*]
-     *       + Labels/Forms/etc... [*]
-     * </pre>
-     * Both items marked with [*] are created by the derived classes to fit their needs.
-     * 
-     * @param parent Parent of the mSection (from createContents)
-     * @return The new Section
-     */
-    private Section createMasterSection(Composite parent) {
-        TableWrapLayout layout = new TableWrapLayout();
-        layout.topMargin = 0;
-        parent.setLayout(layout);
-
-        FormToolkit toolkit = mManagedForm.getToolkit();
-        Section section = toolkit.createSection(parent, Section.TITLE_BAR);
-        section.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP));
-        return section;
-    }
-
-    /**
-     * Create the ui attribute controls to edit the attributes for the given
-     * ElementDescriptor.
-     * <p/>
-     * This is called by the constructor.
-     * Derived classes can override this if necessary.
-     * 
-     * @param managedForm The managed form
-     */
-    private void createUiAttributeControls(
-            final IManagedForm managedForm,
-            final UiElementNode ui_node) {
-
-        final ElementDescriptor elem_desc = ui_node.getDescriptor();
-        mMasterSection.setText(String.format("Attributes for %1$s", ui_node.getShortDescription()));
-
-        if (mCurrentUiElementNode != ui_node) {
-            // Before changing the table, commit all dirty state.
-            if (mIsDirty) {
-                commit(false);
-            }
-            if (mCurrentTable != null) {
-                mCurrentTable.dispose();
-                mCurrentTable = null;
-            }
-
-            // To iterate over all attributes, we use the {@link ElementDescriptor} instead
-            // of the {@link UiElementNode} because the attributes order is guaranteed in the
-            // descriptor but not in the node itself.
-            AttributeDescriptor[] attr_desc_list = ui_node.getAttributeDescriptors();
-
-            // If the attribute list contains at least one SeparatorAttributeDescriptor,
-            // sub-sections will be used. This needs to be known early as it influences the
-            // creation of the master table.
-            boolean useSubsections = false;
-            for (AttributeDescriptor attr_desc : attr_desc_list) {
-                if (attr_desc instanceof SeparatorAttributeDescriptor) {
-                    // Sub-sections will be used. The default sections should no longer be
-                    useSubsections = true;
-                    break;
-                }
-            }
-
-            FormToolkit toolkit = managedForm.getToolkit();
-            Composite masterTable = SectionHelper.createTableLayout(mMasterSection,
-                    toolkit, useSubsections ? 1 : 2 /* numColumns */);
-            mCurrentTable = masterTable;
-
-            mCurrentUiElementNode = ui_node;
-                
-            if (elem_desc.getTooltip() != null) {
-                String tooltip;
-                if (Sdk.getCurrent() != null &&
-                        Sdk.getCurrent().getDocumentationBaseUrl() != null) {
-                    tooltip = DescriptorsUtils.formatFormText(elem_desc.getTooltip(),
-                            elem_desc,
-                            Sdk.getCurrent().getDocumentationBaseUrl());
-                } else {
-                    tooltip = elem_desc.getTooltip();
-                }
-
-                try {
-                    FormText text = SectionHelper.createFormText(masterTable, toolkit,
-                            true /* isHtml */, tooltip, true /* setupLayoutData */);
-                    text.addHyperlinkListener(mTree.getEditor().createHyperlinkListener());
-                    Image icon = elem_desc.getIcon();
-                    if (icon != null) {
-                        text.setImage(DescriptorsUtils.IMAGE_KEY, icon);
-                    }
-                } catch(Exception e) {
-                    // The FormText parser is really really basic and will fail as soon as the
-                    // HTML javadoc is ever so slightly malformatted.
-                    AdtPlugin.log(e,
-                            "Malformed javadoc, rejected by FormText for node %1$s: '%2$s'", //$NON-NLS-1$
-                            ui_node.getDescriptor().getXmlName(),
-                            tooltip);
-                    
-                    // Fallback to a pure text tooltip, no fancy HTML
-                    tooltip = DescriptorsUtils.formatTooltip(elem_desc.getTooltip());
-                    Label label = SectionHelper.createLabel(masterTable, toolkit,
-                            tooltip, tooltip);
-                }
-            }
-
-            Composite table = useSubsections ? null : masterTable;
-            
-            for (AttributeDescriptor attr_desc : attr_desc_list) {
-                if (attr_desc instanceof XmlnsAttributeDescriptor) {
-                    // Do not show hidden attributes
-                    continue;
-                } else if (table == null || attr_desc instanceof SeparatorAttributeDescriptor) {
-                    String title = null;
-                    if (attr_desc instanceof SeparatorAttributeDescriptor) {
-                        // xmlName is actually the label of the separator
-                        title = attr_desc.getXmlLocalName();
-                    } else {
-                        title = String.format("Attributes from %1$s", elem_desc.getUiName());
-                    }
-
-                    table = createSubSectionTable(toolkit, masterTable, title);
-                    if (attr_desc instanceof SeparatorAttributeDescriptor) {
-                        continue;
-                    }
-                }
-
-                UiAttributeNode ui_attr = ui_node.findUiAttribute(attr_desc);
-
-                if (ui_attr != null) {
-                    ui_attr.createUiControl(table, managedForm);
-                    
-                    if (ui_attr.getCurrentValue() != null &&
-                            ui_attr.getCurrentValue().length() > 0) {
-                        ((Section) table.getParent()).setExpanded(true);
-                    }
-                } else {
-                    // The XML has an extra unknown attribute.
-                    // This is not expected to happen so it is ignored.
-                    AdtPlugin.log(IStatus.INFO,
-                            "Attribute %1$s not declared in node %2$s, ignored.", //$NON-NLS-1$
-                            attr_desc.getXmlLocalName(),
-                            ui_node.getDescriptor().getXmlName());
-                }
-            }
-
-            // Create a sub-section for the unknown attributes.
-            // It is initially hidden till there are some attributes to show here.
-            final Composite unknownTable = createSubSectionTable(toolkit, masterTable,
-                    "Unknown XML Attributes");
-            unknownTable.getParent().setVisible(false); // set section to not visible
-            final HashSet<UiAttributeNode> reference = new HashSet<UiAttributeNode>();
-            
-            final IUiUpdateListener updateListener = new IUiUpdateListener() {
-                public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
-                    if (state == UiUpdateState.ATTR_UPDATED) {
-                        updateUnknownAttributesSection(ui_node, unknownTable, managedForm,
-                                reference);
-                    }
-                }
-            };
-            ui_node.addUpdateListener(updateListener);
-            
-            // remove the listener when the UI is disposed
-            unknownTable.addDisposeListener(new DisposeListener() {
-                public void widgetDisposed(DisposeEvent e) {
-                    ui_node.removeUpdateListener(updateListener);
-                }
-            });
-            
-            updateUnknownAttributesSection(ui_node, unknownTable, managedForm, reference);
-            
-            mMasterSection.getParent().pack(true /* changed */);
-        }
-    }
-
-    /**
-     * Create a sub Section and its embedding wrapper table with 2 columns.
-     * @return The table, child of a new section.
-     */
-    private Composite createSubSectionTable(FormToolkit toolkit,
-            Composite masterTable, String title) {
-        
-        // The Section composite seems to ignore colspan when assigned a TableWrapData so
-        // if the parent is a table with more than one column an extra table with one column
-        // is inserted to respect colspan.
-        int parentNumCol = ((TableWrapLayout) masterTable.getLayout()).numColumns;
-        if (parentNumCol > 1) {
-            masterTable = SectionHelper.createTableLayout(masterTable, toolkit, 1);
-            TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB);
-            twd.maxWidth = AndroidEditor.TEXT_WIDTH_HINT;
-            twd.colspan = parentNumCol;
-            masterTable.setLayoutData(twd);
-        }
-        
-        Composite table;
-        Section section = toolkit.createSection(masterTable,
-                Section.TITLE_BAR | Section.TWISTIE);
-
-        // Add an expansion listener that will trigger a reflow on the parent
-        // ScrolledPageBook (which is actually a SharedScrolledComposite). This will
-        // recompute the correct size and adjust the scrollbar as needed.
-        section.addExpansionListener(new IExpansionListener() {
-            public void expansionStateChanged(ExpansionEvent e) {
-                reflowMasterSection();
-            }
-
-            public void expansionStateChanging(ExpansionEvent e) {
-                // pass
-            }
-        });
-
-        section.setText(title);
-        section.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB,
-                                                TableWrapData.TOP));
-        table = SectionHelper.createTableLayout(section, toolkit, 2 /* numColumns */);
-        return table;
-    }
-
-    /**
-     * Reflow the parent ScrolledPageBook (which is actually a SharedScrolledComposite).
-     * This will recompute the correct size and adjust the scrollbar as needed.
-     */
-    private void reflowMasterSection() {
-        for(Composite c = mMasterSection; c != null; c = c.getParent()) {
-            if (c instanceof SharedScrolledComposite) {
-                ((SharedScrolledComposite) c).reflow(true /* flushCache */);
-                break;
-            }
-        }
-    }
-
-    /**
-     * Updates the unknown attributes section for the UI Node.
-     */
-    private void updateUnknownAttributesSection(UiElementNode ui_node,
-            final Composite unknownTable, final IManagedForm managedForm,
-            HashSet<UiAttributeNode> reference) {
-        Collection<UiAttributeNode> ui_attrs = ui_node.getUnknownUiAttributes();
-        Section section = ((Section) unknownTable.getParent());
-        boolean needs_reflow = false;
-
-        // The table was created hidden, show it if there are unknown attributes now
-        if (ui_attrs.size() > 0 && !section.isVisible()) {
-            section.setVisible(true);
-            needs_reflow = true;
-        }
-
-        // Compare the new attribute set with the old "reference" one
-        boolean has_differences = ui_attrs.size() != reference.size();
-        if (!has_differences) {
-            for (UiAttributeNode ui_attr : ui_attrs) {
-                if (!reference.contains(ui_attr)) {
-                    has_differences = true;
-                    break;
-                }
-            }
-        }
-
-        if (has_differences) {
-            needs_reflow = true;
-            reference.clear();
-            
-            // Remove all children of the table
-            for (Control c : unknownTable.getChildren()) {
-                c.dispose();
-            }
-    
-            // Recreate all attributes UI
-            for (UiAttributeNode ui_attr : ui_attrs) {
-                reference.add(ui_attr);
-                ui_attr.createUiControl(unknownTable, managedForm);
-    
-                if (ui_attr.getCurrentValue() != null && ui_attr.getCurrentValue().length() > 0) {
-                    section.setExpanded(true);
-                }
-            }
-        }
-        
-        if (needs_reflow) {
-            reflowMasterSection();
-        }
-    }
-    
-    /**
-     * Marks the part dirty. Called as a result of user interaction with the widgets in the
-     * section.
-     */
-    private void markDirty() {
-        if (!mIsDirty) {
-            mIsDirty = true;
-            mManagedForm.dirtyStateChanged();
-        }
-    }
-}
-
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeContentProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeContentProvider.java
deleted file mode 100644
index 71ef9c0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeContentProvider.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-import java.util.ArrayList;
-
-/**
- * UiModelTreeContentProvider is a trivial implementation of {@link ITreeContentProvider}
- * where elements are expected to be instances of {@link UiElementNode}.
- */
-class UiModelTreeContentProvider implements ITreeContentProvider {
-    
-    /** The descriptor of the elements to be displayed as root in this tree view. All elements
-     *  of the same type in the root will be displayed. */
-    private ElementDescriptor[] mDescriptorFilters;
-    /** The uiRootNode of the model. */
-    private final UiElementNode mUiRootNode;
-
-    public UiModelTreeContentProvider(UiElementNode uiRootNode,
-            ElementDescriptor[] descriptorFilters) {
-        mUiRootNode = uiRootNode;
-        mDescriptorFilters = descriptorFilters;
-    }
-    
-    /* (non-java doc)
-     * Returns all the UI node children of the given element or null if not the right kind
-     * of object. */
-    public Object[] getChildren(Object parentElement) {
-        if (parentElement instanceof UiElementNode) {
-            UiElementNode node = (UiElementNode) parentElement;
-            return node.getUiChildren().toArray();
-        }
-        return null;
-    }
-
-    /* (non-java doc)
-     * Returns the parent of a given UI node or null if it's a root node or it's not the
-     * right kind of node. */
-    public Object getParent(Object element) {
-        if (element instanceof UiElementNode) {
-            UiElementNode node = (UiElementNode) element;
-            return node.getUiParent();
-        }
-        return null;
-    }
-
-    /* (non-java doc)
-     * Returns true if the UI node has any UI children nodes. */
-    public boolean hasChildren(Object element) {
-        if (element instanceof UiElementNode) {
-            UiElementNode node = (UiElementNode) element;
-            return node.getUiChildren().size() > 0;
-        }
-        return false;
-    }
-
-    /* (non-java doc)
-     * Get root elements for the tree. These are all the UI nodes that
-     * match the filter descriptor in the current root node.
-     * <p/>
-     * Although not documented, it seems this method should not return null.
-     * At worse, it should return new Object[0].
-     * <p/>
-     * inputElement is not currently used. The root node and the filter are given
-     * by the enclosing class.
-     */
-    public Object[] getElements(Object inputElement) {
-        ArrayList<UiElementNode> roots = new ArrayList<UiElementNode>();
-        if (mUiRootNode != null) {
-            for (UiElementNode ui_node : mUiRootNode.getUiChildren()) {
-                if (mDescriptorFilters == null || mDescriptorFilters.length == 0) {
-                    roots.add(ui_node);
-                } else {
-                    for (ElementDescriptor filter : mDescriptorFilters) {
-                        if (ui_node.getDescriptor() == filter) {
-                            roots.add(ui_node);
-                        }
-                    }
-                }
-            }
-        }
-        
-        return roots.toArray();
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-        // pass
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeLabelProvider.java
deleted file mode 100644
index 46b0a6b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeLabelProvider.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.ErrorImageComposite;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * UiModelTreeLabelProvider is a trivial implementation of {@link ILabelProvider}
- * where elements are expected to derive from {@link UiElementNode} or
- * from {@link ElementDescriptor}.
- * 
- * It is used by both the master tree viewer and by the list in the Add... selection dialog.
- */
-public class UiModelTreeLabelProvider implements ILabelProvider {
-
-    public UiModelTreeLabelProvider() {
-    }
-
-    /**
-     * Returns the element's logo with a fallback on the android logo.
-     */
-    public Image getImage(Object element) {
-        ElementDescriptor desc = null;
-        if (element instanceof ElementDescriptor) {
-            Image img = ((ElementDescriptor) element).getIcon();
-            if (img != null) {
-                return img;
-            }
-        } else if (element instanceof UiElementNode) {
-            UiElementNode node = (UiElementNode) element;
-            desc = node.getDescriptor();
-            if (desc != null) {
-                Image img = desc.getIcon();
-                if (img != null) {
-                    if (node.hasError()) {
-                        //TODO: cache image
-                        return new ErrorImageComposite(img).createImage();
-                    } else {
-                        return img;
-                    }
-                }
-            }
-        }
-        return AdtPlugin.getAndroidLogo();
-    }
-
-    /**
-     * Uses UiElementNode.shortDescription for the label for this tree item.
-     */
-    public String getText(Object element) {
-        if (element instanceof ElementDescriptor) {
-            ElementDescriptor desc = (ElementDescriptor) element;
-            return desc.getUiName();
-        } else if (element instanceof UiElementNode) {
-            UiElementNode node = (UiElementNode) element;
-            return node.getShortDescription();
-        }
-        return element.toString();
-    }
-
-    public void addListener(ILabelProviderListener listener) {
-        // pass
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-    public boolean isLabelProperty(Object element, String property) {
-        // pass
-        return false;
-    }
-
-    public void removeListener(ILabelProviderListener listener) {
-        // pass
-    }
-}
-
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java
deleted file mode 100644
index 1641284..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java
+++ /dev/null
@@ -1,893 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ITreeSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerComparator;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.ui.forms.DetailsPart;
-import org.eclipse.ui.forms.IDetailsPage;
-import org.eclipse.ui.forms.IDetailsPageProvider;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.MasterDetailsBlock;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-/**
- * {@link UiTreeBlock} is a {@link MasterDetailsBlock} which displays a tree view for
- * a specific set of {@link UiElementNode}.
- * <p/>
- * For a given UI element node, the tree view displays all first-level children that
- * match a given type (given by an {@link ElementDescriptor}. All children from these
- * nodes are also displayed.
- * <p/>
- * In the middle next to the tree are some controls to add or delete tree nodes.
- * On the left is a details part that displays all the visible UI attributes for a given
- * selected UI element node.
- */
-public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml {
-
-    /** Height hint for the tree view. Helps the grid layout resize properly on smaller screens. */
-    private static final int TREE_HEIGHT_HINT = 50;
-
-    /** Container editor */
-    AndroidEditor mEditor;
-    /** The root {@link UiElementNode} which contains all the elements that are to be
-     *  manipulated by this tree view. In general this is the manifest UI node. */
-    private UiElementNode mUiRootNode;
-    /** The descriptor of the elements to be displayed as root in this tree view. All elements
-     *  of the same type in the root will be displayed. */
-    private ElementDescriptor[] mDescriptorFilters;
-    /** The title for the master-detail part (displayed on the top "tab" on top of the tree) */
-    private String mTitle;
-    /** The description for the master-detail part (displayed on top of the tree view) */
-    private String mDescription;
-    /** The master-detail part, composed of a main tree and an auxiliary detail part */
-    private ManifestSectionPart mMasterPart;
-    /** The tree viewer in the master-detail part */
-    private TreeViewer mTreeViewer;
-    /** The "add" button for the tree view */
-    private Button mAddButton;
-    /** The "remove" button for the tree view */
-    private Button mRemoveButton;
-    /** The "up" button for the tree view */
-    private Button mUpButton;
-    /** The "down" button for the tree view */
-    private Button mDownButton;
-    /** The Managed Form used to create the master part */
-    private IManagedForm mManagedForm;
-    /** Reference to the details part of the tree master block. */
-    private DetailsPart mDetailsPart;
-    /** Reference to the clipboard for copy-paste */
-    private Clipboard mClipboard;
-    /** Listener to refresh the tree viewer when the parent's node has been updated */
-    private IUiUpdateListener mUiRefreshListener;
-    /** Listener to enable/disable the UI based on the application node's presence */
-    private IUiUpdateListener mUiEnableListener;
-    /** An adapter/wrapper to use the add/remove/up/down tree edit actions. */
-    private UiTreeActions mUiTreeActions;
-    /**
-     * True if the root node can be created on-demand (i.e. as needed as
-     * soon as children exist). False if an external entity controls the existence of the
-     * root node. In practise, this is false for the manifest application page (the actual
-     * "application" node is managed by the ApplicationToggle part) whereas it is true
-     * for all other tree pages.
-     */
-    private final boolean mAutoCreateRoot;
-
-
-    /**
-     * Creates a new {@link MasterDetailsBlock} that will display all UI nodes matching the
-     * given filter in the given root node.
-     *
-     * @param editor The parent manifest editor.
-     * @param uiRootNode The root {@link UiElementNode} which contains all the elements that are
-     *        to be manipulated by this tree view. In general this is the manifest UI node or the
-     *        application UI node. This cannot be null.
-     * @param autoCreateRoot True if the root node can be created on-demand (i.e. as needed as
-     *        soon as children exist). False if an external entity controls the existence of the
-     *        root node. In practise, this is false for the manifest application page (the actual
-     *        "application" node is managed by the ApplicationToggle part) whereas it is true
-     *        for all other tree pages.
-     * @param descriptorFilters A list of descriptors of the elements to be displayed as root in
-     *        this tree view. Use null or an empty list to accept any kind of node.
-     * @param title Title for the section
-     * @param description Description for the section
-     */
-    public UiTreeBlock(AndroidEditor editor,
-            UiElementNode uiRootNode,
-            boolean autoCreateRoot,
-            ElementDescriptor[] descriptorFilters,
-            String title,
-            String description) {
-        mEditor = editor;
-        mUiRootNode = uiRootNode;
-        mAutoCreateRoot = autoCreateRoot;
-        mDescriptorFilters = descriptorFilters;
-        mTitle = title;
-        mDescription = description;
-    }
-
-    /** @returns The container editor */
-    AndroidEditor getEditor() {
-        return mEditor;
-    }
-
-    /** @returns The reference to the clipboard for copy-paste */
-    Clipboard getClipboard() {
-        return mClipboard;
-    }
-
-    /** @returns The master-detail part, composed of a main tree and an auxiliary detail part */
-    ManifestSectionPart getMasterPart() {
-        return mMasterPart;
-    }
-
-    /**
-     * Returns the {@link UiElementNode} for the current model.
-     * <p/>
-     * This is used by the content provider attached to {@link #mTreeViewer} since
-     * the uiRootNode changes after each call to
-     * {@link #changeRootAndDescriptors(UiElementNode, ElementDescriptor[], boolean)}.
-     */
-    public UiElementNode getRootNode() {
-        return mUiRootNode;
-    }
-
-    @Override
-    protected void createMasterPart(final IManagedForm managedForm, Composite parent) {
-        FormToolkit toolkit = managedForm.getToolkit();
-
-        mManagedForm = managedForm;
-        mMasterPart = new ManifestSectionPart(parent, toolkit);
-        Section section = mMasterPart.getSection();
-        section.setText(mTitle);
-        section.setDescription(mDescription);
-        section.setLayout(new GridLayout());
-        section.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        Composite grid = SectionHelper.createGridLayout(section, toolkit, 2);
-
-        Tree tree = createTreeViewer(toolkit, grid, managedForm);
-        createButtons(toolkit, grid);
-        createTreeContextMenu(tree);
-        createSectionActions(section, toolkit);
-    }
-
-    private void createSectionActions(Section section, FormToolkit toolkit) {
-        ToolBarManager manager = new ToolBarManager(SWT.FLAT);
-        manager.removeAll();
-
-        ToolBar toolbar = manager.createControl(section);
-        section.setTextClient(toolbar);
-
-        ElementDescriptor[] descs = mDescriptorFilters;
-        if (descs == null && mUiRootNode != null) {
-            descs = mUiRootNode.getDescriptor().getChildren();
-        }
-
-        if (descs != null && descs.length > 1) {
-            for (ElementDescriptor desc : descs) {
-                manager.add(new DescriptorFilterAction(desc));
-            }
-        }
-
-        manager.add(new TreeSortAction());
-
-        manager.update(true /*force*/);
-    }
-
-    /**
-     * Creates the tree and its viewer
-     * @return The tree control
-     */
-    private Tree createTreeViewer(FormToolkit toolkit, Composite grid,
-            final IManagedForm managedForm) {
-        // Note: we *could* use a FilteredTree instead of the Tree+TreeViewer here.
-        // However the class must be adapted to create an adapted toolkit tree.
-        final Tree tree = toolkit.createTree(grid, SWT.MULTI);
-        GridData gd = new GridData(GridData.FILL_BOTH);
-        gd.widthHint = AndroidEditor.TEXT_WIDTH_HINT;
-        gd.heightHint = TREE_HEIGHT_HINT;
-        tree.setLayoutData(gd);
-
-        mTreeViewer = new TreeViewer(tree);
-        mTreeViewer.setContentProvider(new UiModelTreeContentProvider(mUiRootNode, mDescriptorFilters));
-        mTreeViewer.setLabelProvider(new UiModelTreeLabelProvider());
-        mTreeViewer.setInput("unused"); //$NON-NLS-1$
-
-        // Create a listener that reacts to selections on the tree viewer.
-        // When a selection is made, ask the managed form to propagate an event to
-        // all parts in the managed form.
-        // This is picked up by UiElementDetail.selectionChanged().
-        mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                managedForm.fireSelectionChanged(mMasterPart, event.getSelection());
-                adjustTreeButtons(event.getSelection());
-            }
-        });
-
-        // Create three listeners:
-        // - One to refresh the tree viewer when the parent's node has been updated
-        // - One to refresh the tree viewer when the framework resources have changed
-        // - One to enable/disable the UI based on the application node's presence.
-        mUiRefreshListener = new IUiUpdateListener() {
-            public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
-                mTreeViewer.refresh();
-            }
-        };
-
-        mUiEnableListener = new IUiUpdateListener() {
-            public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
-                // The UiElementNode for the application XML node always exists, even
-                // if there is no corresponding XML node in the XML file.
-                //
-                // Normally, we enable the UI here if the XML node is not null.
-                //
-                // However if mAutoCreateRoot is true, the root node will be created on-demand
-                // so the tree/block is always enabled.
-                boolean exists = mAutoCreateRoot || (ui_node.getXmlNode() != null);
-                if (mMasterPart != null) {
-                    Section section = mMasterPart.getSection();
-                    if (section.getEnabled() != exists) {
-                        section.setEnabled(exists);
-                        for (Control c : section.getChildren()) {
-                            c.setEnabled(exists);
-                        }
-                    }
-                }
-            }
-        };
-
-        /** Listener to update the root node if the target of the file is changed because of a
-         * SDK location change or a project target change */
-        final ITargetChangeListener targetListener = new ITargetChangeListener() {
-            public void onProjectTargetChange(IProject changedProject) {
-                if (changedProject == mEditor.getProject()) {
-                    onTargetsLoaded();
-                }
-            }
-
-            public void onTargetsLoaded() {
-                // If a details part has been created, we need to "refresh" it too.
-                if (mDetailsPart != null) {
-                    // The details part does not directly expose access to its internal
-                    // page book. Instead it is possible to resize the page book to 0 and then
-                    // back to its original value, which has the side effect of removing all
-                    // existing cached pages.
-                    int limit = mDetailsPart.getPageLimit();
-                    mDetailsPart.setPageLimit(0);
-                    mDetailsPart.setPageLimit(limit);
-                }
-                // Refresh the tree, preserving the selection if possible.
-                mTreeViewer.refresh();
-            }
-        };
-
-        // Setup the listeners
-        changeRootAndDescriptors(mUiRootNode, mDescriptorFilters, false /* refresh */);
-
-        // Listen on resource framework changes to refresh the tree
-        AdtPlugin.getDefault().addTargetListener(targetListener);
-
-        // Remove listeners when the tree widget gets disposed.
-        tree.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                UiElementNode node = mUiRootNode.getUiParent() != null ?
-                                        mUiRootNode.getUiParent() :
-                                        mUiRootNode;
-
-                node.removeUpdateListener(mUiRefreshListener);
-                mUiRootNode.removeUpdateListener(mUiEnableListener);
-
-                AdtPlugin.getDefault().removeTargetListener(targetListener);
-                if (mClipboard != null) {
-                    mClipboard.dispose();
-                    mClipboard = null;
-                }
-            }
-        });
-
-        // Get a new clipboard reference. It is disposed when the tree is disposed.
-        mClipboard = new Clipboard(tree.getDisplay());
-
-        return tree;
-    }
-
-    /**
-     * Changes the UI root node and the descriptor filters of the tree.
-     * <p/>
-     * This removes the listeners attached to the old root node and reattaches them to the
-     * new one.
-     *
-     * @param uiRootNode The root {@link UiElementNode} which contains all the elements that are
-     *        to be manipulated by this tree view. In general this is the manifest UI node or the
-     *        application UI node. This cannot be null.
-     * @param descriptorFilters A list of descriptors of the elements to be displayed as root in
-     *        this tree view. Use null or an empty list to accept any kind of node.
-     * @param forceRefresh If tree, forces the tree to refresh
-     */
-    public void changeRootAndDescriptors(UiElementNode uiRootNode,
-            ElementDescriptor[] descriptorFilters, boolean forceRefresh) {
-        UiElementNode node;
-
-        // Remove previous listeners if any
-        if (mUiRootNode != null) {
-            node = mUiRootNode.getUiParent() != null ? mUiRootNode.getUiParent() : mUiRootNode;
-            node.removeUpdateListener(mUiRefreshListener);
-            mUiRootNode.removeUpdateListener(mUiEnableListener);
-        }
-
-        mUiRootNode = uiRootNode;
-        mDescriptorFilters = descriptorFilters;
-
-        mTreeViewer.setContentProvider(new UiModelTreeContentProvider(mUiRootNode, mDescriptorFilters));
-
-        // Listen on structural changes on the root node of the tree
-        // If the node has a parent, listen on the parent instead.
-        node = mUiRootNode.getUiParent() != null ? mUiRootNode.getUiParent() : mUiRootNode;
-        node.addUpdateListener(mUiRefreshListener);
-
-        // Use the root node to listen to its presence.
-        mUiRootNode.addUpdateListener(mUiEnableListener);
-
-        // Initialize the enabled/disabled state
-        mUiEnableListener.uiElementNodeUpdated(mUiRootNode, null /* state, not used */);
-
-        if (forceRefresh) {
-            mTreeViewer.refresh();
-        }
-
-        createSectionActions(mMasterPart.getSection(), mManagedForm.getToolkit());
-    }
-
-    /**
-     * Creates the buttons next to the tree.
-     */
-    private void createButtons(FormToolkit toolkit, Composite grid) {
-
-        mUiTreeActions = new UiTreeActions();
-
-        Composite button_grid = SectionHelper.createGridLayout(grid, toolkit, 1);
-        button_grid.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
-        mAddButton = toolkit.createButton(button_grid, "Add...", SWT.PUSH);
-        SectionHelper.addControlTooltip(mAddButton, "Adds a new element.");
-        mAddButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL |
-                GridData.VERTICAL_ALIGN_BEGINNING));
-
-        mAddButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                doTreeAdd();
-            }
-        });
-
-        mRemoveButton = toolkit.createButton(button_grid, "Remove...", SWT.PUSH);
-        SectionHelper.addControlTooltip(mRemoveButton, "Removes an existing selected element.");
-        mRemoveButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mRemoveButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                doTreeRemove();
-            }
-        });
-
-        mUpButton = toolkit.createButton(button_grid, "Up", SWT.PUSH);
-        SectionHelper.addControlTooltip(mRemoveButton, "Moves the selected element up.");
-        mUpButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mUpButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                doTreeUp();
-            }
-        });
-
-        mDownButton = toolkit.createButton(button_grid, "Down", SWT.PUSH);
-        SectionHelper.addControlTooltip(mRemoveButton, "Moves the selected element down.");
-        mDownButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mDownButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                doTreeDown();
-            }
-        });
-
-        adjustTreeButtons(TreeSelection.EMPTY);
-    }
-
-    private void createTreeContextMenu(Tree tree) {
-        MenuManager menuManager = new MenuManager();
-        menuManager.setRemoveAllWhenShown(true);
-        menuManager.addMenuListener(new IMenuListener() {
-            /**
-             * The menu is about to be shown. The menu manager has already been
-             * requested to remove any existing menu item. This method gets the
-             * tree selection and if it is of the appropriate type it re-creates
-             * the necessary actions.
-             */
-           public void menuAboutToShow(IMenuManager manager) {
-               ISelection selection = mTreeViewer.getSelection();
-               if (!selection.isEmpty() && selection instanceof ITreeSelection) {
-                   ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
-                   doCreateMenuAction(manager, selected);
-                   return;
-               }
-               doCreateMenuAction(manager, null /* ui_node */);
-            }
-        });
-        Menu contextMenu = menuManager.createContextMenu(tree);
-        tree.setMenu(contextMenu);
-    }
-
-    /**
-     * Adds the menu actions to the context menu when the given UI node is selected in
-     * the tree view.
-     *
-     * @param manager The context menu manager
-     * @param selected The UI nodes selected in the tree. Can be null, in which case the root
-     *                is to be modified.
-     */
-    private void doCreateMenuAction(IMenuManager manager, ArrayList<UiElementNode> selected) {
-        if (selected != null) {
-            boolean hasXml = false;
-            for (UiElementNode uiNode : selected) {
-                if (uiNode.getXmlNode() != null) {
-                    hasXml = true;
-                    break;
-                }
-            }
-
-            if (hasXml) {
-                manager.add(new CopyCutAction(getEditor(), getClipboard(),
-                        null, selected, true /* cut */));
-                manager.add(new CopyCutAction(getEditor(), getClipboard(),
-                        null, selected, false /* cut */));
-
-                // Can't paste with more than one element selected (the selection is the target)
-                if (selected.size() <= 1) {
-                    // Paste is not valid if it would add a second element on a terminal element
-                    // which parent is a document -- an XML document can only have one child. This
-                    // means paste is valid if the current UI node can have children or if the
-                    // parent is not a document.
-                    UiElementNode ui_root = selected.get(0).getUiRoot();
-                    if (ui_root.getDescriptor().hasChildren() ||
-                            !(ui_root.getUiParent() instanceof UiDocumentNode)) {
-                        manager.add(new PasteAction(getEditor(), getClipboard(), selected.get(0)));
-                    }
-                }
-                manager.add(new Separator());
-            }
-        }
-
-        // Append "add" and "remove" actions. They do the same thing as the add/remove
-        // buttons on the side.
-        IconFactory factory = IconFactory.getInstance();
-
-        // "Add" makes sense only if there's 0 or 1 item selected since the
-        // one selected item becomes the target.
-        if (selected == null || selected.size() <= 1) {
-            manager.add(new Action("Add...", factory.getImageDescriptor("add")) { //$NON-NLS-1$
-                @Override
-                public void run() {
-                    super.run();
-                    doTreeAdd();
-                }
-            });
-        }
-
-        if (selected != null) {
-            if (selected != null) {
-                manager.add(new Action("Remove", factory.getImageDescriptor("delete")) { //$NON-NLS-1$
-                    @Override
-                    public void run() {
-                        super.run();
-                        doTreeRemove();
-                    }
-                });
-            }
-            manager.add(new Separator());
-
-            manager.add(new Action("Up", factory.getImageDescriptor("up")) { //$NON-NLS-1$
-                @Override
-                public void run() {
-                    super.run();
-                    doTreeUp();
-                }
-            });
-            manager.add(new Action("Down", factory.getImageDescriptor("down")) { //$NON-NLS-1$
-                @Override
-                public void run() {
-                    super.run();
-                    doTreeDown();
-                }
-            });
-        }
-    }
-
-
-    /**
-     * This is called by the tree when a selection is made.
-     * It enables/disables the buttons associated with the tree depending on the current
-     * selection.
-     *
-     * @param selection The current tree selection (same as mTreeViewer.getSelection())
-     */
-    private void adjustTreeButtons(ISelection selection) {
-        mRemoveButton.setEnabled(!selection.isEmpty() && selection instanceof ITreeSelection);
-        mUpButton.setEnabled(!selection.isEmpty() && selection instanceof ITreeSelection);
-        mDownButton.setEnabled(!selection.isEmpty() && selection instanceof ITreeSelection);
-    }
-
-    /**
-     * An adapter/wrapper to use the add/remove/up/down tree edit actions.
-     */
-    private class UiTreeActions extends UiActions {
-        @Override
-        protected UiElementNode getRootNode() {
-            return mUiRootNode;
-        }
-
-        @Override
-        protected void selectUiNode(UiElementNode uiNodeToSelect) {
-            // Select the new item
-            if (uiNodeToSelect != null) {
-                LinkedList<UiElementNode> segments = new LinkedList<UiElementNode>();
-                for (UiElementNode ui_node = uiNodeToSelect; ui_node != mUiRootNode;
-                        ui_node = ui_node.getUiParent()) {
-                    segments.add(0, ui_node);
-                }
-                if (segments.size() > 0) {
-                    mTreeViewer.setSelection(new TreeSelection(new TreePath(segments.toArray())));
-                } else {
-                    mTreeViewer.setSelection(null);
-                }
-            }
-        }
-
-        @Override
-        public void commitPendingXmlChanges() {
-            commitManagedForm();
-        }
-    }
-
-    /**
-     * Filters an ITreeSelection to only keep the {@link UiElementNode}s (in case there's
-     * something else in there).
-     *
-     * @return A new list of {@link UiElementNode} with at least one item or null.
-     */
-    @SuppressWarnings("unchecked")
-    private ArrayList<UiElementNode> filterSelection(ITreeSelection selection) {
-        ArrayList<UiElementNode> selected = new ArrayList<UiElementNode>();
-
-        for (Iterator it = selection.iterator(); it.hasNext(); ) {
-            Object selectedObj = it.next();
-
-            if (selectedObj instanceof UiElementNode) {
-                selected.add((UiElementNode) selectedObj);
-            }
-        }
-
-        return selected.size() > 0 ? selected : null;
-    }
-
-    /**
-     * Called when the "Add..." button next to the tree view is selected.
-     *
-     * Displays a selection dialog that lets the user select which kind of node
-     * to create, depending on the current selection.
-     */
-    private void doTreeAdd() {
-        UiElementNode ui_node = mUiRootNode;
-        ISelection selection = mTreeViewer.getSelection();
-        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
-            ITreeSelection tree_selection = (ITreeSelection) selection;
-            Object first = tree_selection.getFirstElement();
-            if (first != null && first instanceof UiElementNode) {
-                ui_node = (UiElementNode) first;
-            }
-        }
-
-        mUiTreeActions.doAdd(
-                ui_node,
-                mDescriptorFilters,
-                mTreeViewer.getControl().getShell(),
-                (ILabelProvider) mTreeViewer.getLabelProvider());
-    }
-
-    /**
-     * Called when the "Remove" button is selected.
-     *
-     * If the tree has a selection, remove it.
-     * This simply deletes the XML node attached to the UI node: when the XML model fires the
-     * update event, the tree will get refreshed.
-     */
-    protected void doTreeRemove() {
-        ISelection selection = mTreeViewer.getSelection();
-        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
-            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
-            mUiTreeActions.doRemove(selected, mTreeViewer.getControl().getShell());
-        }
-    }
-
-    /**
-     * Called when the "Up" button is selected.
-     * <p/>
-     * If the tree has a selection, move it up, either in the child list or as the last child
-     * of the previous parent.
-     */
-    protected void doTreeUp() {
-        ISelection selection = mTreeViewer.getSelection();
-        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
-            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
-            mUiTreeActions.doUp(selected);
-        }
-    }
-
-    /**
-     * Called when the "Down" button is selected.
-     *
-     * If the tree has a selection, move it down, either in the same child list or as the
-     * first child of the next parent.
-     */
-    protected void doTreeDown() {
-        ISelection selection = mTreeViewer.getSelection();
-        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
-            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
-            mUiTreeActions.doDown(selected);
-        }
-    }
-
-    /**
-     * Commits the current managed form (the one associated with our master part).
-     * As a side effect, this will commit the current UiElementDetails page.
-     */
-    void commitManagedForm() {
-        if (mManagedForm != null) {
-            mManagedForm.commit(false /* onSave */);
-        }
-    }
-
-    /* Implements ICommitXml for CopyCutAction */
-    public void commitPendingXmlChanges() {
-        commitManagedForm();
-    }
-
-    @Override
-    protected void createToolBarActions(IManagedForm managedForm) {
-        // Pass. Not used, toolbar actions are defined by createSectionActions().
-    }
-
-    @Override
-    protected void registerPages(DetailsPart detailsPart) {
-        // Keep a reference on the details part (the super class doesn't provide a getter
-        // for it.)
-        mDetailsPart = detailsPart;
-
-        // The page selection mechanism does not use pages registered by association with
-        // a node class. Instead it uses a custom details page provider that provides a
-        // new UiElementDetail instance for each node instance. A limit of 5 pages is
-        // then set (the value is arbitrary but should be reasonable) for the internal
-        // page book.
-        detailsPart.setPageLimit(5);
-
-        final UiTreeBlock tree = this;
-
-        detailsPart.setPageProvider(new IDetailsPageProvider() {
-            public IDetailsPage getPage(Object key) {
-                if (key instanceof UiElementNode) {
-                    return new UiElementDetail(tree);
-                }
-                return null;
-            }
-
-            public Object getPageKey(Object object) {
-                return object;  // use node object as key
-            }
-        });
-    }
-
-    /**
-     * An alphabetic sort action for the tree viewer.
-     */
-    private class TreeSortAction extends Action {
-
-        private ViewerComparator mComparator;
-
-        public TreeSortAction() {
-            super("Sorts elements alphabetically.", AS_CHECK_BOX);
-            setImageDescriptor(IconFactory.getInstance().getImageDescriptor("az_sort")); //$NON-NLS-1$
-
-            if (mTreeViewer != null) {
-                boolean is_sorted = mTreeViewer.getComparator() != null;
-                setChecked(is_sorted);
-            }
-        }
-
-        /**
-         * Called when the button is selected. Toggles the tree viewer comparator.
-         */
-        @Override
-        public void run() {
-            if (mTreeViewer == null) {
-                notifyResult(false /*success*/);
-                return;
-            }
-
-            ViewerComparator comp = mTreeViewer.getComparator();
-            if (comp != null) {
-                // Tree is currently sorted.
-                // Save currently comparator and remove it
-                mComparator = comp;
-                mTreeViewer.setComparator(null);
-            } else {
-                // Tree is not currently sorted.
-                // Reuse or add a new comparator.
-                if (mComparator == null) {
-                    mComparator = new ViewerComparator();
-                }
-                mTreeViewer.setComparator(mComparator);
-            }
-
-            notifyResult(true /*success*/);
-        }
-    }
-
-    /**
-     * A filter on descriptor for the tree viewer.
-     * <p/>
-     * The tree viewer will contain many of these actions and only one can be enabled at a
-     * given time. When no action is selected, everything is displayed.
-     * <p/>
-     * Since "radio"-like actions do not allow for unselecting all of them, we manually
-     * handle the exclusive radio button-like property: when an action is selected, it manually
-     * removes all other actions as needed.
-     */
-    private class DescriptorFilterAction extends Action {
-
-        private final ElementDescriptor mDescriptor;
-        private ViewerFilter mFilter;
-
-        public DescriptorFilterAction(ElementDescriptor descriptor) {
-            super(String.format("Displays only %1$s elements.", descriptor.getUiName()),
-                    AS_CHECK_BOX);
-
-            mDescriptor = descriptor;
-            setImageDescriptor(descriptor.getImageDescriptor());
-        }
-
-        /**
-         * Called when the button is selected.
-         * <p/>
-         * Find any existing {@link DescriptorFilter}s and remove them. Install ours.
-         */
-        @Override
-        public void run() {
-            super.run();
-
-            if (isChecked()) {
-                if (mFilter == null) {
-                    // create filter when required
-                    mFilter = new DescriptorFilter(this);
-                }
-
-                // we add our filter first, otherwise the UI might show the full list
-                mTreeViewer.addFilter(mFilter);
-
-                // Then remove the any other filters except ours. There should be at most
-                // one other filter, since that's how the actions are made to look like
-                // exclusive radio buttons.
-                for (ViewerFilter filter : mTreeViewer.getFilters()) {
-                    if (filter instanceof DescriptorFilter && filter != mFilter) {
-                        DescriptorFilterAction action = ((DescriptorFilter) filter).getAction();
-                        action.setChecked(false);
-                        mTreeViewer.removeFilter(filter);
-                    }
-                }
-            } else if (mFilter != null){
-                mTreeViewer.removeFilter(mFilter);
-            }
-        }
-
-        /**
-         * Filters the tree viewer for the given descriptor.
-         * <p/>
-         * The filter is linked to the action so that an action can iterate through the list
-         * of filters and un-select the actions.
-         */
-        private class DescriptorFilter extends ViewerFilter {
-
-            private final DescriptorFilterAction mAction;
-
-            public DescriptorFilter(DescriptorFilterAction action) {
-                mAction = action;
-            }
-
-            public DescriptorFilterAction getAction() {
-                return mAction;
-            }
-
-            /**
-             * Returns true if an element should be displayed, that if the element or
-             * any of its parent matches the requested descriptor.
-             */
-            @Override
-            public boolean select(Viewer viewer, Object parentElement, Object element) {
-                while (element instanceof UiElementNode) {
-                    UiElementNode uiNode = (UiElementNode)element;
-                    if (uiNode.getDescriptor() == mDescriptor) {
-                        return true;
-                    }
-                    element = uiNode.getUiParent();
-                }
-                return false;
-            }
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiSettableAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiSettableAttributeNode.java
deleted file mode 100644
index dd908ad..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiSettableAttributeNode.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.android.ide.eclipse.adt.internal.editors.uimodel;
-
-/**
- * This interface decoration indicates that a given UiAttributeNode can both
- * set and get its current value.
- */
-public interface IUiSettableAttributeNode {
-
-    /** Returns the current value of the node. */
-    public String getCurrentValue();
-    
-    /** Sets the current value of the node. Cannot be null (use an empty string). */
-    public void setCurrentValue(String value);
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiUpdateListener.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiUpdateListener.java
deleted file mode 100644
index a4f1f74..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiUpdateListener.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-
-/**
- * Listen to update notifications in UI nodes.
- */
-public interface IUiUpdateListener {
-
-    /** Update state of the UI node */
-    public enum UiUpdateState {
-        /** The node's attributes have been updated. They may or may not actually have changed. */
-        ATTR_UPDATED,
-        /** The node sub-structure (i.e. child nodes) has changed */
-        CHILDREN_CHANGED,
-        /** The XML counterpart for the UI node has just been created. */
-        CREATED,
-        /** The XML counterpart for the UI node has just been deleted.
-         *  Note that mandatory UI nodes are never actually deleted. */
-        DELETED
-    }
-
-    /**
-     * Indicates that an UiElementNode has been updated.
-     * <p/>
-     * This happens when an {@link UiElementNode} is refreshed to match the
-     * XML model. The actual UI element node may or may not have changed.
-     * 
-     * @param ui_node The {@link UiElementNode} being updated.
-     */
-    public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state);
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAbstractTextAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAbstractTextAttributeNode.java
deleted file mode 100644
index 8910839..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAbstractTextAttributeNode.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-
-import org.w3c.dom.Node;
-
-/**
- * Represents an XML attribute in that can be modified using a simple text field
- * in the XML editor's user interface.
- * <p/>
- * The XML attribute has no default value. When unset, the text field is blank.
- * When updating the XML, if the field is empty, the attribute will be removed
- * from the XML element.  
- * <p/>
- * See {@link UiAttributeNode} for more information.
- */
-public abstract class UiAbstractTextAttributeNode extends UiAttributeNode
-    implements IUiSettableAttributeNode {
-
-    protected static final String DEFAULT_VALUE = "";  //$NON-NLS-1$
-
-    /** Prevent internal listener from firing when internally modifying the text */
-    private boolean mInternalTextModification;
-    /** Last value read from the XML model. Cannot be null. */
-    private String mCurrentValue = DEFAULT_VALUE;
-
-    public UiAbstractTextAttributeNode(AttributeDescriptor attributeDescriptor,
-            UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-    
-    /** Returns the current value of the node. */
-    @Override
-    public final String getCurrentValue() {
-        return mCurrentValue;
-    }
-    
-    /** Sets the current value of the node. Cannot be null (use an empty string). */
-    public final void setCurrentValue(String value) {
-        mCurrentValue = value;
-    }
-    
-    /** Returns if the attribute node is valid, and its UI has been created. */
-    public abstract boolean isValid();
-
-    /** Returns the text value present in the UI. */
-    public abstract String getTextWidgetValue();
-    
-    /** Sets the text value to be displayed in the UI. */
-    public abstract void setTextWidgetValue(String value);
-    
-
-    /**
-     * Updates the current text field's value when the XML has changed.
-     * <p/>
-     * The caller doesn't really know if attributes have changed,
-     * so it will call this to refresh the attribute anyway. The value
-     * is only set if it has changed.
-     * <p/>
-     * This also resets the "dirty" flag.
-    */
-    @Override
-    public void updateValue(Node xml_attribute_node) {
-        mCurrentValue = DEFAULT_VALUE;
-        if (xml_attribute_node != null) {
-            mCurrentValue = xml_attribute_node.getNodeValue();
-        }
-
-        if (isValid() && !getTextWidgetValue().equals(mCurrentValue)) {
-            try {
-                mInternalTextModification = true;
-                setTextWidgetValue(mCurrentValue);
-                setDirty(false);
-            } finally {
-                mInternalTextModification = false;
-            }
-        }
-    }
-
-    /* (non-java doc)
-     * Called by the user interface when the editor is saved or its state changed
-     * and the modified attributes must be committed (i.e. written) to the XML model.
-     */
-    @Override
-    public void commit() {
-        UiElementNode parent = getUiParent();
-        if (parent != null && isValid() && isDirty()) {
-            String value = getTextWidgetValue();
-            if (parent.commitAttributeToXml(this, value)) {
-                mCurrentValue = value;
-                setDirty(false);
-            }
-        }
-    }
-    
-    protected final boolean isInInternalTextModification() {
-        return mInternalTextModification;
-    }
-    
-    protected final void setInInternalTextModification(boolean internalTextModification) {
-        mInternalTextModification = internalTextModification;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java
deleted file mode 100644
index 596cfe3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.forms.IManagedForm;
-import org.w3c.dom.Node;
-
-/**
- * Represents an XML attribute that can be modified by the XML editor's user interface.
- * <p/>
- * The characteristics of an {@link UiAttributeNode} are declared by a
- * corresponding {@link AttributeDescriptor}.
- * <p/>
- * This is an abstract class. Derived classes must implement the creation of the UI
- * and manage its synchronization with the XML.
- */
-public abstract class UiAttributeNode {
-
-    private AttributeDescriptor mDescriptor;
-    private UiElementNode mUiParent;
-    private boolean mIsDirty;
-    private boolean mHasError;
-
-    /** Creates a new {@link UiAttributeNode} linked to a specific {@link AttributeDescriptor} 
-     * and the corresponding runtine {@link UiElementNode} parent. */
-    public UiAttributeNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
-        mDescriptor = attributeDescriptor;
-        mUiParent = uiParent;
-    }
-
-    /** Returns the {@link AttributeDescriptor} specific to this UI attribute node */
-    public final AttributeDescriptor getDescriptor() {
-        return mDescriptor;
-    }
-
-    /** Returns the {@link UiElementNode} that owns this {@link UiAttributeNode} */
-    public final UiElementNode getUiParent() {
-        return mUiParent;
-    }
-    
-    /** Returns the current value of the node. */
-    public abstract String getCurrentValue();
-
-    /**
-     * @return True if the attribute has been changed since it was last loaded
-     *         from the XML model.
-     */
-    public final boolean isDirty() {
-        return mIsDirty;
-    }
-
-    /**
-     * Sets whether the attribute is dirty and also notifies the editor some part's dirty
-     * flag as changed.
-     * <p/>
-     * Subclasses should set the to true as a result of user interaction with the widgets in
-     * the section and then should set to false when the commit() method completed.
-     */
-    public void setDirty(boolean isDirty) {
-        boolean old_value = mIsDirty;
-        mIsDirty = isDirty;
-        // TODO: for unknown attributes, getParent() != null && getParent().getEditor() != null
-        if (old_value != isDirty) {
-            getUiParent().getEditor().editorDirtyStateChanged();
-        }
-    }
-    
-    /**
-     * Sets the error flag value.
-     * @param errorFlag the error flag
-     */
-    public final void setHasError(boolean errorFlag) {
-        mHasError = errorFlag;
-    }
-    
-    /**
-     * Returns whether this node has errors.
-     */
-    public final boolean hasError() {
-        return mHasError;
-    }
-    
-    /**
-     * Called once by the parent user interface to creates the necessary
-     * user interface to edit this attribute.
-     * <p/>
-     * This method can be called more than once in the life cycle of an UI node,
-     * typically when the UI is part of a master-detail tree, as pages are swapped.
-     * 
-     * @param parent The composite where to create the user interface.
-     * @param managedForm The managed form owning this part.
-     */
-    public abstract void createUiControl(Composite parent, IManagedForm managedForm);
-
-    /**
-     * Used to get a list of all possible values for this UI attribute.
-     * <p/>
-     * This is used, among other things, by the XML Content Assists to complete values
-     * for an attribute.
-     * <p/>
-     * Implementations that do not have any known values should return null.
-     * 
-     * @param prefix An optional prefix string, which is whatever the user has already started
-     *   typing. Can be null or an empty string. The implementation can use this to filter choices
-     *   and only return strings that match this prefix. A lazy or default implementation can
-     *   simply ignore this and return everything.
-     * @return A list of possible completion values, and empty array or null.
-     */
-    public abstract String[] getPossibleValues(String prefix);
-
-    /**
-     * Called when the XML is being loaded or has changed to
-     * update the value held by this user interface attribute node.
-     * <p/>
-     * The XML Node <em>may</em> be null, which denotes that the attribute is not
-     * specified in the XML model. In general, this means the "default" value of the
-     * attribute should be used.
-     * <p/>
-     * The caller doesn't really know if attributes have changed,
-     * so it will call this to refresh the attribute anyway. It's up to the
-     * UI implementation to minimize refreshes.
-     * 
-     * @param xml_attribute_node
-     */
-    public abstract void updateValue(Node xml_attribute_node);
-
-    /**
-     * Called by the user interface when the editor is saved or its state changed
-     * and the modified attributes must be committed (i.e. written) to the XML model.
-     * <p/>
-     * Important behaviors:
-     * <ul>
-     * <li>The caller *must* have called IStructuredModel.aboutToChangeModel before.
-     *     The implemented methods must assume it is safe to modify the XML model.
-     * <li>On success, the implementation *must* call setDirty(false).
-     * <li>On failure, the implementation can fail with an exception, which
-     *     is trapped and logged by the caller, or do nothing, whichever is more
-     *     appropriate.
-     * </ul>
-     */
-    public abstract void commit();
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiDocumentNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiDocumentNode.java
deleted file mode 100644
index beac5e1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiDocumentNode.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener.UiUpdateState;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-/**
- * Represents an XML document node that can be modified by the user interface in the XML editor.
- * <p/>
- * The structure of a given {@link UiDocumentNode} is declared by a corresponding
- * {@link DocumentDescriptor}.
- */
-public class UiDocumentNode extends UiElementNode {
-    
-    /**
-     * Creates a new {@link UiDocumentNode} described by a given {@link DocumentDescriptor}.
-     * 
-     * @param documentDescriptor The {@link DocumentDescriptor} for the XML node. Cannot be null.
-     */
-    public UiDocumentNode(DocumentDescriptor documentDescriptor) {
-        super(documentDescriptor);
-    }
-
-    /**
-     * Computes a short string describing the UI node suitable for tree views.
-     * Uses the element's attribute "android:name" if present, or the "android:label" one
-     * followed by the element's name.
-     * 
-     * @return A short string describing the UI node suitable for tree views.
-     */
-    @Override
-    public String getShortDescription() {
-        return "Document"; //$NON-NLS-1$
-    }
-    
-    /**
-     * Computes a "breadcrumb trail" description for this node.
-     * 
-     * @param include_root Whether to include the root (e.g. "Manifest") or not. Has no effect
-     *                     when called on the root node itself.
-     * @return The "breadcrumb trail" description for this node.
-     */
-    @Override
-    public String getBreadcrumbTrailDescription(boolean include_root) {
-        return "Document"; //$NON-NLS-1$
-    }
-    
-    /**
-     * This method throws an exception when attempted to assign a parent, since XML documents
-     * cannot have a parent. It is OK to assign null.
-     */
-    @Override
-    protected void setUiParent(UiElementNode parent) {
-        if (parent != null) {
-            // DEBUG. Change to log warning.
-            throw new UnsupportedOperationException("Documents can't have UI parents"); //$NON-NLS-1$
-        }
-        super.setUiParent(null);
-    }
-
-    /**
-     * Populate this element node with all values from the given XML node.
-     * 
-     * This fails if the given XML node has a different element name -- it won't change the
-     * type of this ui node.
-     * 
-     * This method can be both used for populating values the first time and updating values
-     * after the XML model changed.
-     * 
-     * @param xml_node The XML node to mirror
-     * @return Returns true if the XML structure has changed (nodes added, removed or replaced)
-     */
-    @Override
-    public boolean loadFromXmlNode(Node xml_node) {
-        boolean structure_changed = (getXmlDocument() != xml_node);
-        setXmlDocument((Document) xml_node);
-        structure_changed |= super.loadFromXmlNode(xml_node);
-        if (structure_changed) {
-            invokeUiUpdateListeners(UiUpdateState.CHILDREN_CHANGED);
-        }
-        return structure_changed;
-    }
-    
-    /**
-     * This method throws an exception if there is no underlying XML document.
-     * <p/>
-     * XML documents cannot be created per se -- they are a by-product of the StructuredEditor
-     * XML parser.
-     * 
-     * @return The current value of getXmlDocument().
-     */
-    @Override
-    public Node createXmlNode() {
-        if (getXmlDocument() == null) {
-            // By design, a document node cannot be created, it is owned by the XML parser.
-            // By "design" this should never happen since the XML parser always creates an XML
-            // document container, even for an empty file.
-            throw new UnsupportedOperationException("Documents cannot be created"); //$NON-NLS-1$
-        }
-        return getXmlDocument();
-    }
-
-    /**
-     * This method throws an exception and does not even try to delete the XML document.
-     * <p/>
-     * XML documents cannot be deleted per se -- they are a by-product of the StructuredEditor
-     * XML parser.
-     * 
-     * @return The removed node or null if it didn't exist in the firtst place. 
-     */
-    @Override
-    public Node deleteXmlNode() {
-        // DEBUG. Change to log warning.
-        throw new UnsupportedOperationException("Documents cannot be deleted"); //$NON-NLS-1$
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java
deleted file mode 100644
index b31917e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java
+++ /dev/null
@@ -1,1531 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.CustomViewDescriptorService;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener.UiUpdateState;
-import com.android.ide.eclipse.adt.internal.editors.xml.descriptors.XmlDescriptors;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.views.properties.IPropertyDescriptor;
-import org.eclipse.ui.views.properties.IPropertySource;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * Represents an XML node that can be modified by the user interface in the XML editor.
- * <p/>
- * Each tree viewer used in the application page's parts needs to keep a model representing
- * each underlying node in the tree. This interface represents the base type for such a node.
- * <p/>
- * Each node acts as an intermediary model between the actual XML model (the real data support)
- * and the tree viewers or the corresponding page parts.
- * <p/>
- * Element nodes don't contain data per se. Their data is contained in their attributes
- * as well as their children's attributes, see {@link UiAttributeNode}.
- * <p/>
- * The structure of a given {@link UiElementNode} is declared by a corresponding
- * {@link ElementDescriptor}.
- * <p/>
- * The class implements {@link IPropertySource}, in order to fill the Eclipse property tab when
- * an element is selected. The {@link AttributeDescriptor} are used property descriptors.
- */
-public class UiElementNode implements IPropertySource {
-
-    /** List of prefixes removed from android:id strings when creating short descriptions. */
-    private static String[] ID_PREFIXES = {
-        "@android:id/", //$NON-NLS-1$
-        "@+id/", "@id/", "@+", "@" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-
-    /** The element descriptor for the node. Always present, never null. */
-    private ElementDescriptor mDescriptor;
-    /** The parent element node in the UI model. It is null for a root element or until
-     *  the node is attached to its parent. */
-    private UiElementNode mUiParent;
-    /** The {@link AndroidEditor} handling the UI hierarchy. This is defined only for the
-     *  root node. All children have the value set to null and query their parent. */
-    private AndroidEditor mEditor;
-    /** The XML {@link Document} model that is being mirror by the UI model. This is defined
-     *  only for the root node. All children have the value set to null and query their parent. */
-    private Document mXmlDocument;
-    /** The XML {@link Node} mirror by this UI node. This can be null for mandatory UI node which
-     *  have no corresponding XML node or for new UI nodes before their XML node is set. */
-    private Node mXmlNode;
-    /** The list of all UI children nodes. Can be empty but never null. There's one UI children
-     *  node per existing XML children node. */
-    private ArrayList<UiElementNode> mUiChildren;
-    /** The list of <em>all</em> UI attributes, as declared in the {@link ElementDescriptor}.
-     *  The list is always defined and never null. Unlike the UiElementNode children list, this
-     *  is always defined, even for attributes that do not exist in the XML model -- that's because
-     *  "missing" attributes in the XML model simply mean a default value is used. Also note that
-     *  the underlying collection is a map, so order is not respected. To get the desired attribute
-     *  order, iterate through the {@link ElementDescriptor}'s attribute list. */
-    private HashMap<AttributeDescriptor, UiAttributeNode> mUiAttributes;
-    private HashSet<UiAttributeNode> mUnknownUiAttributes;
-    /** A read-only view of the UI children node collection. */
-    private List<UiElementNode> mReadOnlyUiChildren;
-    /** A read-only view of the UI attributes collection. */
-    private Collection<UiAttributeNode> mReadOnlyUiAttributes;
-    /** A map of hidden attribute descriptors. Key is the XML name. */
-    private Map<String, AttributeDescriptor> mCachedHiddenAttributes;
-    /** An optional list of {@link IUiUpdateListener}. Most element nodes will not have any
-     *  listeners attached, so the list is only created on demand and can be null. */
-    private ArrayList<IUiUpdateListener> mUiUpdateListeners;
-    /** Error Flag */
-    private boolean mHasError;
-    /** Temporary data used by the editors. This data is not sync'ed with the XML */
-    private Object mEditData;
-
-    /**
-     * Creates a new {@link UiElementNode} described by a given {@link ElementDescriptor}.
-     *
-     * @param elementDescriptor The {@link ElementDescriptor} for the XML node. Cannot be null.
-     */
-    public UiElementNode(ElementDescriptor elementDescriptor) {
-        mDescriptor = elementDescriptor;
-        clearContent();
-    }
-
-    /**
-     * Clears the {@link UiElementNode} by resetting the children list and
-     * the {@link UiAttributeNode}s list.
-     * Also resets the attached XML node, document, editor if any.
-     * <p/>
-     * The parent {@link UiElementNode} node is not reset so that it's position
-     * in the hierarchy be left intact, if any.
-     */
-    /* package */ void clearContent() {
-        mXmlNode = null;
-        mXmlDocument = null;
-        mEditor = null;
-        clearAttributes();
-        mReadOnlyUiChildren = null;
-        if (mUiChildren == null) {
-            mUiChildren = new ArrayList<UiElementNode>();
-        } else {
-            // We can't remove mandatory nodes, we just clear them.
-            for (int i = mUiChildren.size() - 1; i >= 0; --i) {
-                removeUiChildAtIndex(i);
-            }
-        }
-    }
-
-    /**
-     * Clears the internal list of attributes, the read-only cached version of it
-     * and the read-only cached hidden attribute list.
-     */
-    private void clearAttributes() {
-        mUiAttributes = null;
-        mReadOnlyUiAttributes = null;
-        mCachedHiddenAttributes = null;
-        mUnknownUiAttributes = new HashSet<UiAttributeNode>();
-    }
-
-    /**
-     * Gets or creates the internal UiAttributes list.
-     * <p/>
-     * When the descriptor derives from ViewElementDescriptor, this list depends on the
-     * current UiParent node.
-     *
-     * @return A new set of {@link UiAttributeNode} that matches the expected
-     *         attributes for this node.
-     */
-    private HashMap<AttributeDescriptor, UiAttributeNode> getInternalUiAttributes() {
-        if (mUiAttributes == null) {
-            AttributeDescriptor[] attr_list = getAttributeDescriptors();
-            mUiAttributes = new HashMap<AttributeDescriptor, UiAttributeNode>(attr_list.length);
-            for (AttributeDescriptor desc : attr_list) {
-                UiAttributeNode ui_node = desc.createUiNode(this);
-                if (ui_node != null) {  // Some AttributeDescriptors do not have UI associated
-                    mUiAttributes.put(desc, ui_node);
-                }
-            }
-        }
-        return mUiAttributes;
-    }
-
-    /**
-     * Computes a short string describing the UI node suitable for tree views.
-     * Uses the element's attribute "android:name" if present, or the "android:label" one
-     * followed by the element's name.
-     *
-     * @return A short string describing the UI node suitable for tree views.
-     */
-    public String getShortDescription() {
-        if (mXmlNode != null && mXmlNode instanceof Element && mXmlNode.hasAttributes()) {
-
-            // Application and Manifest nodes have a special treatment: they are unique nodes
-            // so we don't bother trying to differentiate their strings and we fall back to
-            // just using the UI name below.
-            Element elem = (Element) mXmlNode;
-
-            String attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
-                                              AndroidManifestDescriptors.ANDROID_NAME_ATTR);
-            if (attr == null || attr.length() == 0) {
-                attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
-                                           AndroidManifestDescriptors.ANDROID_LABEL_ATTR);
-            }
-            if (attr == null || attr.length() == 0) {
-                attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
-                                           XmlDescriptors.PREF_KEY_ATTR);
-            }
-            if (attr == null || attr.length() == 0) {
-                attr = elem.getAttribute(ResourcesDescriptors.NAME_ATTR);
-            }
-            if (attr == null || attr.length() == 0) {
-                attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
-                                           LayoutDescriptors.ID_ATTR);
-
-                if (attr != null && attr.length() > 0) {
-                    for (String prefix : ID_PREFIXES) {
-                        if (attr.startsWith(prefix)) {
-                            attr = attr.substring(prefix.length());
-                            break;
-                        }
-                    }
-                }
-            }
-            if (attr != null && attr.length() > 0) {
-                return String.format("%1$s (%2$s)", attr, mDescriptor.getUiName());
-            }
-        }
-
-        return String.format("%1$s", mDescriptor.getUiName());
-    }
-
-    /**
-     * Computes a "breadcrumb trail" description for this node.
-     * It will look something like "Manifest > Application > .myactivity (Activity) > Intent-Filter"
-     *
-     * @param include_root Whether to include the root (e.g. "Manifest") or not. Has no effect
-     *                     when called on the root node itself.
-     * @return The "breadcrumb trail" description for this node.
-     */
-    public String getBreadcrumbTrailDescription(boolean include_root) {
-        StringBuilder sb = new StringBuilder(getShortDescription());
-
-        for (UiElementNode ui_node = getUiParent();
-                ui_node != null;
-                ui_node = ui_node.getUiParent()) {
-            if (!include_root && ui_node.getUiParent() == null) {
-                break;
-            }
-            sb.insert(0, String.format("%1$s > ", ui_node.getShortDescription())); //$NON-NLS-1$
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Sets the XML {@link Document}.
-     * <p/>
-     * The XML {@link Document} is initially null. The XML {@link Document} must be set only on the
-     * UI root element node (this method takes care of that.)
-     */
-    public void setXmlDocument(Document xml_doc) {
-        if (mUiParent == null) {
-            mXmlDocument = xml_doc;
-        } else {
-            mUiParent.setXmlDocument(xml_doc);
-        }
-    }
-
-    /**
-     * Returns the XML {@link Document}.
-     * <p/>
-     * The value is initially null until the UI node is attached to its UI parent -- the value
-     * of the document is then propagated.
-     *
-     * @return the XML {@link Document} or the parent's XML {@link Document} or null.
-     */
-    public Document getXmlDocument() {
-        if (mXmlDocument != null) {
-            return mXmlDocument;
-        } else if (mUiParent != null) {
-            return mUiParent.getXmlDocument();
-        }
-        return null;
-    }
-
-    /**
-     * Returns the XML node associated with this UI node.
-     * <p/>
-     * Some {@link ElementDescriptor} are declared as being "mandatory". This means the
-     * corresponding UI node will exist even if there is no corresponding XML node. Such structure
-     * is created and enforced by the parent of the tree, not the element themselves. However
-     * such nodes will likely not have an XML node associated, so getXmlNode() can return null.
-     *
-     * @return The associated XML node. Can be null for mandatory nodes.
-     */
-    public Node getXmlNode() {
-        return mXmlNode;
-    }
-
-    /**
-     * Returns the {@link ElementDescriptor} for this node. This is never null.
-     * <p/>
-     * Do not use this to call getDescriptor().getAttributes(), instead call
-     * getAttributeDescriptors() which can be overriden by derived classes.
-     */
-    public ElementDescriptor getDescriptor() {
-        return mDescriptor;
-    }
-
-    /**
-     * Returns the {@link AttributeDescriptor} array for the descriptor of this node.
-     * <p/>
-     * Use this instead of getDescriptor().getAttributes() -- derived classes can override
-     * this to manipulate the attribute descriptor list depending on the current UI node.
-     */
-    public AttributeDescriptor[] getAttributeDescriptors() {
-        return mDescriptor.getAttributes();
-    }
-
-    /**
-     * Returns the hidden {@link AttributeDescriptor} array for the descriptor of this node.
-     * This is a subset of the getAttributeDescriptors() list.
-     * <p/>
-     * Use this instead of getDescriptor().getHiddenAttributes() -- potentially derived classes
-     * could override this to manipulate the attribute descriptor list depending on the current
-     * UI node. There's no need for it right now so keep it private.
-     */
-    private Map<String, AttributeDescriptor> getHiddenAttributeDescriptors() {
-        if (mCachedHiddenAttributes == null) {
-            mCachedHiddenAttributes = new HashMap<String, AttributeDescriptor>();
-            for (AttributeDescriptor attr_desc : getAttributeDescriptors()) {
-                if (attr_desc instanceof XmlnsAttributeDescriptor) {
-                    mCachedHiddenAttributes.put(
-                            ((XmlnsAttributeDescriptor) attr_desc).getXmlNsName(),
-                            attr_desc);
-                }
-            }
-        }
-        return mCachedHiddenAttributes;
-    }
-
-    /**
-     * Sets the parent of this UiElementNode.
-     * <p/>
-     * The root node has no parent.
-     */
-    protected void setUiParent(UiElementNode parent) {
-        mUiParent = parent;
-        // Invalidate the internal UiAttributes list, as it may depend on the actual UiParent.
-        clearAttributes();
-    }
-
-    /**
-     * @return The parent {@link UiElementNode} or null if this is the root node.
-     */
-    public UiElementNode getUiParent() {
-        return mUiParent;
-    }
-
-    /**
-     * Returns The root {@link UiElementNode}.
-     */
-    public UiElementNode getUiRoot() {
-        UiElementNode root = this;
-        while (root.mUiParent != null) {
-            root = root.mUiParent;
-        }
-
-        return root;
-    }
-
-    /**
-     * Returns the previous UI sibling of this UI node.
-     * If the node does not have a previous sibling, returns null.
-     */
-    public UiElementNode getUiPreviousSibling() {
-        if (mUiParent != null) {
-            List<UiElementNode> childlist = mUiParent.getUiChildren();
-            if (childlist != null && childlist.size() > 1 && childlist.get(0) != this) {
-                int index = childlist.indexOf(this);
-                return index > 0 ? childlist.get(index - 1) : null;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the next UI sibling of this UI node.
-     * If the node does not have a next sibling, returns null.
-     */
-    public UiElementNode getUiNextSibling() {
-        if (mUiParent != null) {
-            List<UiElementNode> childlist = mUiParent.getUiChildren();
-            if (childlist != null) {
-                int size = childlist.size();
-                if (size > 1 && childlist.get(size - 1) != this) {
-                    int index = childlist.indexOf(this);
-                    return index >= 0 && index < size - 1 ? childlist.get(index + 1) : null;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Sets the {@link AndroidEditor} handling this {@link UiElementNode} hierarchy.
-     * <p/>
-     * The editor must always be set on the root node. This method takes care of that.
-     */
-    public void setEditor(AndroidEditor editor) {
-        if (mUiParent == null) {
-            mEditor = editor;
-        } else {
-            mUiParent.setEditor(editor);
-        }
-    }
-
-    /**
-     * Returns the {@link AndroidEditor} that embeds this {@link UiElementNode}.
-     * <p/>
-     * The value is initially null until the node is attached to its parent -- the value
-     * of the root node is then propagated.
-     *
-     * @return The embedding {@link AndroidEditor} or null.
-     */
-    public AndroidEditor getEditor() {
-        return mUiParent == null ? mEditor : mUiParent.getEditor();
-    }
-
-    /**
-     * Returns the Android target data for the file being edited.
-     */
-    public AndroidTargetData getAndroidTarget() {
-        return getEditor().getTargetData();
-    }
-
-    /**
-     * @return A read-only version of the children collection.
-     */
-    public List<UiElementNode> getUiChildren() {
-        if (mReadOnlyUiChildren == null) {
-            mReadOnlyUiChildren = Collections.unmodifiableList(mUiChildren);
-        }
-        return mReadOnlyUiChildren;
-    }
-
-    /**
-     * @return A read-only version of the attributes collection.
-     */
-    public Collection<UiAttributeNode> getUiAttributes() {
-        if (mReadOnlyUiAttributes == null) {
-            mReadOnlyUiAttributes = Collections.unmodifiableCollection(
-                    getInternalUiAttributes().values());
-        }
-        return mReadOnlyUiAttributes;
-    }
-
-    /**
-     * @return A read-only version of the unknown attributes collection.
-     */
-    public Collection<UiAttributeNode> getUnknownUiAttributes() {
-        return Collections.unmodifiableCollection(mUnknownUiAttributes);
-    }
-
-    /**
-     * Sets the error flag value.
-     * @param errorFlag the error flag
-     */
-    public final void setHasError(boolean errorFlag) {
-        mHasError = errorFlag;
-    }
-
-    /**
-     * Returns whether this node, its attributes, or one of the children nodes (and attributes)
-     * has errors.
-     */
-    public final boolean hasError() {
-        if (mHasError) {
-            return true;
-        }
-
-        // get the error value from the attributes.
-        Collection<UiAttributeNode> attributes = getInternalUiAttributes().values();
-        for (UiAttributeNode attribute : attributes) {
-            if (attribute.hasError()) {
-                return true;
-            }
-        }
-
-        // and now from the children.
-        for (UiElementNode child : mUiChildren) {
-            if (child.hasError()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Adds a new {@link IUiUpdateListener} to the internal update listener list.
-     */
-    public void addUpdateListener(IUiUpdateListener listener) {
-       if (mUiUpdateListeners == null) {
-           mUiUpdateListeners = new ArrayList<IUiUpdateListener>();
-       }
-       if (!mUiUpdateListeners.contains(listener)) {
-           mUiUpdateListeners.add(listener);
-       }
-    }
-
-    /**
-     * Removes an existing {@link IUiUpdateListener} from the internal update listener list.
-     * Does nothing if the list is empty or the listener is not registered.
-     */
-    public void removeUpdateListener(IUiUpdateListener listener) {
-       if (mUiUpdateListeners != null) {
-           mUiUpdateListeners.remove(listener);
-       }
-    }
-
-    /**
-     * Finds a child node relative to this node using a path-like expression.
-     * F.ex. "node1/node2" would find a child "node1" that contains a child "node2" and
-     * returns the latter. If there are multiple nodes with the same name at the same
-     * level, always uses the first one found.
-     *
-     * @param path The path like expression to select a child node.
-     * @return The ui node found or null.
-     */
-    public UiElementNode findUiChildNode(String path) {
-        String[] items = path.split("/");  //$NON-NLS-1$
-        UiElementNode ui_node = this;
-        for (String item : items) {
-            boolean next_segment = false;
-            for (UiElementNode c : ui_node.mUiChildren) {
-                if (c.getDescriptor().getXmlName().equals(item)) {
-                    ui_node = c;
-                    next_segment = true;
-                    break;
-                }
-            }
-            if (!next_segment) {
-                return null;
-            }
-        }
-        return ui_node;
-    }
-
-    /**
-     * Finds an {@link UiElementNode} which contains the give XML {@link Node}.
-     * Looks recursively in all children UI nodes.
-     *
-     * @param xmlNode The XML node to look for.
-     * @return The {@link UiElementNode} that contains xmlNode or null if not found,
-     */
-    public UiElementNode findXmlNode(Node xmlNode) {
-        if (xmlNode == null) {
-            return null;
-        }
-        if (getXmlNode() == xmlNode) {
-            return this;
-        }
-
-        for (UiElementNode uiChild : mUiChildren) {
-            UiElementNode found = uiChild.findXmlNode(xmlNode);
-            if (found != null) {
-                return found;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the {@link UiAttributeNode} matching this attribute descriptor or
-     * null if not found.
-     *
-     * @param attr_desc The {@link AttributeDescriptor} to match.
-     * @return the {@link UiAttributeNode} matching this attribute descriptor or null
-     *         if not found.
-     */
-    public UiAttributeNode findUiAttribute(AttributeDescriptor attr_desc) {
-        return getInternalUiAttributes().get(attr_desc);
-    }
-
-    /**
-     * Populate this element node with all values from the given XML node.
-     *
-     * This fails if the given XML node has a different element name -- it won't change the
-     * type of this ui node.
-     *
-     * This method can be both used for populating values the first time and updating values
-     * after the XML model changed.
-     *
-     * @param xml_node The XML node to mirror
-     * @return Returns true if the XML structure has changed (nodes added, removed or replaced)
-     */
-    public boolean loadFromXmlNode(Node xml_node) {
-        boolean structure_changed = (mXmlNode != xml_node);
-        mXmlNode = xml_node;
-        if (xml_node != null) {
-            updateAttributeList(xml_node);
-            structure_changed |= updateElementList(xml_node);
-            invokeUiUpdateListeners(structure_changed ? UiUpdateState.CHILDREN_CHANGED
-                                                      : UiUpdateState.ATTR_UPDATED);
-        }
-        return structure_changed;
-    }
-
-    /**
-     * Clears the UI node and reload it from the given XML node.
-     * <p/>
-     * This works by clearing all references to any previous XML or UI nodes and
-     * then reloads the XML document from scratch. The editor reference is kept.
-     * <p/>
-     * This is used in the special case where the ElementDescriptor structure has changed.
-     * Rather than try to diff inflated UI nodes (as loadFromXmlNode does), we don't bother
-     * and reload everything. This is not subtle and should be used very rarely.
-     *
-     * @param xml_node The XML node or document to reload. Can be null.
-     */
-    public void reloadFromXmlNode(Node xml_node) {
-        // The editor needs to be preserved, it is not affected by an XML change.
-        AndroidEditor editor = getEditor();
-        clearContent();
-        setEditor(editor);
-        if (xml_node != null) {
-            setXmlDocument(xml_node.getOwnerDocument());
-        }
-        // This will reload all the XML and recreate the UI structure from scratch.
-        loadFromXmlNode(xml_node);
-    }
-
-    /**
-     * Called by attributes when they want to commit their value
-     * to an XML node.
-     * <p/>
-     * For mandatory nodes, this makes sure the underlying XML element node
-     * exists in the model. If not, it is created and assigned as the underlying
-     * XML node.
-     * </br>
-     * For non-mandatory nodes, simply return the underlying XML node, which
-     * must always exists.
-     *
-     * @return The XML node matching this {@link UiElementNode} or null.
-     */
-    public Node prepareCommit() {
-        if (getDescriptor().isMandatory()) {
-            createXmlNode();
-            // The new XML node has been created.
-            // We don't need to refresh using loadFromXmlNode() since there are
-            // no attributes or elements that need to be loading into this node.
-        }
-        return getXmlNode();
-    }
-
-    /**
-     * Commits the attributes (all internal, inherited from UI parent & unknown attributes).
-     * This is called by the UI when the embedding part needs to be committed.
-     */
-    public void commit() {
-        for (UiAttributeNode ui_attr : getInternalUiAttributes().values()) {
-            ui_attr.commit();
-        }
-
-        for (UiAttributeNode ui_attr : mUnknownUiAttributes) {
-            ui_attr.commit();
-        }
-    }
-
-    /**
-     * Returns true if the part has been modified with respect to the data
-     * loaded from the model.
-     */
-    public boolean isDirty() {
-        for (UiAttributeNode ui_attr : getInternalUiAttributes().values()) {
-            if (ui_attr.isDirty()) {
-                return true;
-            }
-        }
-
-        for (UiAttributeNode ui_attr : mUnknownUiAttributes) {
-            if (ui_attr.isDirty()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Creates the underlying XML element node for this UI node if it doesn't already
-     * exists.
-     *
-     * @return The new value of getXmlNode() (can be null if creation failed)
-     */
-    public Node createXmlNode() {
-        if (mXmlNode != null) {
-            return null;
-        }
-        Node parentXmlNode = null;
-        if (mUiParent != null) {
-            parentXmlNode = mUiParent.prepareCommit();
-            if (parentXmlNode == null) {
-                // The parent failed to create its own backing XML node. Abort.
-                // No need to throw an exception, the parent will most likely
-                // have done so itself.
-                return null;
-            }
-        }
-
-        String element_name = getDescriptor().getXmlName();
-        Document doc = getXmlDocument();
-
-        // We *must* have a root node. If not, we need to abort.
-        if (doc == null) {
-            throw new RuntimeException(
-                    String.format("Missing XML document for %1$s XML node.", element_name));
-        }
-
-        // If we get here and parent_xml_node is null, the node is to be created
-        // as the root node of the document (which can't be null, cf check above).
-        if (parentXmlNode == null) {
-            parentXmlNode = doc;
-        }
-
-        mXmlNode = doc.createElement(element_name);
-
-        Node xmlNextSibling = null;
-
-        UiElementNode uiNextSibling = getUiNextSibling();
-        if (uiNextSibling != null) {
-            xmlNextSibling = uiNextSibling.getXmlNode();
-        }
-
-        parentXmlNode.insertBefore(mXmlNode, xmlNextSibling);
-
-        // Insert a separator after the tag, to make it easier to read
-        Text sep = doc.createTextNode("\n");
-        parentXmlNode.appendChild(sep);
-
-        // Set all initial attributes in the XML node if they are not empty.
-        // Iterate on the descriptor list to get the desired order and then use the
-        // internal values, if any.
-        for (AttributeDescriptor attr_desc : getAttributeDescriptors()) {
-            if (attr_desc instanceof XmlnsAttributeDescriptor) {
-                XmlnsAttributeDescriptor desc = (XmlnsAttributeDescriptor) attr_desc;
-                Attr attr = doc.createAttributeNS(XmlnsAttributeDescriptor.XMLNS_URI,
-                        desc.getXmlNsName());
-                attr.setValue(desc.getValue());
-                attr.setPrefix(desc.getXmlNsPrefix());
-                mXmlNode.getAttributes().setNamedItemNS(attr);
-            } else {
-                UiAttributeNode ui_attr = getInternalUiAttributes().get(attr_desc);
-                commitAttributeToXml(ui_attr, ui_attr.getCurrentValue());
-            }
-        }
-
-        invokeUiUpdateListeners(UiUpdateState.CREATED);
-        return mXmlNode;
-    }
-
-    /**
-     * Removes the XML node corresponding to this UI node if it exists
-     * and also removes all mirrored information in this UI node (i.e. children, attributes)
-     *
-     * @return The removed node or null if it didn't exist in the firtst place.
-     */
-    public Node deleteXmlNode() {
-        if (mXmlNode == null) {
-            return null;
-        }
-
-        // First clear the internals of the node and *then* actually deletes the XML
-        // node (because doing so will generate an update even and this node may be
-        // revisited via loadFromXmlNode).
-        Node old_xml_node = mXmlNode;
-        clearContent();
-
-        Node xml_parent = old_xml_node.getParentNode();
-        if (xml_parent == null) {
-            xml_parent = getXmlDocument();
-        }
-        old_xml_node = xml_parent.removeChild(old_xml_node);
-
-        invokeUiUpdateListeners(UiUpdateState.DELETED);
-        return old_xml_node;
-    }
-
-    /**
-     * Updates the element list for this UiElementNode.
-     * At the end, the list of children UiElementNode here will match the one from the
-     * provided XML {@link Node}:
-     * <ul>
-     * <li> Walk both the current ui children list and the xml children list at the same time.
-     * <li> If we have a new xml child but already reached the end of the ui child list, add the
-     *      new xml node.
-     * <li> Otherwise, check if the xml node is referenced later in the ui child list and if so,
-     *      move it here. It means the XML child list has been reordered.
-     * <li> Otherwise, this is a new XML node that we add in the middle of the ui child list.
-     * <li> At the end, we may have finished walking the xml child list but still have remaining
-     *      ui children, simply delete them as they matching trailing xml nodes that have been
-     *      removed unless they are mandatory ui nodes.
-     * </ul>
-     * Note that only the first case is used when populating the ui list the first time.
-     *
-     * @param xml_node The XML node to mirror
-     * @return True when the XML structure has changed.
-     */
-    protected boolean updateElementList(Node xml_node) {
-        boolean structure_changed = false;
-        int ui_index = 0;
-        Node xml_child = xml_node.getFirstChild();
-        while (xml_child != null) {
-            if (xml_child.getNodeType() == Node.ELEMENT_NODE) {
-                String element_name = xml_child.getNodeName();
-                UiElementNode ui_node = null;
-                if (mUiChildren.size() <= ui_index) {
-                    // A new node is being added at the end of the list
-                    ElementDescriptor desc = mDescriptor.findChildrenDescriptor(element_name,
-                            false /* recursive */);
-                    if (desc == null) {
-                        // Unknown node. Create a temporary descriptor for it.
-                        // most important we want to auto-add unknown attributes to it.
-                        AndroidEditor editor = getEditor();
-                        IEditorInput editorInput = editor.getEditorInput();
-                        if (editorInput instanceof IFileEditorInput) {
-                            IFileEditorInput fileInput = (IFileEditorInput)editorInput;
-                            desc = CustomViewDescriptorService.getInstance().getDescriptor(
-                                    fileInput.getFile().getProject(), element_name);
-                            if (desc == null) {
-                                desc = new ElementDescriptor(element_name);
-                            }
-                        } else {
-                            desc = new ElementDescriptor(element_name);
-                            // TODO associate a new "?" icon to this descriptor.
-                        }
-                    }
-                    structure_changed = true;
-                    ui_node = appendNewUiChild(desc);
-                    ui_index++;
-                } else {
-                    // A new node is being inserted or moved.
-                    // Note: mandatory nodes can be created without an XML node in which case
-                    // getXmlNode() is null.
-                    UiElementNode ui_child;
-                    int n = mUiChildren.size();
-                    for (int j = ui_index; j < n; j++) {
-                        ui_child = mUiChildren.get(j);
-                        if (ui_child.getXmlNode() != null && ui_child.getXmlNode() == xml_child) {
-                            if (j > ui_index) {
-                                // Found the same XML node at some later index, now move it here.
-                                mUiChildren.remove(j);
-                                mUiChildren.add(ui_index, ui_child);
-                                structure_changed = true;
-                            }
-                            ui_node = ui_child;
-                            ui_index++;
-                            break;
-                        }
-                    }
-
-                    if (ui_node == null) {
-                        // Look for an unused mandatory node with no XML node attached
-                        // referencing the same XML element name
-                        for (int j = ui_index; j < n; j++) {
-                            ui_child = mUiChildren.get(j);
-                            if (ui_child.getXmlNode() == null &&
-                                    ui_child.getDescriptor().isMandatory() &&
-                                    ui_child.getDescriptor().getXmlName().equals(element_name)) {
-                                if (j > ui_index) {
-                                    // Found it, now move it here
-                                    mUiChildren.remove(j);
-                                    mUiChildren.add(ui_index, ui_child);
-                                }
-                                // assign the XML node to this empty mandatory element.
-                                ui_child.mXmlNode = xml_child;
-                                structure_changed = true;
-                                ui_node = ui_child;
-                                ui_index++;
-                            }
-                        }
-                    }
-
-                    if (ui_node == null) {
-                        // Inserting new node
-                        ElementDescriptor desc = mDescriptor.findChildrenDescriptor(element_name,
-                                false /* recursive */);
-                        if (desc == null) {
-                            // Unknown element. Simply ignore it.
-                            AdtPlugin.log(IStatus.WARNING,
-                                    "AndroidManifest: Ignoring unknown '%s' XML element", //$NON-NLS-1$
-                                    element_name);
-                        } else {
-                            structure_changed = true;
-                            ui_node = insertNewUiChild(ui_index, desc);
-                            ui_index++;
-                        }
-                    }
-                }
-                if (ui_node != null) {
-                    // If we touched an UI Node, even an existing one, refresh its content.
-                    // For new nodes, this will populate them recursively.
-                    structure_changed |= ui_node.loadFromXmlNode(xml_child);
-                }
-            }
-            xml_child = xml_child.getNextSibling();
-        }
-
-        // There might be extra UI nodes at the end if the XML node list got shorter.
-        for (int index = mUiChildren.size() - 1; index >= ui_index; --index) {
-             structure_changed |= removeUiChildAtIndex(index);
-        }
-
-        return structure_changed;
-    }
-
-    /**
-     * Internal helper to remove an UI child node given by its index in the
-     * internal child list.
-     *
-     * Also invokes the update listener on the node to be deleted *after* the node has
-     * been removed.
-     *
-     * @param ui_index The index of the UI child to remove, range 0 .. mUiChildren.size()-1
-     * @return True if the structure has changed
-     * @throws IndexOutOfBoundsException if index is out of mUiChildren's bounds. Of course you
-     *         know that could never happen unless the computer is on fire or something.
-     */
-    private boolean removeUiChildAtIndex(int ui_index) {
-        UiElementNode ui_node = mUiChildren.get(ui_index);
-        ElementDescriptor desc = ui_node.getDescriptor();
-
-        try {
-            if (ui_node.getDescriptor().isMandatory()) {
-                // This is a mandatory node. Such a node must exist in the UiNode hierarchy
-                // even if there's no XML counterpart. However we only need to keep one.
-
-                // Check if the parent (e.g. this node) has another similar ui child node.
-                boolean keepNode = true;
-                for (UiElementNode child : mUiChildren) {
-                    if (child != ui_node && child.getDescriptor() == desc) {
-                        // We found another child with the same descriptor that is not
-                        // the node we want to remove. This means we have one mandatory
-                        // node so we can safely remove ui_node.
-                        keepNode = false;
-                        break;
-                    }
-                }
-
-                if (keepNode) {
-                    // We can't remove a mandatory node as we need to keep at least one
-                    // mandatory node in the parent. Instead we just clear its content
-                    // (including its XML Node reference).
-
-                    // A mandatory node with no XML means it doesn't really exist, so it can't be
-                    // deleted. So the structure will change only if the ui node is actually
-                    // associated to an XML node.
-                    boolean xml_exists = (ui_node.getXmlNode() != null);
-
-                    ui_node.clearContent();
-                    return xml_exists;
-                }
-            }
-
-            mUiChildren.remove(ui_index);
-            return true;
-        } finally {
-            // Tell listeners that a node has been removed.
-            // The model has already been modified.
-            invokeUiUpdateListeners(UiUpdateState.DELETED);
-        }
-    }
-
-    /**
-     * Creates a new {@link UiElementNode} from the given {@link ElementDescriptor}
-     * and appends it to the end of the element children list.
-     *
-     * @param descriptor The {@link ElementDescriptor} that knows how to create the UI node.
-     * @return The new UI node that has been appended
-     */
-    public UiElementNode appendNewUiChild(ElementDescriptor descriptor) {
-        UiElementNode ui_node;
-        ui_node = descriptor.createUiNode();
-        mUiChildren.add(ui_node);
-        ui_node.setUiParent(this);
-        ui_node.invokeUiUpdateListeners(UiUpdateState.CREATED);
-        return ui_node;
-    }
-
-    /**
-     * Creates a new {@link UiElementNode} from the given {@link ElementDescriptor}
-     * and inserts it in the element children list at the specified position.
-     *
-     * @param index The position where to insert in the element children list.
-     * @param descriptor The {@link ElementDescriptor} that knows how to create the UI node.
-     * @return The new UI node.
-     */
-    public UiElementNode insertNewUiChild(int index, ElementDescriptor descriptor) {
-        UiElementNode ui_node;
-        ui_node = descriptor.createUiNode();
-        mUiChildren.add(index, ui_node);
-        ui_node.setUiParent(this);
-        ui_node.invokeUiUpdateListeners(UiUpdateState.CREATED);
-        return ui_node;
-    }
-
-    /**
-     * Updates the {@link UiAttributeNode} list for this {@link UiElementNode}.
-     * <p/>
-     * For a given {@link UiElementNode}, the attribute list always exists in
-     * full and is totally independent of whether the XML model actually
-     * has the corresponding attributes.
-     * <p/>
-     * For each attribute declared in this {@link UiElementNode}, get
-     * the corresponding XML attribute. It may not exist, in which case the
-     * value will be null. We don't really know if a value has changed, so
-     * the updateValue() is called on the UI sattribute in all cases.
-     *
-     * @param xmlNode The XML node to mirror
-     */
-    protected void updateAttributeList(Node xmlNode) {
-        NamedNodeMap xmlAttrMap = xmlNode.getAttributes();
-        HashSet<Node> visited = new HashSet<Node>();
-
-        // For all known (i.e. expected) UI attributes, find an existing XML attribute of
-        // same (uri, local name) and update the internal Ui attribute value.
-        for (UiAttributeNode uiAttr : getInternalUiAttributes().values()) {
-            AttributeDescriptor desc = uiAttr.getDescriptor();
-            if (!(desc instanceof SeparatorAttributeDescriptor)) {
-                Node xmlAttr = xmlAttrMap == null ? null :
-                    xmlAttrMap.getNamedItemNS(desc.getNamespaceUri(), desc.getXmlLocalName());
-                uiAttr.updateValue(xmlAttr);
-                visited.add(xmlAttr);
-            }
-        }
-
-        // Clone the current list of unknown attributes. We'll then remove from this list when
-        // we still attributes which are still unknown. What will be left are the old unknown
-        // attributes that have been deleted in the current XML attribute list.
-        @SuppressWarnings("unchecked") //$NON-NLS-1$
-        HashSet<UiAttributeNode> deleted = (HashSet<UiAttributeNode>) mUnknownUiAttributes.clone();
-
-        // We need to ignore hidden attributes.
-        Map<String, AttributeDescriptor> hiddenAttrDesc = getHiddenAttributeDescriptors();
-
-        // Traverse the actual XML attribute list to find unknown attributes
-        if (xmlAttrMap != null) {
-            for (int i = 0; i < xmlAttrMap.getLength(); i++) {
-                Node xmlAttr = xmlAttrMap.item(i);
-                // Ignore attributes which have actual descriptors
-                if (visited.contains(xmlAttr)) {
-                    continue;
-                }
-
-                String xmlFullName = xmlAttr.getNodeName();
-
-                // Ignore attributes which are hidden (based on the prefix:localName key)
-                if (hiddenAttrDesc.containsKey(xmlFullName)) {
-                    continue;
-                }
-
-                String xmlAttrLocalName = xmlAttr.getLocalName();
-                String xmlNsUri = xmlAttr.getNamespaceURI();
-
-                UiAttributeNode uiAttr = null;
-                for (UiAttributeNode a : mUnknownUiAttributes) {
-                    String aLocalName = a.getDescriptor().getXmlLocalName();
-                    String aNsUri = a.getDescriptor().getNamespaceUri();
-                    if (aLocalName.equals(xmlAttrLocalName) &&
-                            (aNsUri == xmlNsUri || (aNsUri != null && aNsUri.equals(xmlNsUri)))) {
-                        // This attribute is still present in the unknown list
-                        uiAttr = a;
-                        // It has not been deleted
-                        deleted.remove(a);
-                        break;
-                    }
-                }
-                if (uiAttr == null) {
-                    // Create a new unknown attribute
-                    TextAttributeDescriptor desc = new TextAttributeDescriptor(
-                            xmlAttrLocalName, // xml name
-                            xmlFullName, // ui name
-                            xmlNsUri, // NS uri
-                            "Unknown XML attribute"); // tooltip, translatable
-                    uiAttr = desc.createUiNode(this);
-                    mUnknownUiAttributes.add(uiAttr);
-                }
-
-                uiAttr.updateValue(xmlAttr);
-            }
-
-            // Remove from the internal list unknown attributes that have been deleted from the xml
-            for (UiAttributeNode a : deleted) {
-                mUnknownUiAttributes.remove(a);
-            }
-        }
-    }
-
-    /**
-     * Invoke all registered {@link IUiUpdateListener} listening on this UI update for this node.
-     */
-    protected void invokeUiUpdateListeners(UiUpdateState state) {
-        if (mUiUpdateListeners != null) {
-            for (IUiUpdateListener listener : mUiUpdateListeners) {
-                try {
-                    listener.uiElementNodeUpdated(this, state);
-                } catch (Exception e) {
-                    // prevent a crashing listener from crashing the whole invocation chain
-                    AdtPlugin.log(e, "UIElement Listener failed: %s, state=%s",  //$NON-NLS-1$
-                            getBreadcrumbTrailDescription(true),
-                            state.toString());
-                }
-            }
-        }
-    }
-
-    // --- for derived implementations only ---
-
-    // TODO doc
-    protected void setXmlNode(Node xml_node) {
-        mXmlNode = xml_node;
-    }
-
-    /**
-     * Sets the temporary data used by the editors.
-     * @param data the data.
-     *
-     * @since GLE1
-     * @deprecated Used by GLE1. Should be deprecated for GLE2.
-     */
-    public void setEditData(Object data) {
-        mEditData = data;
-    }
-
-    /**
-     * Returns the temporary data used by the editors for this object.
-     * @return the data, or <code>null</code> if none has been set.
-     */
-    public Object getEditData() {
-        return mEditData;
-    }
-
-    public void refreshUi() {
-        invokeUiUpdateListeners(UiUpdateState.ATTR_UPDATED);
-    }
-
-
-    // ------------- Helpers
-
-    /**
-     * Helper method to commit a single attribute value to XML.
-     * <p/>
-     * This method updates the XML regardless of the current XML value.
-     * Callers should check first if an update is needed.
-     * If the new value is empty, the XML attribute will be actually removed.
-     * <p/>
-     * Note that the caller MUST ensure that modifying the underlying XML model is
-     * safe and must take care of marking the model as dirty if necessary.
-     *
-     * @see AndroidEditor#editXmlModel(Runnable)
-     *
-     * @param uiAttr The attribute node to commit. Must be a child of this UiElementNode.
-     * @param newValue The new value to set.
-     * @return True if the XML attribute was modified or removed, false if nothing changed.
-     */
-    public boolean commitAttributeToXml(UiAttributeNode uiAttr, String newValue) {
-        // Get (or create) the underlying XML element node that contains the attributes.
-        Node element = prepareCommit();
-        if (element != null && uiAttr != null) {
-            String attrLocalName = uiAttr.getDescriptor().getXmlLocalName();
-            String attrNsUri = uiAttr.getDescriptor().getNamespaceUri();
-
-            NamedNodeMap attrMap = element.getAttributes();
-            if (newValue == null || newValue.length() == 0) {
-                // Remove attribute if it's empty
-                if (attrMap.getNamedItemNS(attrNsUri, attrLocalName) != null) {
-                    attrMap.removeNamedItemNS(attrNsUri, attrLocalName);
-                    return true;
-                }
-            } else {
-                // Add or replace an attribute
-                Document doc = element.getOwnerDocument();
-                if (doc != null) {
-                    Attr attr = doc.createAttributeNS(attrNsUri, attrLocalName);
-                    attr.setValue(newValue);
-                    attr.setPrefix(lookupNamespacePrefix(element, attrNsUri));
-                    attrMap.setNamedItemNS(attr);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Helper method to commit all dirty attributes values to XML.
-     * <p/>
-     * This method is useful if {@link #setAttributeValue(String, String, boolean)} has been
-     * called more than once and all the attributes marked as dirty must be commited to the
-     * XML. It calls {@link #commitAttributeToXml(UiAttributeNode, String)} on each dirty
-     * attribute.
-     * <p/>
-     * Note that the caller MUST ensure that modifying the underlying XML model is
-     * safe and must take care of marking the model as dirty if necessary.
-     *
-     * @see AndroidEditor#editXmlModel(Runnable)
-     *
-     * @return True if one or more values were actually modified or removed,
-     *         false if nothing changed.
-     */
-    public boolean commitDirtyAttributesToXml() {
-        boolean result = false;
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-
-        for (Entry<AttributeDescriptor, UiAttributeNode> entry : attributeMap.entrySet()) {
-            UiAttributeNode ui_attr = entry.getValue();
-            if (ui_attr.isDirty()) {
-                result |= commitAttributeToXml(ui_attr, ui_attr.getCurrentValue());
-                ui_attr.setDirty(false);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Returns the namespace prefix matching the requested namespace URI.
-     * If no such declaration is found, returns the default "android" prefix.
-     *
-     * @param node The current node. Must not be null.
-     * @param nsUri The namespace URI of which the prefix is to be found,
-     *              e.g. SdkConstants.NS_RESOURCES
-     * @return The first prefix declared or the default "android" prefix.
-     */
-    private String lookupNamespacePrefix(Node node, String nsUri) {
-        // Note: Node.lookupPrefix is not implemented in wst/xml/core NodeImpl.java
-        // The following code emulates this simple call:
-        //   String prefix = node.lookupPrefix(SdkConstants.NS_RESOURCES);
-
-        // if the requested URI is null, it denotes an attribute with no namespace.
-        if (nsUri == null) {
-            return null;
-        }
-
-        // per XML specification, the "xmlns" URI is reserved
-        if (XmlnsAttributeDescriptor.XMLNS_URI.equals(nsUri)) {
-            return "xmlns"; //$NON-NLS-1$
-        }
-
-        HashSet<String> visited = new HashSet<String>();
-        Document doc = node == null ? null : node.getOwnerDocument();
-
-        for (; node != null && node.getNodeType() == Node.ELEMENT_NODE;
-               node = node.getParentNode()) {
-            NamedNodeMap attrs = node.getAttributes();
-            for (int n = attrs.getLength() - 1; n >= 0; --n) {
-                Node attr = attrs.item(n);
-                if ("xmlns".equals(attr.getPrefix())) {  //$NON-NLS-1$
-                    String uri = attr.getNodeValue();
-                    String nsPrefix = attr.getLocalName();
-                    // Is this the URI we are looking for? If yes, we found its prefix.
-                    if (nsUri.equals(uri)) {
-                        return nsPrefix;
-                    }
-                    visited.add(nsPrefix);
-                }
-            }
-        }
-
-        // Use a sensible default prefix if we can't find one.
-        // We need to make sure the prefix is not one that was declared in the scope
-        // visited above. Use a default namespace prefix "android" for the Android resource
-        // NS and use "ns" for all other custom namespaces.
-        String prefix = SdkConstants.NS_RESOURCES.equals(nsUri) ? "android" : "ns"; //$NON-NLS-1$ //$NON-NLS-2$
-        String base = prefix;
-        for (int i = 1; visited.contains(prefix); i++) {
-            prefix = base + Integer.toString(i);
-        }
-
-        // Also create & define this prefix/URI in the XML document as an attribute in the
-        // first element of the document.
-        if (doc != null) {
-            node = doc.getFirstChild();
-            while (node != null && node.getNodeType() != Node.ELEMENT_NODE) {
-                node = node.getNextSibling();
-            }
-            if (node != null) {
-                Attr attr = doc.createAttributeNS(XmlnsAttributeDescriptor.XMLNS_URI, prefix);
-                attr.setValue(nsUri);
-                attr.setPrefix("xmlns"); //$NON-NLS-1$
-                node.getAttributes().setNamedItemNS(attr);
-            }
-        }
-
-        return prefix;
-    }
-
-    /**
-     * Utility method to internally set the value of a text attribute for the current
-     * UiElementNode.
-     * <p/>
-     * This method is a helper. It silently ignores the errors such as the requested
-     * attribute not being present in the element or attribute not being settable.
-     * It accepts inherited attributes (such as layout).
-     * <p/>
-     * This does not commit to the XML model. It does mark the attribute node as dirty.
-     * This is up to the caller.
-     *
-     * @see #commitAttributeToXml(UiAttributeNode, String)
-     * @see #commitDirtyAttributesToXml()
-     *
-     * @param attrXmlName The XML name of the attribute to modify
-     * @param value The new value for the attribute. If set to null, the attribute is removed.
-     * @param override True if the value must be set even if one already exists.
-     * @return The {@link UiAttributeNode} that has been modified or null.
-     */
-    public UiAttributeNode setAttributeValue(String attrXmlName, String value, boolean override) {
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-
-        if (value == null) {
-            value = ""; //$NON-NLS-1$ -- this removes an attribute
-        }
-
-        for (Entry<AttributeDescriptor, UiAttributeNode> entry : attributeMap.entrySet()) {
-            AttributeDescriptor ui_desc = entry.getKey();
-            if (ui_desc.getXmlLocalName().equals(attrXmlName)) {
-                UiAttributeNode ui_attr = entry.getValue();
-                // Not all attributes are editable, ignore those which are not
-                if (ui_attr instanceof IUiSettableAttributeNode) {
-                    String current = ui_attr.getCurrentValue();
-                    // Only update (and mark as dirty) if the attribute did not have any
-                    // value or if the value was different.
-                    if (override || current == null || !current.equals(value)) {
-                        ((IUiSettableAttributeNode) ui_attr).setCurrentValue(value);
-                        // mark the attribute as dirty since their internal content
-                        // as been modified, but not the underlying XML model
-                        ui_attr.setDirty(true);
-                        return ui_attr;
-                    }
-                }
-                break;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Utility method to retrieve the internal value of an attribute.
-     * <p/>
-     * Note that this retrieves the *field* value if the attribute has some UI, and
-     * not the actual XML value. They may differ if the attribute is dirty.
-     *
-     * @param attrXmlName The XML name of the attribute to modify
-     * @return The current internal value for the attribute or null in case of error.
-     */
-    public String getAttributeValue(String attrXmlName) {
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-
-        for (Entry<AttributeDescriptor, UiAttributeNode> entry : attributeMap.entrySet()) {
-            AttributeDescriptor ui_desc = entry.getKey();
-            if (ui_desc.getXmlLocalName().equals(attrXmlName)) {
-                UiAttributeNode ui_attr = entry.getValue();
-                return ui_attr.getCurrentValue();
-            }
-        }
-        return null;
-    }
-
-    // ------ IPropertySource methods
-
-    public Object getEditableValue() {
-        return null;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
-     *
-     * Returns the property descriptor for this node. Since the descriptors are not linked to the
-     * data, the AttributeDescriptor are used directly.
-     */
-    public IPropertyDescriptor[] getPropertyDescriptors() {
-        List<IPropertyDescriptor> propDescs = new ArrayList<IPropertyDescriptor>();
-
-        // get the standard descriptors
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-        Set<AttributeDescriptor> keys = attributeMap.keySet();
-
-
-        // we only want the descriptor that do implement the IPropertyDescriptor interface.
-        for (AttributeDescriptor key : keys) {
-            if (key instanceof IPropertyDescriptor) {
-                propDescs.add((IPropertyDescriptor)key);
-            }
-        }
-
-        // now get the descriptor from the unknown attributes
-        for (UiAttributeNode unknownNode : mUnknownUiAttributes) {
-            if (unknownNode.getDescriptor() instanceof IPropertyDescriptor) {
-                propDescs.add((IPropertyDescriptor)unknownNode.getDescriptor());
-            }
-        }
-
-        // TODO cache this maybe, as it's not going to change (except for unknown descriptors)
-        return propDescs.toArray(new IPropertyDescriptor[propDescs.size()]);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
-     *
-     * Returns the value of a given property. The id is the result of IPropertyDescriptor.getId(),
-     * which return the AttributeDescriptor itself.
-     */
-    public Object getPropertyValue(Object id) {
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-
-        UiAttributeNode attribute = attributeMap.get(id);
-
-        if (attribute == null) {
-            // look for the id in the unknown attributes.
-            for (UiAttributeNode unknownAttr : mUnknownUiAttributes) {
-                if (id == unknownAttr.getDescriptor()) {
-                    return unknownAttr;
-                }
-            }
-        }
-
-        return attribute;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
-     *
-     * Returns whether the property is set. In our case this is if the string is non empty.
-     */
-    public boolean isPropertySet(Object id) {
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-
-        UiAttributeNode attribute = attributeMap.get(id);
-
-        if (attribute != null) {
-            return attribute.getCurrentValue().length() > 0;
-        }
-
-        // look for the id in the unknown attributes.
-        for (UiAttributeNode unknownAttr : mUnknownUiAttributes) {
-            if (id == unknownAttr.getDescriptor()) {
-                return unknownAttr.getCurrentValue().length() > 0;
-            }
-        }
-
-        return false;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
-     *
-     * Reset the property to its default value. For now we simply empty it.
-     */
-    public void resetPropertyValue(Object id) {
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-
-        UiAttributeNode attribute = attributeMap.get(id);
-        if (attribute != null) {
-            // TODO: reset the value of the attribute
-
-            return;
-        }
-
-        // look for the id in the unknown attributes.
-        for (UiAttributeNode unknownAttr : mUnknownUiAttributes) {
-            if (id == unknownAttr.getDescriptor()) {
-                // TODO: reset the value of the attribute
-
-                return;
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
-     *
-     * Set the property value. id is the result of IPropertyDescriptor.getId(), which is the
-     * AttributeDescriptor itself. Value should be a String.
-     */
-    public void setPropertyValue(Object id, Object value) {
-        HashMap<AttributeDescriptor, UiAttributeNode> attributeMap = getInternalUiAttributes();
-
-        UiAttributeNode attribute = attributeMap.get(id);
-
-        if (attribute == null) {
-            // look for the id in the unknown attributes.
-            for (UiAttributeNode unknownAttr : mUnknownUiAttributes) {
-                if (id == unknownAttr.getDescriptor()) {
-                    attribute = unknownAttr;
-                    break;
-                }
-            }
-        }
-
-        if (attribute != null) {
-
-            // get the current value and compare it to the new value
-            String oldValue = attribute.getCurrentValue();
-            final String newValue = (String)value;
-
-            if (oldValue.equals(newValue)) {
-                return;
-            }
-
-            final UiAttributeNode fAttribute = attribute;
-            AndroidEditor editor = getEditor();
-            editor.editXmlModel(new Runnable() {
-                public void run() {
-                    commitAttributeToXml(fAttribute, newValue);
-                }
-            });
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiFlagAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiFlagAttributeNode.java
deleted file mode 100644
index eb9903f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiFlagAttributeNode.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.FlagAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.resource.FontDescriptor;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.dialogs.SelectionStatusDialog;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Represents an XML attribute that is defined by a set of flag values,
- * i.e. enum names separated by pipe (|) characters.
- * 
- * Note: in Android resources, a "flag" is a list of fixed values where one or
- * more values can be selected using an "or", e.g. "align='left|top'".
- * By contrast, an "enum" is a list of fixed values of which only one can be
- * selected at a given time, e.g. "gravity='right'".
- * <p/>
- * This class handles the "flag" case.
- * The "enum" case is done using {@link UiListAttributeNode}.
- */
-public class UiFlagAttributeNode extends UiTextAttributeNode {
-
-    public UiFlagAttributeNode(FlagAttributeDescriptor attributeDescriptor,
-            UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-
-    /* (non-java doc)
-     * Creates a label widget and an associated text field.
-     * <p/>
-     * As most other parts of the android manifest editor, this assumes the
-     * parent uses a table layout with 2 columns.
-     */
-    @Override
-    public void createUiControl(Composite parent, IManagedForm managedForm) {
-        setManagedForm(managedForm);
-        FormToolkit toolkit = managedForm.getToolkit();
-        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-
-        Label label = toolkit.createLabel(parent, desc.getUiName());
-        label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
-        SectionHelper.addControlTooltip(label, DescriptorsUtils.formatTooltip(desc.getTooltip()));
-
-        Composite composite = toolkit.createComposite(parent);
-        composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
-        GridLayout gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        composite.setLayout(gl);
-        // Fixes missing text borders under GTK... also requires adding a 1-pixel margin
-        // for the text field below
-        toolkit.paintBordersFor(composite);
-        
-        final Text text = toolkit.createText(composite, getCurrentValue());
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalIndent = 1;  // Needed by the fixed composite borders under GTK
-        text.setLayoutData(gd);
-        final Button selectButton = toolkit.createButton(composite, "Select...", SWT.PUSH);
-        
-        setTextWidget(text);
-        
-        selectButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-
-                String currentText = getTextWidgetValue();
-                
-                String result = showDialog(selectButton.getShell(), currentText);
-                
-                if (result != null) {
-                    setTextWidgetValue(result);
-                }
-            }
-        });
-    }
-
-    /**
-     * Get the flag names, either from the initial names set in the attribute
-     * or by querying the framework resource parser.
-     * 
-     * {@inheritDoc}
-     */
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        String attr_name = getDescriptor().getXmlLocalName();
-        String element_name = getUiParent().getDescriptor().getXmlName();
-        
-        String[] values = null;
-        
-        if (getDescriptor() instanceof FlagAttributeDescriptor &&
-                ((FlagAttributeDescriptor) getDescriptor()).getNames() != null) {
-            // Get enum values from the descriptor
-            values = ((FlagAttributeDescriptor) getDescriptor()).getNames();
-        }
-
-        if (values == null) {
-            // or from the AndroidTargetData
-            UiElementNode uiNode = getUiParent();
-            AndroidEditor editor = uiNode.getEditor();
-            AndroidTargetData data = editor.getTargetData();
-            if (data != null) {
-                values = data.getAttributeValues(element_name, attr_name);
-            }
-        }
-        
-        return values;
-    }
-    
-    /**
-     * Shows a dialog letting the user choose a set of enum, and returns a string
-     * containing the result.
-     */
-    public String showDialog(Shell shell, String currentValue) {
-        FlagSelectionDialog dlg = new FlagSelectionDialog(
-                shell, currentValue.trim().split("\\s*\\|\\s*")); //$NON-NLS-1$
-        dlg.open();
-        Object[] result = dlg.getResult();
-        if (result != null) {
-            StringBuilder buf = new StringBuilder();
-            for (Object name : result) {
-                if (name instanceof String) {
-                    if (buf.length() > 0) {
-                        buf.append("|"); //$NON-NLS-1$
-                    }
-                    buf.append(name);
-                }
-            }
-            
-            return buf.toString();
-        }
-        
-        return null;
-
-    }
-    
-    /**
-     * Displays a list of flag names with checkboxes.
-     */
-    private class FlagSelectionDialog extends SelectionStatusDialog {
-
-        private Set<String> mCurrentSet;
-        private Table mTable;
-
-        public FlagSelectionDialog(Shell parentShell, String[] currentNames) {
-            super(parentShell);
-            
-            mCurrentSet = new HashSet<String>();
-            for (String name : currentNames) {
-                if (name.length() > 0) {
-                    mCurrentSet.add(name);
-                }
-            }
-
-            int shellStyle = getShellStyle();
-            setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
-        }
-
-        @Override
-        protected void computeResult() {
-            if (mTable != null) {
-                ArrayList<String> results = new ArrayList<String>();
-                
-                for (TableItem item : mTable.getItems()) {
-                    if (item.getChecked()) {
-                        results.add((String)item.getData());
-                    }
-                }
-                
-                setResult(results);
-            }
-        }
-
-        @Override
-        protected Control createDialogArea(Composite parent) {
-            Composite composite= new Composite(parent, SWT.NONE);
-            composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-            composite.setLayout(new GridLayout(1, true));
-            composite.setFont(parent.getFont());
-            
-            Label label = new Label(composite, SWT.NONE);
-            label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-            label.setText(String.format("Select the flag values for attribute %1$s:",
-                    ((FlagAttributeDescriptor) getDescriptor()).getUiName()));
- 
-            mTable = new Table(composite, SWT.CHECK | SWT.BORDER);
-            GridData data = new GridData();
-            // The 60,18 hints are the ones used by AbstractElementListSelectionDialog
-            data.widthHint = convertWidthInCharsToPixels(60);
-            data.heightHint = convertHeightInCharsToPixels(18);
-            data.grabExcessVerticalSpace = true;
-            data.grabExcessHorizontalSpace = true;
-            data.horizontalAlignment = GridData.FILL;
-            data.verticalAlignment = GridData.FILL;
-            mTable.setLayoutData(data);
-
-            mTable.setHeaderVisible(false);
-            final TableColumn column = new TableColumn(mTable, SWT.NONE);
-
-            // List all the expected flag names and check those which are currently used
-            String[] names = getPossibleValues(null);
-            if (names != null) {
-                for (String name : names) {
-                    TableItem item = new TableItem(mTable, SWT.NONE);
-                    item.setText(name);
-                    item.setData(name);
-                    
-                    boolean hasName = mCurrentSet.contains(name);
-                    item.setChecked(hasName);
-                    if (hasName) {
-                        mCurrentSet.remove(name);
-                    }
-                }
-            }
-
-            // If there are unknown flag names currently used, display them at the end if the
-            // table already checked.
-            if (!mCurrentSet.isEmpty()) {
-                FontDescriptor fontDesc = JFaceResources.getDialogFontDescriptor();
-                fontDesc = fontDesc.withStyle(SWT.ITALIC);
-                Font font = fontDesc.createFont(JFaceResources.getDialogFont().getDevice());
-
-                for (String name : mCurrentSet) {
-                    TableItem item = new TableItem(mTable, SWT.NONE);
-                    item.setText(String.format("%1$s (unknown flag)", name));
-                    item.setData(name);
-                    item.setChecked(true);
-                    item.setFont(font);
-                }
-            }
-            
-            // Add a listener that will resize the column to the full width of the table
-            // so that only one column appears in the table even if the dialog is resized.
-            ControlAdapter listener = new ControlAdapter() {
-                @Override
-                public void controlResized(ControlEvent e) {
-                    Rectangle r = mTable.getClientArea();
-                    column.setWidth(r.width);
-                }
-            };
-            
-            mTable.addControlListener(listener);
-            listener.controlResized(null /* event not used */);
-
-            // Add a selection listener that will check/uncheck items when they are double-clicked
-            mTable.addSelectionListener(new SelectionAdapter() {
-                /** Default selection means double-click on "most" platforms */
-                @Override
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    if (e.item instanceof TableItem) {
-                        TableItem i = (TableItem) e.item;
-                        i.setChecked(!i.getChecked());
-                    }
-                    super.widgetDefaultSelected(e);
-                } 
-            });
-            
-            Dialog.applyDialogFont(composite);            
-            setHelpAvailable(false);
-            
-            return composite;
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java
deleted file mode 100644
index 3354b76..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ListAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-
-/**
- * Represents an XML attribute which has possible built-in values, and can be modified by
- * an editable Combo box.
- * <p/>
- * See {@link UiTextAttributeNode} for more information.
- */
-public class UiListAttributeNode extends UiAbstractTextAttributeNode {
-
-    protected Combo mCombo;
-
-    public UiListAttributeNode(ListAttributeDescriptor attributeDescriptor,
-            UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-    
-    /* (non-java doc)
-     * Creates a label widget and an associated text field.
-     * <p/>
-     * As most other parts of the android manifest editor, this assumes the
-     * parent uses a table layout with 2 columns.
-     */
-    @Override
-    public final void createUiControl(final Composite parent, IManagedForm managedForm) {
-        FormToolkit toolkit = managedForm.getToolkit();
-        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-
-        Label label = toolkit.createLabel(parent, desc.getUiName());
-        label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
-        SectionHelper.addControlTooltip(label, DescriptorsUtils.formatTooltip(desc.getTooltip()));
-
-        int style = SWT.DROP_DOWN;
-        mCombo = new Combo(parent, style); 
-        TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE);
-        twd.maxWidth = 100;
-        mCombo.setLayoutData(twd);
-        
-        fillCombo();
-        
-        setTextWidgetValue(getCurrentValue());
-        
-        mCombo.addModifyListener(new ModifyListener() {
-            /**
-             * Sent when the text is modified, whether by the user via manual
-             * input or programmatic input via setText().
-             * <p/>
-             * Simply mark the attribute as dirty if it really changed.
-             * The container SectionPart will collect these flag and manage them.
-             */
-            public void modifyText(ModifyEvent e) {
-                if (!isInInternalTextModification() &&
-                        !isDirty() &&
-                        mCombo != null &&
-                        getCurrentValue() != null &&
-                        !mCombo.getText().equals(getCurrentValue())) {
-                    setDirty(true);
-                }
-            }            
-        });
-
-        // Remove self-reference when the widget is disposed
-        mCombo.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                mCombo = null;
-            }
-        });
-    }
-    
-    protected void fillCombo() {
-        String[] values = getPossibleValues(null);
-
-        if (values == null) {
-            AdtPlugin.log(IStatus.ERROR,
-                    "FrameworkResourceManager did not provide values yet for %1$s",
-                    getDescriptor().getXmlLocalName());
-        } else {
-            for (String value : values) {
-                mCombo.add(value);
-            }
-        }
-    }
-    
-    /**
-     * Get the list values, either from the initial values set in the attribute
-     * or by querying the framework resource parser.
-     * 
-     * {@inheritDoc}
-     */
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        AttributeDescriptor descriptor = getDescriptor();
-        UiElementNode uiParent = getUiParent();
-
-        String attr_name = descriptor.getXmlLocalName();
-        String element_name = uiParent.getDescriptor().getXmlName();
-        
-        // FrameworkResourceManager expects a specific prefix for the attribute.
-        String nsPrefix = "";
-        if (SdkConstants.NS_RESOURCES.equals(descriptor.getNamespaceUri())) {
-            nsPrefix = "android:"; //$NON-NLS-1$
-        } else if (XmlnsAttributeDescriptor.XMLNS_URI.equals(descriptor.getNamespaceUri())) {
-            nsPrefix = "xmlns:"; //$NON-NLS-1$
-        }
-        attr_name = nsPrefix + attr_name;
-        
-        String[] values = null;
-        
-        if (descriptor instanceof ListAttributeDescriptor &&
-                ((ListAttributeDescriptor) descriptor).getValues() != null) {
-            // Get enum values from the descriptor
-            values = ((ListAttributeDescriptor) descriptor).getValues();
-        }
-
-        if (values == null) {
-            // or from the AndroidTargetData
-            UiElementNode uiNode = getUiParent();
-            AndroidEditor editor = uiNode.getEditor();
-            AndroidTargetData data = editor.getTargetData();
-            if (data != null) {
-                // get the great-grand-parent descriptor.
-                
-                // the parent should always exist.
-                UiElementNode grandParentNode = uiParent.getUiParent();
-    
-                String greatGrandParentNodeName = null;
-                if (grandParentNode != null) {
-                    UiElementNode greatGrandParentNode = grandParentNode.getUiParent();
-                    if (greatGrandParentNode != null) {
-                        greatGrandParentNodeName =
-                            greatGrandParentNode.getDescriptor().getXmlName();
-                    }
-                }
-            
-                values = data.getAttributeValues(element_name, attr_name, greatGrandParentNodeName);
-            }
-        }
-        
-        return values;
-    }
-
-    @Override
-    public String getTextWidgetValue() {
-        if (mCombo != null) {
-            return mCombo.getText();
-        }
-        
-        return null;
-    }
-
-    @Override
-    public final boolean isValid() {
-        return mCombo != null;
-    }
-
-    @Override
-    public void setTextWidgetValue(String value) {
-        if (mCombo != null) {
-            mCombo.setText(value);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java
deleted file mode 100644
index be2384c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.ui.ReferenceChooserDialog;
-import com.android.ide.eclipse.adt.internal.ui.ResourceChooser;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Represents an XML attribute for a resource that can be modified using a simple text field or
- * a dialog to choose an existing resource.
- * <p/>
- * It can be configured to represent any kind of resource, by providing the desired
- * {@link ResourceType} in the constructor.
- * <p/>
- * See {@link UiTextAttributeNode} for more information.
- */
-public class UiResourceAttributeNode extends UiTextAttributeNode {
-    
-    private ResourceType mType;
-    
-    public UiResourceAttributeNode(ResourceType type,
-            AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-        
-        mType = type;
-    }
-
-    /* (non-java doc)
-     * Creates a label widget and an associated text field.
-     * <p/>
-     * As most other parts of the android manifest editor, this assumes the
-     * parent uses a table layout with 2 columns.
-     */
-    @Override
-    public void createUiControl(final Composite parent, IManagedForm managedForm) {
-        setManagedForm(managedForm);
-        FormToolkit toolkit = managedForm.getToolkit();
-        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-
-        Label label = toolkit.createLabel(parent, desc.getUiName());
-        label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
-        SectionHelper.addControlTooltip(label, DescriptorsUtils.formatTooltip(desc.getTooltip()));
-
-        Composite composite = toolkit.createComposite(parent);
-        composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
-        GridLayout gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        composite.setLayout(gl);
-        // Fixes missing text borders under GTK... also requires adding a 1-pixel margin
-        // for the text field below
-        toolkit.paintBordersFor(composite);
-        
-        final Text text = toolkit.createText(composite, getCurrentValue());
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalIndent = 1;  // Needed by the fixed composite borders under GTK
-        text.setLayoutData(gd);
-        Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
-        
-        setTextWidget(text);
-
-        // TODO Add a validator using onAddModifyListener
-        
-        browseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                String result = showDialog(parent.getShell(), text.getText().trim());
-                if (result != null) {
-                    text.setText(result);
-                }
-            }
-        });
-    }
-    
-    /**
-     * Shows a dialog letting the user choose a set of enum, and returns a string
-     * containing the result.
-     */
-    public String showDialog(Shell shell, String currentValue) {
-        // we need to get the project of the file being edited.
-        UiElementNode uiNode = getUiParent();
-        AndroidEditor editor = uiNode.getEditor();
-        IProject project = editor.getProject();
-        if (project != null) {
-            // get the resource repository for this project and the system resources.
-            IResourceRepository projectRepository =
-                ResourceManager.getInstance().getProjectResources(project);
-            
-            if (mType != null) {
-                // get the Target Data to get the system resources
-                AndroidTargetData data = editor.getTargetData();
-                IResourceRepository systemRepository = data.getSystemResources();
-
-                // open a resource chooser dialog for specified resource type.
-                ResourceChooser dlg = new ResourceChooser(project,
-                        mType,
-                        projectRepository,
-                        systemRepository,
-                        shell);
-
-                dlg.setCurrentResource(currentValue);
-
-                if (dlg.open() == Window.OK) {
-                    return dlg.getCurrentResource();
-                }
-            } else {
-                ReferenceChooserDialog dlg = new ReferenceChooserDialog(
-                        project,
-                        projectRepository,
-                        shell);
-
-                dlg.setCurrentResource(currentValue);
-
-                if (dlg.open() == Window.OK) {
-                    return dlg.getCurrentResource();
-                }
-            }
-        }
-
-        return null;
-    }
-    
-    /**
-     * Gets all the values one could use to auto-complete a "resource" value in an XML
-     * content assist.
-     * <p/>
-     * Typically the user is editing the value of an attribute in a resource XML, e.g.
-     *   <pre> "&lt;Button android:test="@string/my_[caret]_string..." </pre>
-     * <p/>
-     * 
-     * "prefix" is the value that the user has typed so far (or more exactly whatever is on the
-     * left side of the insertion point). In the example above it would be "@style/my_".
-     * <p/>
-     * 
-     * To avoid a huge long list of values, the completion works on two levels:
-     * <ul>
-     * <li> If a resource type as been typed so far (e.g. "@style/"), then limit the values to
-     *      the possible completions that match this type.
-     * <li> If no resource type as been typed so far, then return the various types that could be
-     *      completed. So if the project has only strings and layouts resources, for example,
-     *      the returned list will only include "@string/" and "@layout/".
-     * </ul>
-     * 
-     * Finally if anywhere in the string we find the special token "android:", we use the
-     * current framework system resources rather than the project resources.
-     * This works for both "@android:style/foo" and "@style/android:foo" conventions even though
-     * the reconstructed name will always be of the former form.
-     * 
-     * Note that "android:" here is a keyword specific to Android resources and should not be
-     * mixed with an XML namespace for an XML attribute name. 
-     */
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        IResourceRepository repository = null;
-        boolean isSystem = false;
-
-        UiElementNode uiNode = getUiParent();
-        AndroidEditor editor = uiNode.getEditor();
-
-        if (prefix == null || prefix.indexOf("android:") < 0) {
-            IProject project = editor.getProject();
-            if (project != null) {
-                // get the resource repository for this project and the system resources.
-                repository = ResourceManager.getInstance().getProjectResources(project);
-            }
-        } else {
-            // If there's a prefix with "android:" in it, use the system resources
-            //
-            // TODO find a way to only list *public* framework resources here.
-            AndroidTargetData data = editor.getTargetData();
-            repository = data.getSystemResources();
-            isSystem = true;
-        }
-
-        // Get list of potential resource types, either specific to this project
-        // or the generic list.
-        ResourceType[] resTypes = (repository != null) ?
-                    repository.getAvailableResourceTypes() :
-                    ResourceType.values();
-
-        // Get the type name from the prefix, if any. It's any word before the / if there's one
-        String typeName = null;
-        if (prefix != null) {
-            Matcher m = Pattern.compile(".*?([a-z]+)/.*").matcher(prefix);
-            if (m.matches()) {
-                typeName = m.group(1);
-            }
-        }
-
-        // Now collect results
-        ArrayList<String> results = new ArrayList<String>();
-
-        if (typeName == null) {
-            // This prefix does not have a / in it, so the resource string is either empty
-            // or does not have the resource type in it. Simply offer the list of potential
-            // resource types.
-
-            for (ResourceType resType : resTypes) {
-                results.add("@" + resType.getName() + "/");
-                if (resType == ResourceType.ID) {
-                    // Also offer the + version to create an id from scratch
-                    results.add("@+" + resType.getName() + "/");
-                }
-            }
-        } else if (repository != null) {
-            // We have a style name and a repository. Find all resources that match this
-            // type and recreate suggestions out of them.
-
-            ResourceType resType = ResourceType.getEnum(typeName);
-            if (resType != null) {
-                StringBuilder sb = new StringBuilder();
-                sb.append('@');
-                if (prefix.indexOf('+') >= 0) {
-                    sb.append('+');
-                }
-                
-                if (isSystem) {
-                    sb.append("android:");
-                }
-                
-                sb.append(typeName).append('/');
-                String base = sb.toString();
-
-                for (ResourceItem item : repository.getResources(resType)) {
-                    results.add(base + item.getName());
-                }
-            }
-        }
-
-        return results.toArray(new String[results.size()]);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiSeparatorAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiSeparatorAttributeNode.java
deleted file mode 100644
index 3d20062..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiSeparatorAttributeNode.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.eclipse.ui.forms.widgets.TableWrapLayout;
-import org.w3c.dom.Node;
-
-/**
- * {@link UiSeparatorAttributeNode} does not represent any real attribute.
- * <p/>
- * It is used to separate groups of attributes visually.
- */
-public class UiSeparatorAttributeNode extends UiAttributeNode {
-
-    /** Creates a new {@link UiAttributeNode} linked to a specific {@link AttributeDescriptor} */
-    public UiSeparatorAttributeNode(SeparatorAttributeDescriptor attrDesc,
-            UiElementNode uiParent) {
-        super(attrDesc, uiParent);
-    }
-
-    /** Returns the current value of the node. */
-    @Override
-    public String getCurrentValue() {
-        // There is no value here.
-        return null;
-    }
-
-    /**
-     * Sets whether the attribute is dirty and also notifies the editor some part's dirty
-     * flag as changed.
-     * <p/>
-     * Subclasses should set the to true as a result of user interaction with the widgets in
-     * the section and then should set to false when the commit() method completed.
-     */
-    @Override
-    public void setDirty(boolean isDirty) {
-        // This is never dirty.
-    }
-    
-    /**
-     * Called once by the parent user interface to creates the necessary
-     * user interface to edit this attribute.
-     * <p/>
-     * This method can be called more than once in the life cycle of an UI node,
-     * typically when the UI is part of a master-detail tree, as pages are swapped.
-     * 
-     * @param parent The composite where to create the user interface.
-     * @param managedForm The managed form owning this part.
-     */
-    @Override
-    public void createUiControl(Composite parent, IManagedForm managedForm) {
-        FormToolkit toolkit = managedForm.getToolkit();
-        Composite row = toolkit.createComposite(parent);
-        
-        TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB);
-        if (parent.getLayout() instanceof TableWrapLayout) {
-            twd.colspan = ((TableWrapLayout) parent.getLayout()).numColumns;
-        }
-        row.setLayoutData(twd);
-        row.setLayout(new GridLayout(3, false /* equal width */));
-
-        Label sep = toolkit.createSeparator(row, SWT.HORIZONTAL);
-        GridData gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
-        gd.widthHint = 16;
-        sep.setLayoutData(gd);
-
-        Label label = toolkit.createLabel(row, getDescriptor().getXmlLocalName());
-        label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
-
-        sep = toolkit.createSeparator(row, SWT.HORIZONTAL);
-        sep.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-    }
-    
-    /**
-     * No completion values for this UI attribute.
-     * 
-     * {@inheritDoc}
-     */
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        return null;
-    }
-    
-    /**
-     * Called when the XML is being loaded or has changed to
-     * update the value held by this user interface attribute node.
-     * <p/>
-     * The XML Node <em>may</em> be null, which denotes that the attribute is not
-     * specified in the XML model. In general, this means the "default" value of the
-     * attribute should be used.
-     * <p/>
-     * The caller doesn't really know if attributes have changed,
-     * so it will call this to refresh the attribute anyway. It's up to the
-     * UI implementation to minimize refreshes.
-     * 
-     * @param xml_attribute_node
-     */
-    @Override
-    public void updateValue(Node xml_attribute_node) {
-        // No value to update.
-    }
-
-    /**
-     * Called by the user interface when the editor is saved or its state changed
-     * and the modified attributes must be committed (i.e. written) to the XML model.
-     * <p/>
-     * Important behaviors:
-     * <ul>
-     * <li>The caller *must* have called IStructuredModel.aboutToChangeModel before.
-     *     The implemented methods must assume it is safe to modify the XML model.
-     * <li>On success, the implementation *must* call setDirty(false).
-     * <li>On failure, the implementation can fail with an exception, which
-     *     is trapped and logged by the caller, or do nothing, whichever is more
-     *     appropriate.
-     * </ul>
-     */
-    @Override
-    public void commit() {
-        // No value to commit.
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextAttributeNode.java
deleted file mode 100644
index 40496ab..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextAttributeNode.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-
-/**
- * Represents an XML attribute in that can be modified using a simple text field
- * in the XML editor's user interface.
- * <p/>
- * The XML attribute has no default value. When unset, the text field is blank.
- * When updating the XML, if the field is empty, the attribute will be removed
- * from the XML element.  
- * <p/>
- * See {@link UiAttributeNode} for more information.
- */
-public class UiTextAttributeNode extends UiAbstractTextAttributeNode {
-
-    /** Text field */
-    private Text mText;
-    /** The managed form, set only once createUiControl has been called. */
-    private IManagedForm mManagedForm;
-
-    public UiTextAttributeNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-    
-    /* (non-java doc)
-     * Creates a label widget and an associated text field.
-     * <p/>
-     * As most other parts of the android manifest editor, this assumes the
-     * parent uses a table layout with 2 columns.
-     */
-    @Override
-    public void createUiControl(Composite parent, IManagedForm managedForm) {
-        setManagedForm(managedForm);
-        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-        Text text = SectionHelper.createLabelAndText(parent, managedForm.getToolkit(),
-                desc.getUiName(), getCurrentValue(),
-                DescriptorsUtils.formatTooltip(desc.getTooltip()));
-
-        setTextWidget(text);
-    }
-
-    /**
-     * No completion values for this UI attribute.
-     * 
-     * {@inheritDoc}
-     */
-    @Override
-    public String[] getPossibleValues(String prefix) {
-        return null;
-    }
-    
-    /**
-     * Sets the internal managed form.
-     * This is usually set by createUiControl.
-     */
-    protected void setManagedForm(IManagedForm managedForm) {
-         mManagedForm = managedForm;
-    }
-    
-    /**
-     * @return The managed form, set only once createUiControl has been called.
-     */
-    protected IManagedForm getManagedForm() {
-        return mManagedForm;
-    }
-    
-    /* (non-java doc)
-     * Returns if the attribute node is valid, and its UI has been created.
-     */
-    @Override
-    public boolean isValid() {
-        return mText != null;
-    }
-
-    @Override
-    public String getTextWidgetValue() {
-        if (mText != null) {
-            return mText.getText();
-        }
-        
-        return null;
-    }
-
-    @Override
-    public void setTextWidgetValue(String value) {
-        if (mText != null) {
-            mText.setText(value);
-        }
-    }
-
-    /**
-     * Sets the Text widget object, and prepares it to handle modification and synchronization
-     * with the XML node.
-     * @param textWidget
-     */
-    protected final void setTextWidget(Text textWidget) {
-        mText = textWidget;
- 
-        if (textWidget != null) {
-            // Sets the with hint for the text field. Derived classes can always override it.
-            // This helps the grid layout to resize correctly on smaller screen sizes.
-            Object data = textWidget.getLayoutData();
-            if (data == null) {
-            } else if (data instanceof GridData) {
-                ((GridData)data).widthHint = AndroidEditor.TEXT_WIDTH_HINT;
-            } else if (data instanceof TableWrapData) {
-                ((TableWrapData)data).maxWidth = 100;
-            }
-            
-            mText.addModifyListener(new ModifyListener() {
-                /**
-                 * Sent when the text is modified, whether by the user via manual
-                 * input or programmatic input via setText().
-                 * <p/>
-                 * Simply mark the attribute as dirty if it really changed.
-                 * The container SectionPart will collect these flag and manage them.
-                 */
-                public void modifyText(ModifyEvent e) {
-                    if (!isInInternalTextModification() &&
-                            !isDirty() &&
-                            mText != null &&
-                            getCurrentValue() != null &&
-                            !mText.getText().equals(getCurrentValue())) {
-                        setDirty(true);
-                    }
-                }            
-            });
-            
-            // Remove self-reference when the widget is disposed
-            mText.addDisposeListener(new DisposeListener() {
-                public void widgetDisposed(DisposeEvent e) {
-                    mText = null;
-                }
-            });
-        }
-        
-        onAddValidators(mText);
-    }
-
-    /**
-     * Called after the text widget as been created.
-     * <p/>
-     * Derived classes typically want to:
-     * <li> Create a new {@link ModifyListener} and attach it to the given {@link Text} widget.
-     * <li> In the modify listener, call getManagedForm().getMessageManager().addMessage()
-     *      and getManagedForm().getMessageManager().removeMessage() as necessary.
-     * <li> Call removeMessage in a new text.addDisposeListener.
-     * <li> Call the validator once to setup the initial messages as needed.
-     * <p/>
-     * The base implementation does nothing.
-     * 
-     * @param text The {@link Text} widget to validate.
-     */
-    protected void onAddValidators(Text text) {
-    }
-
-    /**
-     * Returns the text widget.
-     */
-    protected final Text getTextWidget() {
-        return mText;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextValueNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextValueNode.java
deleted file mode 100644
index 33fa9fc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextValueNode.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.uimodel;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextValueDescriptor;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
-/**
- * Represents an XML element value in that can be modified using a simple text field
- * in the XML editor's user interface.
- */
-public class UiTextValueNode extends UiTextAttributeNode {
-
-    public UiTextValueNode(TextValueDescriptor attributeDescriptor, UiElementNode uiParent) {
-        super(attributeDescriptor, uiParent);
-    }
-
-    /**
-     * Updates the current text field's value when the XML has changed.
-     * <p/>
-     * The caller doesn't really know if value of the element has changed,
-     * so it will call this to refresh the value anyway. The value
-     * is only set if it has changed.
-     * <p/>
-     * This also resets the "dirty" flag.
-    */
-    @Override
-    public void updateValue(Node xml_attribute_node) {
-        setCurrentValue(DEFAULT_VALUE);
-
-        // The argument xml_attribute_node is not used here. It should always be
-        // null since this is not an attribute. What we want is the "text value" of
-        // the parent element, which is actually the first text node of the element.
-        
-        UiElementNode parent = getUiParent();
-        if (parent != null) {
-            Node xml_node = parent.getXmlNode();
-            if (xml_node != null) {
-                for (Node xml_child = xml_node.getFirstChild();
-                    xml_child != null;
-                    xml_child = xml_child.getNextSibling()) {
-                    if (xml_child.getNodeType() == Node.TEXT_NODE) {
-                        setCurrentValue(xml_child.getNodeValue());
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (isValid() && !getTextWidgetValue().equals(getCurrentValue())) {
-            try {
-                setInInternalTextModification(true);
-                setTextWidgetValue(getCurrentValue());
-                setDirty(false);
-            } finally {
-                setInInternalTextModification(false);
-            }
-        }
-    }
-
-    /* (non-java doc)
-     * Called by the user interface when the editor is saved or its state changed
-     * and the modified "attributes" must be committed (i.e. written) to the XML model.
-     */
-    @Override
-    public void commit() {
-        UiElementNode parent = getUiParent();
-        if (parent != null && isValid() && isDirty()) {
-            // Get (or create) the underlying XML element node that contains the value.
-            Node element = parent.prepareCommit();
-            if (element != null) {
-                String value = getTextWidgetValue();
-
-                // Try to find an existing text child to update.
-                boolean updated = false;
-
-                for (Node xml_child = element.getFirstChild();
-                        xml_child != null;
-                        xml_child = xml_child.getNextSibling()) {
-                    if (xml_child.getNodeType() == Node.TEXT_NODE) {
-                        xml_child.setNodeValue(value);
-                        updated = true;
-                        break;
-                    }
-                }
-
-                // If we didn't find a text child to update, we need to create one.
-                if (!updated) {
-                    Document doc = element.getOwnerDocument();
-                    if (doc != null) {
-                        Text text = doc.createTextNode(value);
-                        element.appendChild(text);
-                    }
-                }
-                
-                setCurrentValue(value);
-            }
-        }
-        setDirty(false);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlContentAssist.java
deleted file mode 100644
index cd0b259..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlContentAssist.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.xml;
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-
-/**
- * Content Assist Processor for /res/xml XML files
- */
-class XmlContentAssist extends AndroidContentAssist {
-
-    /**
-     * Constructor for LayoutContentAssist 
-     */
-    public XmlContentAssist() {
-        super(AndroidTargetData.DESCRIPTOR_XML);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlEditor.java
deleted file mode 100644
index aca6c8f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlEditor.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.xml;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.FirstElementParser;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.FileEditorInput;
-import org.w3c.dom.Document;
-
-/**
- * Multi-page form editor for /res/xml XML files.
- */
-public class XmlEditor extends AndroidEditor {
-
-    public static final String ID = AndroidConstants.EDITORS_NAMESPACE + ".xml.XmlEditor"; //$NON-NLS-1$
-
-    /** Root node of the UI element hierarchy */
-    private UiDocumentNode mUiRootNode;
-
-    /**
-     * Creates the form editor for resources XML files.
-     */
-    public XmlEditor() {
-        super();
-    }
-
-    /**
-     * Returns the root node of the UI element hierarchy, which here
-     * is the document node.
-     */
-    @Override
-    public UiDocumentNode getUiRootNode() {
-        return mUiRootNode;
-    }
-
-    // ---- Static ----
-
-    /**
-     * Indicates if this is a file that this {@link XmlEditor} can handle.
-     * <p/>
-     * The {@link XmlEditor} can handle XML files that have a <searchable> or
-     * <Preferences> root XML element with the adequate xmlns:android attribute.
-     *
-     * @return True if the {@link XmlEditor} can handle that file.
-     */
-    public static boolean canHandleFile(IFile file) {
-        // we need the target of the file's project to access the descriptors.
-        IProject project = file.getProject();
-        IAndroidTarget target = Sdk.getCurrent().getTarget(project);
-        if (target != null) {
-            // Note: the target data can be null when an SDK is not finished loading yet.
-            // We can potentially arrive here when Eclipse is started with a file previously
-            // open and the resource gets refreshed -- at that point we may not have the SDK yet.
-            AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
-
-            FirstElementParser.Result result = FirstElementParser.parse(
-                    file.getLocation().toOSString(),
-                    SdkConstants.NS_RESOURCES);
-
-            if (result != null && data != null) {
-                String name = result.getElement();
-                if (name != null && result.getXmlnsPrefix() != null) {
-                    DocumentDescriptor desc = data.getXmlDescriptors().getDescriptor();
-                    for (ElementDescriptor elem : desc.getChildren()) {
-                        if (elem.getXmlName().equals(name)) {
-                            // This is an element that this document can handle
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    // ---- Base Class Overrides ----
-
-    /**
-     * Returns whether the "save as" operation is supported by this editor.
-     * <p/>
-     * Save-As is a valid operation for the ManifestEditor since it acts on a
-     * single source file.
-     *
-     * @see IEditorPart
-     */
-    @Override
-    public boolean isSaveAsAllowed() {
-        return true;
-    }
-
-    /**
-     * Create the various form pages.
-     */
-    @Override
-    protected void createFormPages() {
-        try {
-            addPage(new XmlTreePage(this));
-        } catch (PartInitException e) {
-            AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$
-        }
-
-    }
-
-    /* (non-java doc)
-     * Change the tab/title name to include the project name.
-     */
-    @Override
-    protected void setInput(IEditorInput input) {
-        super.setInput(input);
-        if (input instanceof FileEditorInput) {
-            FileEditorInput fileInput = (FileEditorInput) input;
-            IFile file = fileInput.getFile();
-            setPartName(String.format("%1$s", file.getName()));
-        }
-    }
-
-    /**
-     * Processes the new XML Model, which XML root node is given.
-     *
-     * @param xml_doc The XML document, if available, or null if none exists.
-     */
-    @Override
-    protected void xmlModelChanged(Document xml_doc) {
-        // init the ui root on demand
-        initUiRootNode(false /*force*/);
-
-        mUiRootNode.loadFromXmlNode(xml_doc);
-
-        super.xmlModelChanged(xml_doc);
-    }
-
-    /**
-     * Creates the initial UI Root Node, including the known mandatory elements.
-     * @param force if true, a new UiRootNode is recreated even if it already exists.
-     */
-    @Override
-    protected void initUiRootNode(boolean force) {
-        // The root UI node is always created, even if there's no corresponding XML node.
-        if (mUiRootNode == null || force) {
-            Document doc = null;
-            if (mUiRootNode != null) {
-                doc = mUiRootNode.getXmlDocument();
-            }
-
-            // get the target data from the opened file (and its project)
-            AndroidTargetData data = getTargetData();
-
-            DocumentDescriptor desc;
-            if (data == null) {
-                desc = new DocumentDescriptor("temp", null /*children*/);
-            } else {
-                desc = data.getXmlDescriptors().getDescriptor();
-            }
-
-            mUiRootNode = (UiDocumentNode) desc.createUiNode();
-            mUiRootNode.setEditor(this);
-
-            onDescriptorsChanged(doc);
-        }
-    }
-
-    // ---- Local Methods ----
-
-    /**
-     * Reloads the UI manifest node from the XML, and calls the pages to update.
-     */
-    private void onDescriptorsChanged(Document document) {
-        if (document != null) {
-            mUiRootNode.loadFromXmlNode(document);
-        } else {
-            mUiRootNode.reloadFromXmlNode(mUiRootNode.getXmlNode());
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlSourceViewerConfig.java
deleted file mode 100644
index 62f43ef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlSourceViewerConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.xml;
-
-
-import com.android.ide.eclipse.adt.internal.editors.AndroidSourceViewerConfig;
-
-/**
- * Source Viewer Configuration that calls in XmlContentAssist.
- */
-public class XmlSourceViewerConfig extends AndroidSourceViewerConfig {
-
-    public XmlSourceViewerConfig() {
-        super(new XmlContentAssist());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlTreePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlTreePage.java
deleted file mode 100644
index 14b4662..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlTreePage.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.xml;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-/**
- * Page for the xml form editor.
- */
-public final class XmlTreePage extends FormPage {
-    /** Page id used for switching tabs programmatically */
-    public final static String PAGE_ID = "xml_tree_page"; //$NON-NLS-1$
-
-    /** Container editor */
-    XmlEditor mEditor;
-
-    public XmlTreePage(XmlEditor editor) {
-        super(editor, PAGE_ID, "Structure");  // tab's label, keep it short
-        mEditor = editor;
-    }
-
-    /**
-     * Creates the content in the form hosted in this page.
-     * 
-     * @param managedForm the form hosted in this page.
-     */
-    @Override
-    protected void createFormContent(IManagedForm managedForm) {
-        super.createFormContent(managedForm);
-        ScrolledForm form = managedForm.getForm();
-        form.setText("Android Xml");
-        form.setImage(AdtPlugin.getAndroidLogo());
-
-        UiElementNode rootNode = mEditor.getUiRootNode();
-        UiTreeBlock block = new UiTreeBlock(mEditor, rootNode,
-                true /* autoCreateRoot */,
-                null /* no element filters */,
-                "Xml Elements",
-                "List of all xml elements in this XML file.");
-        block.createContent(managedForm);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java
deleted file mode 100644
index d393bee..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.xml.descriptors;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.sdklib.SdkConstants;
-
-import java.util.ArrayList;
-import java.util.Map;
-
-
-/**
- * Description of the /res/xml structure.
- * Currently supports the <searchable> and <preferences> root nodes.
- */
-public final class XmlDescriptors implements IDescriptorProvider {
-
-    // Public attributes names, attributes descriptors and elements descriptors referenced
-    // elsewhere.
-    public static final String PREF_KEY_ATTR = "key"; //$NON-NLS-1$
-
-    /** The root document descriptor for both searchable and preferences. */
-    private DocumentDescriptor mDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ 
-
-    /** The root document descriptor for searchable. */
-    private DocumentDescriptor mSearchDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ 
-
-    /** The root document descriptor for preferences. */
-    private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ 
-
-    /** The root document descriptor for widget provider. */
-    private DocumentDescriptor mAppWidgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ 
-
-    /** @return the root descriptor for both searchable and preferences. */
-    public DocumentDescriptor getDescriptor() {
-        return mDescriptor;
-    }
-    
-    public ElementDescriptor[] getRootElementDescriptors() {
-        return mDescriptor.getChildren();
-    }
-    
-    /** @return the root descriptor for searchable. */
-    public DocumentDescriptor getSearchableDescriptor() {
-        return mSearchDescriptor;
-    }
-    
-    /** @return the root descriptor for preferences. */
-    public DocumentDescriptor getPreferencesDescriptor() {
-        return mPrefDescriptor;
-    }
-    
-    /** @return the root descriptor for widget providers. */
-    public DocumentDescriptor getAppWidgetDescriptor() {
-        return mAppWidgetDescriptor;
-    }
-    
-    public IDescriptorProvider getSearchableProvider() {
-        return new IDescriptorProvider() {
-            public ElementDescriptor getDescriptor() {
-                return mSearchDescriptor;
-            }
-
-            public ElementDescriptor[] getRootElementDescriptors() {
-                return mSearchDescriptor.getChildren();
-            }
-        };
-    }
-
-    public IDescriptorProvider getPreferencesProvider() {
-        return new IDescriptorProvider() {
-            public ElementDescriptor getDescriptor() {
-                return mPrefDescriptor;
-            }
-
-            public ElementDescriptor[] getRootElementDescriptors() {
-                return mPrefDescriptor.getChildren();
-            }
-        };
-    }
-
-    public IDescriptorProvider getAppWidgetProvider() {
-        return new IDescriptorProvider() {
-            public ElementDescriptor getDescriptor() {
-                return mAppWidgetDescriptor;
-            }
-
-            public ElementDescriptor[] getRootElementDescriptors() {
-                return mAppWidgetDescriptor.getChildren();
-            }
-        };
-    }
-
-    /**
-     * Updates the document descriptor.
-     * <p/>
-     * It first computes the new children of the descriptor and then updates them
-     * all at once.
-     * 
-     * @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file
-     * @param appWidgetStyleMap The map style=>attributes for <appwidget-provider> from the attrs.xml file
-     * @param prefs The list of non-group preference descriptions 
-     * @param prefGroups The list of preference group descriptions
-     */
-    public synchronized void updateDescriptors(
-            Map<String, DeclareStyleableInfo> searchableStyleMap,
-            Map<String, DeclareStyleableInfo> appWidgetStyleMap,
-            ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
-
-        XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
-                "android", //$NON-NLS-1$
-                SdkConstants.NS_RESOURCES); 
-
-        ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);
-        ElementDescriptor appWidget = createAppWidgetProviderInfo(appWidgetStyleMap, xmlns);
-        ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns);
-        ArrayList<ElementDescriptor> list =  new ArrayList<ElementDescriptor>();
-        if (searchable != null) {
-            list.add(searchable);
-            mSearchDescriptor.setChildren(new ElementDescriptor[]{ searchable });
-        }
-        if (appWidget != null) {
-            list.add(appWidget);
-            mAppWidgetDescriptor.setChildren(new ElementDescriptor[]{ appWidget });
-        }
-        if (preferences != null) {
-            list.add(preferences);
-            mPrefDescriptor.setChildren(new ElementDescriptor[]{ preferences });
-        }
-
-        if (list.size() > 0) {
-            mDescriptor.setChildren(list.toArray(new ElementDescriptor[list.size()]));
-        }
-    }
-
-    //-------------------------
-    // Creation of <searchable>
-    //-------------------------
-    
-    /**
-     * Returns the new ElementDescriptor for <searchable>
-     */
-    private ElementDescriptor createSearchable(
-            Map<String, DeclareStyleableInfo> searchableStyleMap,
-            XmlnsAttributeDescriptor xmlns) {
-
-        ElementDescriptor action_key = createElement(searchableStyleMap,
-                "SearchableActionKey", //$NON-NLS-1$ styleName
-                "actionkey", //$NON-NLS-1$ xmlName
-                "Action Key", // uiName
-                null, // sdk url
-                null, // extraAttribute
-                null, // childrenElements
-                false /* mandatory */ );
-
-        ElementDescriptor searchable = createElement(searchableStyleMap,
-                "Searchable", //$NON-NLS-1$ styleName
-                "searchable", //$NON-NLS-1$ xmlName
-                "Searchable", // uiName
-                null, // sdk url
-                xmlns, // extraAttribute
-                new ElementDescriptor[] { action_key }, // childrenElements
-                false /* mandatory */ );
-        return searchable;
-    }
-    
-    /**
-     * Returns the new ElementDescriptor for <appwidget-provider>
-     */
-    private ElementDescriptor createAppWidgetProviderInfo(
-            Map<String, DeclareStyleableInfo> appWidgetStyleMap,
-            XmlnsAttributeDescriptor xmlns) {
-
-        if (appWidgetStyleMap == null) {
-            return null;
-        }
-        
-        ElementDescriptor appWidget = createElement(appWidgetStyleMap,
-                "AppWidgetProviderInfo", //$NON-NLS-1$ styleName
-                "appwidget-provider", //$NON-NLS-1$ xmlName
-                "AppWidget Provider", // uiName
-                null, // sdk url
-                xmlns, // extraAttribute
-                null, // childrenElements
-                false /* mandatory */ );
-        return appWidget;
-    }
-
-    /**
-     * Returns a new ElementDescriptor constructed from the information given here
-     * and the javadoc & attributes extracted from the style map if any.
-     */
-    private ElementDescriptor createElement(
-            Map<String, DeclareStyleableInfo> styleMap, String styleName,
-            String xmlName, String uiName, String sdkUrl,
-            AttributeDescriptor extraAttribute,
-            ElementDescriptor[] childrenElements, boolean mandatory) {
-
-        ElementDescriptor element = new ElementDescriptor(xmlName, uiName, null, sdkUrl,
-                null, childrenElements, mandatory);
-
-        return updateElement(element, styleMap, styleName, extraAttribute);
-    }
-
-    /**
-     * Updates an ElementDescriptor with the javadoc & attributes extracted from the style
-     * map if any.
-     */
-    private ElementDescriptor updateElement(ElementDescriptor element,
-            Map<String, DeclareStyleableInfo> styleMap,
-            String styleName,
-            AttributeDescriptor extraAttribute) {
-        ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>();
-
-        DeclareStyleableInfo style = styleMap != null ? styleMap.get(styleName) : null;
-        if (style != null) {
-            DescriptorsUtils.appendAttributes(descs,
-                    null,   // elementName
-                    SdkConstants.NS_RESOURCES,
-                    style.getAttributes(),
-                    null,   // requiredAttributes
-                    null);  // overrides
-            element.setTooltip(style.getJavaDoc());
-        }
-
-        if (extraAttribute != null) {
-            descs.add(extraAttribute);
-        }
-
-        element.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()]));
-        return element;
-    }
-
-    //--------------------------
-    // Creation of <Preferences>
-    //--------------------------
-
-    /**
-     * Returns the new ElementDescriptor for <Preferences>
-     */
-    private ElementDescriptor createPreference(ViewClassInfo[] prefs,
-            ViewClassInfo[] prefGroups, XmlnsAttributeDescriptor xmlns) {
-
-        ArrayList<ElementDescriptor> newPrefs = new ArrayList<ElementDescriptor>();
-        if (prefs != null) {
-            for (ViewClassInfo info : prefs) {
-                ElementDescriptor desc = convertPref(info);
-                newPrefs.add(desc);
-            }
-        }
-
-        ElementDescriptor topPreferences = null;
-        
-        ArrayList<ElementDescriptor> newGroups = new ArrayList<ElementDescriptor>();
-        if (prefGroups != null) {
-            for (ViewClassInfo info : prefGroups) {
-                ElementDescriptor desc = convertPref(info);
-                newGroups.add(desc);
-                
-                if (info.getCanonicalClassName() == AndroidConstants.CLASS_PREFERENCES) {
-                    topPreferences = desc;
-                }
-            }
-        }
-
-        ArrayList<ElementDescriptor> everything = new ArrayList<ElementDescriptor>();
-        everything.addAll(newGroups);
-        everything.addAll(newPrefs);
-        ElementDescriptor[] newArray = everything.toArray(new ElementDescriptor[everything.size()]);
-
-        // Link all groups to everything else here.. recursively
-        for (ElementDescriptor layoutDesc : newGroups) {
-            layoutDesc.setChildren(newArray);
-        }
-
-        // The "top" element to be returned corresponds to the class "Preferences".
-        // Its descriptor has already been created. However the root one also needs
-        // the hidden xmlns:android definition..
-        if (topPreferences != null) {
-            AttributeDescriptor[] attrs = topPreferences.getAttributes();
-            AttributeDescriptor[] newAttrs = new AttributeDescriptor[attrs.length + 1];
-            System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
-            newAttrs[attrs.length] = xmlns;
-            return new ElementDescriptor(
-                    topPreferences.getXmlName(),
-                    topPreferences.getUiName(),
-                    topPreferences.getTooltip(),
-                    topPreferences.getSdkUrl(),
-                    newAttrs,
-                    topPreferences.getChildren(),
-                    false /* mandatory */);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Creates an element descriptor from a given {@link ViewClassInfo}.
-     */
-    private ElementDescriptor convertPref(ViewClassInfo info) {
-        String xml_name = info.getShortClassName();
-        String tooltip = info.getJavaDoc();
-        
-        // Process all Preference attributes
-        ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
-        DescriptorsUtils.appendAttributes(attributes,
-                null,   // elementName
-                SdkConstants.NS_RESOURCES,
-                info.getAttributes(),
-                null,   // requiredAttributes
-                null);  // overrides
-        
-        for (ViewClassInfo link = info.getSuperClass();
-                link != null;
-                link = link.getSuperClass()) {
-            AttributeInfo[] attrList = link.getAttributes();
-            if (attrList.length > 0) {
-                attributes.add(new SeparatorAttributeDescriptor(
-                        String.format("Attributes from %1$s", link.getShortClassName()))); 
-                DescriptorsUtils.appendAttributes(attributes,
-                        null,   // elementName
-                        SdkConstants.NS_RESOURCES,
-                        attrList,
-                        null,   // requiredAttributes
-                        null);  // overrides
-            }
-        }
-
-        return new ViewElementDescriptor(xml_name,
-                xml_name, // ui_name
-                info.getCanonicalClassName(),
-                tooltip,
-                null, // sdk_url
-                attributes.toArray(new AttributeDescriptor[attributes.size()]),
-                null,
-                null, // children
-                false /* mandatory */);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AMReceiver.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AMReceiver.java
deleted file mode 100644
index c79a25b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AMReceiver.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-/**
- * Output receiver for am process (Activity Manager)
- * 
- * Monitors adb output for am errors, and retries launch as appropriate. 
- */
-public class AMReceiver extends MultiLineReceiver {
-
-    private static final int MAX_ATTEMPT_COUNT = 5;
-    private static final Pattern sAmErrorType = Pattern.compile("Error type (\\d+)"); //$NON-NLS-1$
-
-    private final DelayedLaunchInfo mLaunchInfo;
-    private final IDevice mDevice;
-    private final ILaunchController mLaunchController;
-
-    /**
-     * Basic constructor.
-     * 
-     * @param launchInfo the {@link DelayedLaunchInfo} associated with the am process.
-     * @param device the Android device on which the launch is done.
-     * @param launchController the {@link ILaunchController} that is managing the launch
-     */
-    public AMReceiver(DelayedLaunchInfo launchInfo, IDevice device, 
-            ILaunchController launchController) {
-        mLaunchInfo = launchInfo;
-        mDevice = device;
-        mLaunchController = launchController;
-    }
-
-    /**
-     * Monitors the am process for error messages. If an error occurs, will reattempt launch up to
-     * <code>MAX_ATTEMPT_COUNT</code> times.
-     * 
-     * @param lines a portion of the am output
-     * 
-     * @see MultiLineReceiver#processNewLines(String[])
-     */
-    @Override
-    public void processNewLines(String[] lines) {
-        // first we check if one starts with error
-        ArrayList<String> array = new ArrayList<String>();
-        boolean error = false;
-        boolean warning = false;
-        for (String s : lines) {
-            // ignore empty lines.
-            if (s.length() == 0) {
-                continue;
-            }
-
-            // check for errors that output an error type, if the attempt count is still
-            // valid. If not the whole text will be output in the console
-            if (mLaunchInfo.getAttemptCount() < MAX_ATTEMPT_COUNT &&
-                    mLaunchInfo.isCancelled() == false) {
-                Matcher m = sAmErrorType.matcher(s);
-                if (m.matches()) {
-                    // get the error type
-                    int type = Integer.parseInt(m.group(1));
-
-                    final int waitTime = 3;
-                    String msg;
-
-                    switch (type) {
-                        case 1:
-                            /* Intended fall through */
-                        case 2:
-                            msg = String.format(
-                                    "Device not ready. Waiting %1$d seconds before next attempt.",
-                                    waitTime);
-                            break;
-                        case 3:
-                            msg = String.format(
-                                    "New package not yet registered with the system. Waiting %1$d seconds before next attempt.",
-                                    waitTime);
-                            break;
-                        default:
-                            msg = String.format(
-                                    "Device not ready (%2$d). Waiting %1$d seconds before next attempt.",
-                                    waitTime, type);
-                        break;
-
-                    }
-
-                    AdtPlugin.printToConsole(mLaunchInfo.getProject(), msg);
-
-                    // launch another thread, that waits a bit and attempts another launch
-                    new Thread("Delayed Launch attempt") {
-                        @Override
-                        public void run() {
-                            try {
-                                sleep(waitTime * 1000);
-                            } catch (InterruptedException e) {
-                                // ignore
-                            }
-
-                            mLaunchController.launchApp(mLaunchInfo, mDevice);
-                        }
-                    }.start();
-
-                    // no need to parse the rest
-                    return;
-                }
-            }
-
-            // check for error if needed
-            if (error == false && s.startsWith("Error:")) { //$NON-NLS-1$
-                error = true;
-            }
-            if (warning == false && s.startsWith("Warning:")) { //$NON-NLS-1$
-                warning = true;
-            }
-
-            // add the line to the list
-            array.add("ActivityManager: " + s); //$NON-NLS-1$
-        }
-
-        // then we display them in the console
-        if (warning || error) {
-            AdtPlugin.printErrorToConsole(mLaunchInfo.getProject(), array.toArray());
-        } else {
-            AdtPlugin.printToConsole(mLaunchInfo.getProject(), array.toArray());
-        }
-
-        // if error then we cancel the launch, and remove the delayed info
-        if (error) {
-            mLaunchController.stopLaunch(mLaunchInfo);
-        }
-    }
-
-    /**
-     * Returns true if launch has been cancelled
-     */
-    public boolean isCancelled() {
-        return mLaunchInfo.isCancelled();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ActivityLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ActivityLaunchAction.java
deleted file mode 100644
index 09f01ec..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ActivityLaunchAction.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import java.io.IOException;
-
-/**
- * Launches the given activity
- */
-public class ActivityLaunchAction implements IAndroidLaunchAction {
-
-    private final String mActivity;
-    private final ILaunchController mLaunchController;
-    
-    /**
-     * Creates a ActivityLaunchAction
-     * 
-     * @param activity fully qualified activity name to launch
-     * @param controller the {@link ILaunchController} that performs launch
-     */
-    public ActivityLaunchAction(String activity, ILaunchController controller) {
-        mActivity = activity;
-        mLaunchController = controller;
-    }
-    
-    /**
-     * Launches the activity on targeted device
-     * 
-     * @param info the {@link DelayedLaunchInfo} that contains launch details
-     * @param device the Android device to perform action on
-     * 
-     * @see IAndroidLaunchAction#doLaunchAction(DelayedLaunchInfo, IDevice)
-     */
-    public boolean doLaunchAction(DelayedLaunchInfo info, IDevice device) {
-        try {
-            String msg = String.format("Starting activity %1$s on device ", mActivity,
-                    device);
-            AdtPlugin.printToConsole(info.getProject(), msg);
-
-            // In debug mode, we need to add the info to the list of application monitoring
-            // client changes.
-            // increment launch attempt count, to handle retries and timeouts
-            info.incrementAttemptCount();
-
-            // now we actually launch the app.
-            device.executeShellCommand("am start" //$NON-NLS-1$
-                    + (info.isDebugMode() ? " -D" //$NON-NLS-1$
-                            : "") //$NON-NLS-1$
-                    + " -n " //$NON-NLS-1$
-                    + info.getPackageName() + "/" //$NON-NLS-1$
-                    + mActivity.replaceAll("\\$", "\\\\\\$"), //$NON-NLS-1$ //$NON-NLS-2$
-                    new AMReceiver(info, device, mLaunchController));
-
-            // if the app is not a debug app, we need to do some clean up, as
-            // the process is done!
-            if (info.isDebugMode() == false) {
-                // stop the launch object, since there's no debug, and it can't
-                // provide any control over the app
-                return false;
-            }
-        } catch (IOException e) {
-            // something went wrong trying to launch the app.
-            // lets stop the Launch
-            AdtPlugin.printErrorToConsole(info.getProject(),
-                    String.format("Launch error: %s", e.getMessage()));
-            return false;
-        }
-        return true;
-    }
-    
-    /**
-     * Returns a description of the activity being launched
-     * 
-     * @see IAndroidLaunchAction#getLaunchDescription()
-     */
-    public String getLaunchDescription() {
-       return String.format("%1$s activity launch", mActivity);
-    }
-    
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunch.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunch.java
deleted file mode 100644
index 8e2c133..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunch.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.debug.core.Launch;
-import org.eclipse.debug.core.model.ISourceLocator;
-
-/**
- * Custom implementation of Launch to allow access to the LaunchManager
- *
- */
-public class AndroidLaunch extends Launch {
-
-    /**
-     * Basic constructor does nothing special
-     * @param launchConfiguration
-     * @param mode
-     * @param locator
-     */
-    public AndroidLaunch(ILaunchConfiguration launchConfiguration, String mode,
-            ISourceLocator locator) {
-        super(launchConfiguration, mode, locator);
-    }
-
-    /** Stops the launch, and removes it from the launch manager */
-    public void stopLaunch() {
-        ILaunchManager mgr = getLaunchManager();
-
-        if (canTerminate()) {
-            try {
-                terminate();
-            } catch (DebugException e) {
-                // well looks like we couldn't stop it. nothing else to be
-                // done really
-            }
-        }
-        // remove the launch
-        mgr.removeLaunch(this);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchConfiguration.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchConfiguration.java
deleted file mode 100644
index 2b02c59..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchConfiguration.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.ILaunchConfiguration;
-
-/**
- * Launch configuration data. This stores the result of querying the
- * {@link ILaunchConfiguration} so that it's only done once. 
- */
-public class AndroidLaunchConfiguration {
-    
-    /**
-     * Launch action. See {@link LaunchConfigDelegate#ACTION_DEFAULT},
-     * {@link LaunchConfigDelegate#ACTION_ACTIVITY},
-     * {@link LaunchConfigDelegate#ACTION_DO_NOTHING}
-     */
-    public int mLaunchAction = LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION;
-    
-    /**
-     * Target selection mode for the configuration: either {@link #AUTO} or {@link #MANUAL}.
-     */
-    public enum TargetMode {
-        /** Automatic target selection mode. */
-        AUTO(true),
-        /** Manual target selection mode. */
-        MANUAL(false);
-        
-        private boolean mValue;
-
-        TargetMode(boolean value) {
-            mValue = value;
-        }
-        
-        public boolean getValue() {
-            return mValue;
-        }
-        
-        public static TargetMode getMode(boolean value) {
-            for (TargetMode mode : values()) {
-                if (mode.mValue == value) {
-                    return mode;
-                }
-            }
-            
-            return null;
-        }
-    }
-    
-    /**
-     * Target selection mode.
-     * @see TargetMode
-     */
-    public TargetMode mTargetMode = LaunchConfigDelegate.DEFAULT_TARGET_MODE;
-
-    /**
-     * Indicates whether the emulator should be called with -wipe-data
-     */
-    public boolean mWipeData = LaunchConfigDelegate.DEFAULT_WIPE_DATA;
-
-    /**
-     * Indicates whether the emulator should be called with -no-boot-anim
-     */
-    public boolean mNoBootAnim = LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM;
-    
-    /**
-     * AVD Name.
-     */
-    public String mAvdName = null;
-    
-    public String mNetworkSpeed = EmulatorConfigTab.getSpeed(
-            LaunchConfigDelegate.DEFAULT_SPEED);
-    public String mNetworkDelay = EmulatorConfigTab.getDelay(
-            LaunchConfigDelegate.DEFAULT_DELAY);
-
-    /**
-     * Optional custom command line parameter to launch the emulator
-     */
-    public String mEmulatorCommandLine;
-
-    /**
-     * Initialized the structure from an ILaunchConfiguration object.
-     * @param config
-     */
-    public void set(ILaunchConfiguration config) {
-        try {
-            mLaunchAction = config.getAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
-                    mLaunchAction);
-        } catch (CoreException e1) {
-            // nothing to be done here, we'll use the default value
-        }
-
-        try {
-            boolean value = config.getAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
-                    mTargetMode.getValue());
-            mTargetMode = TargetMode.getMode(value);
-        } catch (CoreException e) {
-            // nothing to be done here, we'll use the default value
-        }
-
-        try {
-            mAvdName = config.getAttribute(LaunchConfigDelegate.ATTR_AVD_NAME, mAvdName);
-        } catch (CoreException e) {
-            // ignore
-        }
-
-        int index = LaunchConfigDelegate.DEFAULT_SPEED;
-        try {
-            index = config.getAttribute(LaunchConfigDelegate.ATTR_SPEED, index);
-        } catch (CoreException e) {
-            // nothing to be done here, we'll use the default value
-        }
-        mNetworkSpeed = EmulatorConfigTab.getSpeed(index);
-
-        index = LaunchConfigDelegate.DEFAULT_DELAY;
-        try {
-            index = config.getAttribute(LaunchConfigDelegate.ATTR_DELAY, index);
-        } catch (CoreException e) {
-            // nothing to be done here, we'll use the default value
-        }
-        mNetworkDelay = EmulatorConfigTab.getDelay(index);
-
-        try {
-            mEmulatorCommandLine = config.getAttribute(
-                    LaunchConfigDelegate.ATTR_COMMANDLINE, ""); //$NON-NLS-1$
-        } catch (CoreException e) {
-            // lets not do anything here, we'll use the default value
-        }
-
-        try {
-            mWipeData = config.getAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA, mWipeData);
-        } catch (CoreException e) {
-            // nothing to be done here, we'll use the default value
-        }
-
-        try {
-            mNoBootAnim = config.getAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM,
-                                              mNoBootAnim);
-        } catch (CoreException e) {
-            // nothing to be done here, we'll use the default value
-        }
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java
deleted file mode 100644
index eab0c6c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java
+++ /dev/null
@@ -1,1607 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ddmlib.ClientData.DebuggerStatus;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration.TargetMode;
-import com.android.ide.eclipse.adt.internal.launch.DelayedLaunchInfo.InstallRetryMode;
-import com.android.ide.eclipse.adt.internal.launch.DeviceChooserDialog.DeviceChooserResponse;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.ApkInstallManager;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.wizards.actions.AvdManagerAction;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.NullSdkLog;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchConfigurationType;
-import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.debug.core.model.IDebugTarget;
-import org.eclipse.debug.ui.DebugUITools;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
-import org.eclipse.jdt.launching.IVMConnector;
-import org.eclipse.jdt.launching.JavaRuntime;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map.Entry;
-
-/**
- * Controls the launch of Android application either on a device or on the
- * emulator. If an emulator is already running, this class will attempt to reuse
- * it.
- */
-public final class AndroidLaunchController implements IDebugBridgeChangeListener,
-        IDeviceChangeListener, IClientChangeListener, ILaunchController {
-
-    private static final String FLAG_AVD = "-avd"; //$NON-NLS-1$
-    private static final String FLAG_NETDELAY = "-netdelay"; //$NON-NLS-1$
-    private static final String FLAG_NETSPEED = "-netspeed"; //$NON-NLS-1$
-    private static final String FLAG_WIPE_DATA = "-wipe-data"; //$NON-NLS-1$
-    private static final String FLAG_NO_BOOT_ANIM = "-no-boot-anim"; //$NON-NLS-1$
-
-    /**
-     * Map to store {@link ILaunchConfiguration} objects that must be launched as simple connection
-     * to running application. The integer is the port on which to connect.
-     * <b>ALL ACCESS MUST BE INSIDE A <code>synchronized (sListLock)</code> block!</b>
-     */
-    private static final HashMap<ILaunchConfiguration, Integer> sRunningAppMap =
-        new HashMap<ILaunchConfiguration, Integer>();
-
-    private static final Object sListLock = sRunningAppMap;
-
-    /**
-     * List of {@link DelayedLaunchInfo} waiting for an emulator to connect.
-     * <p>Once an emulator has connected, {@link DelayedLaunchInfo#getDevice()} is set and the
-     * DelayedLaunchInfo object is moved to
-     * {@link AndroidLaunchController#mWaitingForReadyEmulatorList}.
-     * <b>ALL ACCESS MUST BE INSIDE A <code>synchronized (sListLock)</code> block!</b>
-     */
-    private final ArrayList<DelayedLaunchInfo> mWaitingForEmulatorLaunches =
-        new ArrayList<DelayedLaunchInfo>();
-
-    /**
-     * List of application waiting to be launched on a device/emulator.<br>
-     * <b>ALL ACCESS MUST BE INSIDE A <code>synchronized (sListLock)</code> block!</b>
-     * */
-    private final ArrayList<DelayedLaunchInfo> mWaitingForReadyEmulatorList =
-        new ArrayList<DelayedLaunchInfo>();
-
-    /**
-     * Application waiting to show up as waiting for debugger.
-     * <b>ALL ACCESS MUST BE INSIDE A <code>synchronized (sListLock)</code> block!</b>
-     */
-    private final ArrayList<DelayedLaunchInfo> mWaitingForDebuggerApplications =
-        new ArrayList<DelayedLaunchInfo>();
-
-    /**
-     * List of clients that have appeared as waiting for debugger before their name was available.
-     * <b>ALL ACCESS MUST BE INSIDE A <code>synchronized (sListLock)</code> block!</b>
-     */
-    private final ArrayList<Client> mUnknownClientsWaitingForDebugger = new ArrayList<Client>();
-
-    /** static instance for singleton */
-    private static AndroidLaunchController sThis = new AndroidLaunchController();
-
-    /** private constructor to enforce singleton */
-    private AndroidLaunchController() {
-        AndroidDebugBridge.addDebugBridgeChangeListener(this);
-        AndroidDebugBridge.addDeviceChangeListener(this);
-        AndroidDebugBridge.addClientChangeListener(this);
-    }
-
-    /**
-     * Returns the singleton reference.
-     */
-    public static AndroidLaunchController getInstance() {
-        return sThis;
-    }
-
-
-    /**
-     * Launches a remote java debugging session on an already running application
-     * @param project The project of the application to debug.
-     * @param debugPort The port to connect the debugger to.
-     */
-    public static void debugRunningApp(IProject project, int debugPort) {
-        // get an existing or new launch configuration
-        ILaunchConfiguration config = AndroidLaunchController.getLaunchConfig(project);
-
-        if (config != null) {
-            setPortLaunchConfigAssociation(config, debugPort);
-
-            // and launch
-            DebugUITools.launch(config, ILaunchManager.DEBUG_MODE);
-        }
-    }
-
-    /**
-     * Returns an {@link ILaunchConfiguration} for the specified {@link IProject}.
-     * @param project the project
-     * @return a new or already existing <code>ILaunchConfiguration</code> or null if there was
-     * an error when creating a new one.
-     */
-    public static ILaunchConfiguration getLaunchConfig(IProject project) {
-        // get the launch manager
-        ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
-
-        // now get the config type for our particular android type.
-        ILaunchConfigurationType configType = manager.getLaunchConfigurationType(
-                        LaunchConfigDelegate.ANDROID_LAUNCH_TYPE_ID);
-
-        String name = project.getName();
-
-        // search for an existing launch configuration
-        ILaunchConfiguration config = findConfig(manager, configType, name);
-
-        // test if we found one or not
-        if (config == null) {
-            // Didn't find a matching config, so we make one.
-            // It'll be made in the "working copy" object first.
-            ILaunchConfigurationWorkingCopy wc = null;
-
-            try {
-                // make the working copy object
-                wc = configType.newInstance(null,
-                        manager.generateUniqueLaunchConfigurationNameFrom(name));
-
-                // set the project name
-                wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, name);
-
-                // set the launch mode to default.
-                wc.setAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
-                        LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION);
-
-                // set default target mode
-                wc.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
-                        LaunchConfigDelegate.DEFAULT_TARGET_MODE.getValue());
-
-                // default AVD: None
-                wc.setAttribute(LaunchConfigDelegate.ATTR_AVD_NAME, (String) null);
-
-                // set the default network speed
-                wc.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
-                        LaunchConfigDelegate.DEFAULT_SPEED);
-
-                // and delay
-                wc.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
-                        LaunchConfigDelegate.DEFAULT_DELAY);
-
-                // default wipe data mode
-                wc.setAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA,
-                        LaunchConfigDelegate.DEFAULT_WIPE_DATA);
-
-                // default disable boot animation option
-                wc.setAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM,
-                        LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM);
-
-                // set default emulator options
-                IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
-                String emuOptions = store.getString(AdtPlugin.PREFS_EMU_OPTIONS);
-                wc.setAttribute(LaunchConfigDelegate.ATTR_COMMANDLINE, emuOptions);
-
-                // map the config and the project
-                wc.setMappedResources(getResourcesToMap(project));
-
-                // save the working copy to get the launch config object which we return.
-                return wc.doSave();
-
-            } catch (CoreException e) {
-                String msg = String.format(
-                        "Failed to create a Launch config for project '%1$s': %2$s",
-                        project.getName(), e.getMessage());
-                AdtPlugin.printErrorToConsole(project, msg);
-
-                // no launch!
-                return null;
-            }
-        }
-
-        return config;
-    }
-
-    /**
-     * Returns the list of resources to map to a Launch Configuration.
-     * @param project the project associated to the launch configuration.
-     */
-    public static IResource[] getResourcesToMap(IProject project) {
-        ArrayList<IResource> array = new ArrayList<IResource>(2);
-        array.add(project);
-
-        IFile manifest = AndroidManifestParser.getManifest(project);
-        if (manifest != null) {
-            array.add(manifest);
-        }
-
-        return array.toArray(new IResource[array.size()]);
-    }
-
-    /**
-     * Launches an android app on the device or emulator
-     *
-     * @param project The project we're launching
-     * @param mode the mode in which to launch, one of the mode constants
-     *      defined by <code>ILaunchManager</code> - <code>RUN_MODE</code> or
-     *      <code>DEBUG_MODE</code>.
-     * @param apk the resource to the apk to launch.
-     * @param packageName the Android package name of the app
-     * @param debugPackageName the Android package name to debug
-     * @param debuggable the debuggable value of the app, or null if not set.
-     * @param requiredApiVersionNumber the api version required by the app, or null if none.
-     * @param launchAction the action to perform after app sync
-     * @param config the launch configuration
-     * @param launch the launch object
-     */
-    public void launch(final IProject project, String mode, IFile apk,
-            String packageName, String debugPackageName, Boolean debuggable,
-            String requiredApiVersionNumber, final IAndroidLaunchAction launchAction,
-            final AndroidLaunchConfiguration config, final AndroidLaunch launch,
-            IProgressMonitor monitor) {
-
-        String message = String.format("Performing %1$s", launchAction.getLaunchDescription());
-        AdtPlugin.printToConsole(project, message);
-
-        // create the launch info
-        final DelayedLaunchInfo launchInfo = new DelayedLaunchInfo(project, packageName,
-                debugPackageName, launchAction, apk, debuggable, requiredApiVersionNumber, launch,
-                monitor);
-
-        // set the debug mode
-        launchInfo.setDebugMode(mode.equals(ILaunchManager.DEBUG_MODE));
-
-        // get the SDK
-        Sdk currentSdk = Sdk.getCurrent();
-        AvdManager avdManager = currentSdk.getAvdManager();
-
-        // reload the AVDs to make sure we are up to date
-        try {
-            avdManager.reloadAvds(NullSdkLog.getLogger());
-        } catch (AndroidLocationException e1) {
-            // this happens if the AVD Manager failed to find the folder in which the AVDs are
-            // stored. This is unlikely to happen, but if it does, we should force to go manual
-            // to allow using physical devices.
-            config.mTargetMode = TargetMode.MANUAL;
-        }
-
-        // get the project target
-        final IAndroidTarget projectTarget = currentSdk.getTarget(project);
-
-        // FIXME: check errors on missing sdk, AVD manager, or project target.
-
-        // device chooser response object.
-        final DeviceChooserResponse response = new DeviceChooserResponse();
-
-        /*
-         * Launch logic:
-         * - Manually Mode
-         *       Always display a UI that lets a user see the current running emulators/devices.
-         *       The UI must show which devices are compatibles, and allow launching new emulators
-         *       with compatible (and not yet running) AVD.
-         * - Automatic Way
-         *     * Preferred AVD set.
-         *           If Preferred AVD is not running: launch it.
-         *           Launch the application on the preferred AVD.
-         *     * No preferred AVD.
-         *           Count the number of compatible emulators/devices.
-         *           If != 1, display a UI similar to manual mode.
-         *           If == 1, launch the application on this AVD/device.
-         */
-
-        if (config.mTargetMode == TargetMode.AUTO) {
-            // if we are in automatic target mode, we need to find the current devices
-            IDevice[] devices = AndroidDebugBridge.getBridge().getDevices();
-
-            // first check if we have a preferred AVD name, and if it actually exists, and is valid
-            // (ie able to run the project).
-            // We need to check this in case the AVD was recreated with a different target that is
-            // not compatible.
-            AvdInfo preferredAvd = null;
-            if (config.mAvdName != null) {
-                preferredAvd = avdManager.getAvd(config.mAvdName, true /*validAvdOnly*/);
-                if (projectTarget.isCompatibleBaseFor(preferredAvd.getTarget()) == false) {
-                    preferredAvd = null;
-
-                    AdtPlugin.printErrorToConsole(project, String.format(
-                            "Preferred AVD '%1$s' is not compatible with the project target '%2$s'. Looking for a compatible AVD...",
-                            config.mAvdName, projectTarget.getName()));
-                }
-            }
-
-            if (preferredAvd != null) {
-                // look for a matching device
-                for (IDevice d : devices) {
-                    String deviceAvd = d.getAvdName();
-                    if (deviceAvd != null && deviceAvd.equals(config.mAvdName)) {
-                        response.setDeviceToUse(d);
-
-                        AdtPlugin.printToConsole(project, String.format(
-                                "Automatic Target Mode: Preferred AVD '%1$s' is available on emulator '%2$s'",
-                                config.mAvdName, d));
-
-                        continueLaunch(response, project, launch, launchInfo, config);
-                        return;
-                    }
-                }
-
-                // at this point we have a valid preferred AVD that is not running.
-                // We need to start it.
-                response.setAvdToLaunch(preferredAvd);
-
-                AdtPlugin.printToConsole(project, String.format(
-                        "Automatic Target Mode: Preferred AVD '%1$s' is not available. Launching new emulator.",
-                        config.mAvdName));
-
-                continueLaunch(response, project, launch, launchInfo, config);
-                return;
-            }
-
-            // no (valid) preferred AVD? look for one.
-            HashMap<IDevice, AvdInfo> compatibleRunningAvds = new HashMap<IDevice, AvdInfo>();
-            boolean hasDevice = false; // if there's 1+ device running, we may force manual mode,
-                                       // as we cannot always detect proper compatibility with
-                                       // devices. This is the case if the project target is not
-                                       // a standard platform
-            for (IDevice d : devices) {
-                String deviceAvd = d.getAvdName();
-                if (deviceAvd != null) { // physical devices return null.
-                    AvdInfo info = avdManager.getAvd(deviceAvd, true /*validAvdOnly*/);
-                    if (info != null && projectTarget.isCompatibleBaseFor(info.getTarget())) {
-                        compatibleRunningAvds.put(d, info);
-                    }
-                } else {
-                    if (projectTarget.isPlatform()) { // means this can run on any device as long
-                                                      // as api level is high enough
-                        AndroidVersion deviceVersion = Sdk.getDeviceVersion(d);
-                        if (deviceVersion.canRun(projectTarget.getVersion())) {
-                            // device is compatible with project
-                            compatibleRunningAvds.put(d, null);
-                            continue;
-                        }
-                    } else {
-                        // for non project platform, we can't be sure if a device can
-                        // run an application or not, since we don't query the device
-                        // for the list of optional libraries that it supports.
-                    }
-                    hasDevice = true;
-                }
-            }
-
-            // depending on the number of devices, we'll simulate an automatic choice
-            // from the device chooser or simply show up the device chooser.
-            if (hasDevice == false && compatibleRunningAvds.size() == 0) {
-                // if zero emulators/devices, we launch an emulator.
-                // We need to figure out which AVD first.
-
-                // we are going to take the closest AVD. ie a compatible AVD that has the API level
-                // closest to the project target.
-                AvdInfo defaultAvd = findMatchingAvd(avdManager, projectTarget);
-
-                if (defaultAvd != null) {
-                    response.setAvdToLaunch(defaultAvd);
-
-                    AdtPlugin.printToConsole(project, String.format(
-                            "Automatic Target Mode: launching new emulator with compatible AVD '%1$s'",
-                            defaultAvd.getName()));
-
-                    continueLaunch(response, project, launch, launchInfo, config);
-                    return;
-                } else {
-                    AdtPlugin.printToConsole(project, String.format(
-                            "Failed to find an AVD compatible with target '%1$s'.",
-                            projectTarget.getName()));
-
-                    final Display display = AdtPlugin.getDisplay();
-                    final boolean[] searchAgain = new boolean[] { false };
-                    // ask the user to create a new one.
-                    display.syncExec(new Runnable() {
-                        public void run() {
-                            Shell shell = display.getActiveShell();
-                            if (MessageDialog.openQuestion(shell, "Android AVD Error",
-                                    "No compatible targets were found. Do you wish to a add new Android Virtual Device?")) {
-                                AvdManagerAction action = new AvdManagerAction();
-                                action.run(null /*action*/);
-                                searchAgain[0] = true;
-                            }
-                        }
-                    });
-                    if (searchAgain[0]) {
-                        // attempt to reload the AVDs and find one compatible.
-                        defaultAvd = findMatchingAvd(avdManager, projectTarget);
-
-                        if (defaultAvd == null) {
-                            AdtPlugin.printErrorToConsole(project, String.format(
-                                    "Still no compatible AVDs with target '%1$s': Aborting launch.",
-                                    projectTarget.getName()));
-                            stopLaunch(launchInfo);
-                        } else {
-                            response.setAvdToLaunch(defaultAvd);
-
-                            AdtPlugin.printToConsole(project, String.format(
-                                    "Launching new emulator with compatible AVD '%1$s'",
-                                    defaultAvd.getName()));
-
-                            continueLaunch(response, project, launch, launchInfo, config);
-                            return;
-                        }
-                    }
-                }
-            } else if (hasDevice == false && compatibleRunningAvds.size() == 1) {
-                Entry<IDevice, AvdInfo> e = compatibleRunningAvds.entrySet().iterator().next();
-                response.setDeviceToUse(e.getKey());
-
-                // get the AvdInfo, if null, the device is a physical device.
-                AvdInfo avdInfo = e.getValue();
-                if (avdInfo != null) {
-                    message = String.format("Automatic Target Mode: using existing emulator '%1$s' running compatible AVD '%2$s'",
-                            response.getDeviceToUse(), e.getValue().getName());
-                } else {
-                    message = String.format("Automatic Target Mode: using device '%1$s'",
-                            response.getDeviceToUse());
-                }
-                AdtPlugin.printToConsole(project, message);
-
-                continueLaunch(response, project, launch, launchInfo, config);
-                return;
-            }
-
-            // if more than one device, we'll bring up the DeviceChooser dialog below.
-            if (compatibleRunningAvds.size() >= 2) {
-                message = "Automatic Target Mode: Several compatible targets. Please select a target device.";
-            } else if (hasDevice) {
-                message = "Automatic Target Mode: Unable to detect device compatibility. Please select a target device.";
-            }
-
-            AdtPlugin.printToConsole(project, message);
-        }
-
-        // bring up the device chooser.
-        AdtPlugin.getDisplay().asyncExec(new Runnable() {
-            public void run() {
-                try {
-                    // open the chooser dialog. It'll fill 'response' with the device to use
-                    // or the AVD to launch.
-                    DeviceChooserDialog dialog = new DeviceChooserDialog(
-                            AdtPlugin.getDisplay().getActiveShell(),
-                            response, launchInfo.getPackageName(), projectTarget);
-                    if (dialog.open() == Dialog.OK) {
-                        AndroidLaunchController.this.continueLaunch(response, project, launch,
-                                launchInfo, config);
-                    } else {
-                        AdtPlugin.printErrorToConsole(project, "Launch canceled!");
-                        stopLaunch(launchInfo);
-                        return;
-                    }
-                } catch (Exception e) {
-                    // there seems to be some case where the shell will be null. (might be
-                    // an OS X bug). Because of this the creation of the dialog will throw
-                    // and IllegalArg exception interrupting the launch with no user feedback.
-                    // So we trap all the exception and display something.
-                    String msg = e.getMessage();
-                    if (msg == null) {
-                        msg = e.getClass().getCanonicalName();
-                    }
-                    AdtPlugin.printErrorToConsole(project,
-                            String.format("Error during launch: %s", msg));
-                    stopLaunch(launchInfo);
-                }
-            }
-        });
-    }
-
-    /**
-     * Find a matching AVD.
-     */
-    private AvdInfo findMatchingAvd(AvdManager avdManager, final IAndroidTarget projectTarget) {
-        AvdInfo[] avds = avdManager.getValidAvds();
-        AvdInfo defaultAvd = null;
-        for (AvdInfo avd : avds) {
-            if (projectTarget.isCompatibleBaseFor(avd.getTarget())) {
-                // at this point we can ignore the code name issue since
-                // IAndroidTarget.isCompatibleBaseFor() will already have filtered the non
-                // compatible AVDs.
-                if (defaultAvd == null ||
-                        avd.getTarget().getVersion().getApiLevel() <
-                            defaultAvd.getTarget().getVersion().getApiLevel()) {
-                    defaultAvd = avd;
-                }
-            }
-        }
-        return defaultAvd;
-    }
-
-    /**
-     * Continues the launch based on the DeviceChooser response.
-     * @param response the device chooser response
-     * @param project The project being launched
-     * @param launch The eclipse launch info
-     * @param launchInfo The {@link DelayedLaunchInfo}
-     * @param config The config needed to start a new emulator.
-     */
-    void continueLaunch(final DeviceChooserResponse response, final IProject project,
-            final AndroidLaunch launch, final DelayedLaunchInfo launchInfo,
-            final AndroidLaunchConfiguration config) {
-
-        // Since this is called from the UI thread we spawn a new thread
-        // to finish the launch.
-        new Thread() {
-            @Override
-            public void run() {
-                if (response.getAvdToLaunch() != null) {
-                    // there was no selected device, we start a new emulator.
-                    synchronized (sListLock) {
-                        AvdInfo info = response.getAvdToLaunch();
-                        mWaitingForEmulatorLaunches.add(launchInfo);
-                        AdtPlugin.printToConsole(project, String.format(
-                                "Launching a new emulator with Virtual Device '%1$s'",
-                                info.getName()));
-                        boolean status = launchEmulator(config, info);
-
-                        if (status == false) {
-                            // launching the emulator failed!
-                            AdtPlugin.displayError("Emulator Launch",
-                                    "Couldn't launch the emulator! Make sure the SDK directory is properly setup and the emulator is not missing.");
-
-                            // stop the launch and return
-                            mWaitingForEmulatorLaunches.remove(launchInfo);
-                            AdtPlugin.printErrorToConsole(project, "Launch canceled!");
-                            stopLaunch(launchInfo);
-                            return;
-                        }
-
-                        return;
-                    }
-                } else if (response.getDeviceToUse() != null) {
-                    launchInfo.setDevice(response.getDeviceToUse());
-                    simpleLaunch(launchInfo, launchInfo.getDevice());
-                }
-            }
-        }.start();
-    }
-
-    /**
-     * Queries for a debugger port for a specific {@link ILaunchConfiguration}.
-     * <p/>
-     * If the configuration and a debugger port where added through
-     * {@link #setPortLaunchConfigAssociation(ILaunchConfiguration, int)}, then this method
-     * will return the debugger port, and remove the configuration from the list.
-     * @param launchConfig the {@link ILaunchConfiguration}
-     * @return the debugger port or {@link LaunchConfigDelegate#INVALID_DEBUG_PORT} if the
-     * configuration was not setup.
-     */
-    static int getPortForConfig(ILaunchConfiguration launchConfig) {
-        synchronized (sListLock) {
-            Integer port = sRunningAppMap.get(launchConfig);
-            if (port != null) {
-                sRunningAppMap.remove(launchConfig);
-                return port;
-            }
-        }
-
-        return LaunchConfigDelegate.INVALID_DEBUG_PORT;
-    }
-
-    /**
-     * Set a {@link ILaunchConfiguration} and its associated debug port, in the list of
-     * launch config to connect directly to a running app instead of doing full launch (sync,
-     * launch, and connect to).
-     * @param launchConfig the {@link ILaunchConfiguration} object.
-     * @param port The debugger port to connect to.
-     */
-    private static void setPortLaunchConfigAssociation(ILaunchConfiguration launchConfig,
-            int port) {
-        synchronized (sListLock) {
-            sRunningAppMap.put(launchConfig, port);
-        }
-    }
-
-    /**
-     * Checks the build information, and returns whether the launch should continue.
-     * <p/>The value tested are:
-     * <ul>
-     * <li>Minimum API version requested by the application. If the target device does not match,
-     * the launch is canceled.</li>
-     * <li>Debuggable attribute of the application and whether or not the device requires it. If
-     * the device requires it and it is not set in the manifest, the launch will be forced to
-     * "release" mode instead of "debug"</li>
-     * <ul>
-     */
-    private boolean checkBuildInfo(DelayedLaunchInfo launchInfo, IDevice device) {
-        if (device != null) {
-            // check the app required API level versus the target device API level
-
-            String deviceVersion = device.getProperty(IDevice.PROP_BUILD_VERSION);
-            String deviceApiLevelString = device.getProperty(IDevice.PROP_BUILD_API_LEVEL);
-            String deviceCodeName = device.getProperty(IDevice.PROP_BUILD_CODENAME);
-
-            int deviceApiLevel = -1;
-            try {
-                deviceApiLevel = Integer.parseInt(deviceApiLevelString);
-            } catch (NumberFormatException e) {
-                // pass, we'll keep the apiLevel value at -1.
-            }
-
-            String requiredApiString = launchInfo.getRequiredApiVersionNumber();
-            if (requiredApiString != null) {
-                int requiredApi = -1;
-                try {
-                    requiredApi = Integer.parseInt(requiredApiString);
-                } catch (NumberFormatException e) {
-                    // pass, we'll keep requiredApi value at -1.
-                }
-
-                if (requiredApi == -1) {
-                    // this means the manifest uses a codename for minSdkVersion
-                    // check that the device is using the same codename
-                    if (requiredApiString.equals(deviceCodeName) == false) {
-                        AdtPlugin.printErrorToConsole(launchInfo.getProject(), String.format(
-                            "ERROR: Application requires a device running '%1$s'!",
-                            requiredApiString));
-                        return false;
-                    }
-                } else {
-                    // app requires a specific API level
-                    if (deviceApiLevel == -1) {
-                        AdtPlugin.printToConsole(launchInfo.getProject(),
-                                "WARNING: Unknown device API version!");
-                    } else if (deviceApiLevel < requiredApi) {
-                        String msg = String.format(
-                                "ERROR: Application requires API version %1$d. Device API version is %2$d (Android %3$s).",
-                                requiredApi, deviceApiLevel, deviceVersion);
-                        AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
-
-                        // abort the launch
-                        return false;
-                    }
-                }
-            } else {
-                // warn the application API level requirement is not set.
-                AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                        "WARNING: Application does not specify an API level requirement!");
-
-                // and display the target device API level (if known)
-                if (deviceApiLevel == -1) {
-                    AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                            "WARNING: Unknown device API version!");
-                } else {
-                    AdtPlugin.printErrorToConsole(launchInfo.getProject(), String.format(
-                            "Device API version is %1$d (Android %2$s)", deviceApiLevel,
-                            deviceVersion));
-                }
-            }
-
-
-            // now checks that the device/app can be debugged (if needed)
-            if (device.isEmulator() == false && launchInfo.isDebugMode()) {
-                String debuggableDevice = device.getProperty(IDevice.PROP_DEBUGGABLE);
-                if (debuggableDevice != null && debuggableDevice.equals("0")) { //$NON-NLS-1$
-                    // the device is "secure" and requires apps to declare themselves as debuggable!
-                    if (launchInfo.getDebuggable() == null) {
-                        String message1 = String.format(
-                                "Device '%1$s' requires that applications explicitely declare themselves as debuggable in their manifest.",
-                                device.getSerialNumber());
-                        String message2 = String.format("Application '%1$s' does not have the attribute 'debuggable' set to TRUE in its manifest and cannot be debugged.",
-                                launchInfo.getPackageName());
-                        AdtPlugin.printErrorToConsole(launchInfo.getProject(), message1, message2);
-
-                        // because am -D does not check for ro.debuggable and the
-                        // 'debuggable' attribute, it is important we do not use the -D option
-                        // in this case or the app will wait for a debugger forever and never
-                        // really launch.
-                        launchInfo.setDebugMode(false);
-                    } else if (launchInfo.getDebuggable() == Boolean.FALSE) {
-                        String message = String.format("Application '%1$s' has its 'debuggable' attribute set to FALSE and cannot be debugged.",
-                                launchInfo.getPackageName());
-                        AdtPlugin.printErrorToConsole(launchInfo.getProject(), message);
-
-                        // because am -D does not check for ro.debuggable and the
-                        // 'debuggable' attribute, it is important we do not use the -D option
-                        // in this case or the app will wait for a debugger forever and never
-                        // really launch.
-                        launchInfo.setDebugMode(false);
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Do a simple launch on the specified device, attempting to sync the new
-     * package, and then launching the application. Failed sync/launch will
-     * stop the current AndroidLaunch and return false;
-     * @param launchInfo
-     * @param device
-     * @return true if succeed
-     */
-    private boolean simpleLaunch(DelayedLaunchInfo launchInfo, IDevice device) {
-        // API level check
-        if (checkBuildInfo(launchInfo, device) == false) {
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), "Launch canceled!");
-            stopLaunch(launchInfo);
-            return false;
-        }
-
-        // sync the app
-        if (syncApp(launchInfo, device) == false) {
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), "Launch canceled!");
-            stopLaunch(launchInfo);
-            return false;
-        }
-
-        // launch the app
-        launchApp(launchInfo, device);
-
-        return true;
-    }
-
-
-    /**
-     * If needed, syncs the application and all its dependencies on the device/emulator.
-     *
-     * @param launchInfo The Launch information object.
-     * @param device the device on which to sync the application
-     * @return true if the install succeeded.
-     */
-    private boolean syncApp(DelayedLaunchInfo launchInfo, IDevice device) {
-        boolean alreadyInstalled = ApkInstallManager.getInstance().isApplicationInstalled(
-                launchInfo.getProject(), device);
-
-        if (alreadyInstalled) {
-            AdtPlugin.printToConsole(launchInfo.getProject(),
-            "Application already deployed. No need to reinstall.");
-        } else {
-            if (doSyncApp(launchInfo, device) == false) {
-                return false;
-            }
-        }
-
-        // The app is now installed, now try the dependent projects
-        for (DelayedLaunchInfo dependentLaunchInfo : getDependenciesLaunchInfo(launchInfo)) {
-            String msg = String.format("Project dependency found, installing: %s",
-                    dependentLaunchInfo.getProject().getName());
-            AdtPlugin.printToConsole(launchInfo.getProject(), msg);
-            if (syncApp(dependentLaunchInfo, device) == false) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Syncs the application on the device/emulator.
-     *
-     * @param launchInfo The Launch information object.
-     * @param device the device on which to sync the application
-     * @return true if the install succeeded.
-     */
-    private boolean doSyncApp(DelayedLaunchInfo launchInfo, IDevice device) {
-        IPath path = launchInfo.getPackageFile().getLocation();
-        String fileName = path.lastSegment();
-        try {
-            String message = String.format("Uploading %1$s onto device '%2$s'",
-                    fileName, device.getSerialNumber());
-            AdtPlugin.printToConsole(launchInfo.getProject(), message);
-
-            String remotePackagePath = device.syncPackageToDevice(path.toOSString());
-            boolean installResult = installPackage(launchInfo, remotePackagePath, device);
-            device.removeRemotePackage(remotePackagePath);
-
-            // if the installation succeeded, we register it.
-            if (installResult) {
-               ApkInstallManager.getInstance().registerInstallation(
-                       launchInfo.getProject(), device);
-            }
-            return installResult;
-        }
-        catch (IOException e) {
-            String msg = String.format("Failed to upload %1$s on device '%2$s'", fileName,
-                    device.getSerialNumber());
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg, e);
-        }
-        return false;
-    }
-
-    /**
-     * For the current launchInfo, create additional DelayedLaunchInfo that should be used to
-     * sync APKs that we are dependent on to the device.
-     *
-     * @param launchInfo the original launch info that we want to find the
-     * @return a list of DelayedLaunchInfo (may be empty if no dependencies were found or error)
-     */
-    public List<DelayedLaunchInfo> getDependenciesLaunchInfo(DelayedLaunchInfo launchInfo) {
-        List<DelayedLaunchInfo> dependencies = new ArrayList<DelayedLaunchInfo>();
-
-        // Convert to equivalent JavaProject
-        IJavaProject javaProject;
-        try {
-            //assuming this is an Android (and Java) project since it is attached to the launchInfo.
-            javaProject = BaseProjectHelper.getJavaProject(launchInfo.getProject());
-        } catch (CoreException e) {
-            // return empty dependencies
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), e);
-            return dependencies;
-        }
-
-        // Get all projects that this depends on
-        List<IJavaProject> androidProjectList;
-        try {
-            androidProjectList = ProjectHelper.getAndroidProjectDependencies(javaProject);
-        } catch (JavaModelException e) {
-            // return empty dependencies
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), e);
-            return dependencies;
-        }
-
-        // for each project, parse manifest and create launch information
-        for (IJavaProject androidProject : androidProjectList) {
-            // Parse the Manifest to get various required information
-            // copied from LaunchConfigDelegate
-            AndroidManifestParser manifestParser;
-            try {
-                manifestParser = AndroidManifestParser.parse(
-                        androidProject, null /* errorListener */,
-                        true /* gatherData */, false /* markErrors */);
-            } catch (CoreException e) {
-                AdtPlugin.printErrorToConsole(
-                        launchInfo.getProject(),
-                        String.format("Error parsing manifest of %s",
-                                androidProject.getElementName()));
-                continue;
-            }
-
-            // Get the APK location (can return null)
-            IFile apk = ProjectHelper.getApplicationPackage(androidProject.getProject());
-            if (apk == null) {
-                // getApplicationPackage will have logged an error message
-                continue;
-            }
-
-            // Create new launchInfo as an hybrid between parent and dependency information
-            DelayedLaunchInfo delayedLaunchInfo = new DelayedLaunchInfo(
-                    androidProject.getProject(),
-                    manifestParser.getPackage(),
-                    manifestParser.getPackage(),
-                    launchInfo.getLaunchAction(),
-                    apk,
-                    manifestParser.getDebuggable(),
-                    manifestParser.getApiLevelRequirement(),
-                    launchInfo.getLaunch(),
-                    launchInfo.getMonitor());
-
-            // Add to the list
-            dependencies.add(delayedLaunchInfo);
-        }
-
-        return dependencies;
-    }
-
-    /**
-     * Installs the application package on the device, and handles return result
-     * @param launchInfo The launch information
-     * @param remotePath The remote path of the package.
-     * @param device The device on which the launch is done.
-     */
-    private boolean installPackage(DelayedLaunchInfo launchInfo, final String remotePath,
-            final IDevice device) {
-        String message = String.format("Installing %1$s...", launchInfo.getPackageFile().getName());
-        AdtPlugin.printToConsole(launchInfo.getProject(), message);
-        try {
-            // try a reinstall first, because the most common case is the app is already installed
-            String result = doInstall(launchInfo, remotePath, device, true /* reinstall */);
-
-            /* For now we force to retry the install (after uninstalling) because there's no
-             * other way around it: adb install does not want to update a package w/o uninstalling
-             * the old one first!
-             */
-            return checkInstallResult(result, device, launchInfo, remotePath,
-                    InstallRetryMode.ALWAYS);
-        } catch (IOException e) {
-            String msg = String.format(
-                    "Failed to install %1$s on device '%2$s!",
-                    launchInfo.getPackageFile().getName(), device.getSerialNumber());
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg, e.getMessage());
-        }
-
-        return false;
-    }
-
-    /**
-     * Checks the result of an installation, and takes optional actions based on it.
-     * @param result the result string from the installation
-     * @param device the device on which the installation occured.
-     * @param launchInfo the {@link DelayedLaunchInfo}
-     * @param remotePath the temporary path of the package on the device
-     * @param retryMode indicates what to do in case, a package already exists.
-     * @return <code>true<code> if success, <code>false</code> otherwise.
-     * @throws IOException
-     */
-    private boolean checkInstallResult(String result, IDevice device, DelayedLaunchInfo launchInfo,
-            String remotePath, InstallRetryMode retryMode) throws IOException {
-        if (result == null) {
-            AdtPlugin.printToConsole(launchInfo.getProject(), "Success!");
-            return true;
-        }
-        else if (result.equals("INSTALL_FAILED_ALREADY_EXISTS")) { //$NON-NLS-1$
-            // this should never happen, since reinstall mode is used on the first attempt
-            if (retryMode == InstallRetryMode.PROMPT) {
-                boolean prompt = AdtPlugin.displayPrompt("Application Install",
-                        "A previous installation needs to be uninstalled before the new package can be installed.\nDo you want to uninstall?");
-                if (prompt) {
-                    retryMode = InstallRetryMode.ALWAYS;
-                } else {
-                    AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                        "Installation error! The package already exists.");
-                    return false;
-                }
-            }
-
-            if (retryMode == InstallRetryMode.ALWAYS) {
-                /*
-                 * TODO: create a UI that gives the dev the choice to:
-                 * - clean uninstall on launch
-                 * - full uninstall if application exists.
-                 * - soft uninstall if application exists (keeps the app data around).
-                 * - always ask (choice of soft-reinstall, full reinstall)
-                AdtPlugin.printErrorToConsole(launchInfo.mProject,
-                        "Application already exists, uninstalling...");
-                String res = doUninstall(device, launchInfo);
-                if (res == null) {
-                    AdtPlugin.printToConsole(launchInfo.mProject, "Success!");
-                } else {
-                    AdtPlugin.printErrorToConsole(launchInfo.mProject,
-                            String.format("Failed to uninstall: %1$s", res));
-                    return false;
-                }
-                */
-
-                AdtPlugin.printToConsole(launchInfo.getProject(),
-                        "Application already exists. Attempting to re-install instead...");
-                String res = doInstall(launchInfo, remotePath, device, true /* reinstall */ );
-                return checkInstallResult(res, device, launchInfo, remotePath,
-                        InstallRetryMode.NEVER);
-            }
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                    "Installation error! The package already exists.");
-        } else if (result.equals("INSTALL_FAILED_INVALID_APK")) { //$NON-NLS-1$
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                "Installation failed due to invalid APK file!",
-                "Please check logcat output for more details.");
-        } else if (result.equals("INSTALL_FAILED_INVALID_URI")) { //$NON-NLS-1$
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                "Installation failed due to invalid URI!",
-                "Please check logcat output for more details.");
-        } else if (result.equals("INSTALL_FAILED_COULDNT_COPY")) { //$NON-NLS-1$
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                String.format("Installation failed: Could not copy %1$s to its final location!",
-                        launchInfo.getPackageFile().getName()),
-                "Please check logcat output for more details.");
-        } else if (result.equals("INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES")) {
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                    "Re-installation failed due to different application signatures.",
-                    "You must perform a full uninstall of the application. WARNING: This will remove the application data!",
-                    String.format("Please execute 'adb uninstall %1$s' in a shell.", launchInfo.getPackageName()));
-        } else {
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                String.format("Installation error: %1$s", result),
-                "Please check logcat output for more details.");
-        }
-
-        return false;
-    }
-
-    /**
-     * Performs the uninstallation of an application.
-     * @param device the device on which to install the application.
-     * @param launchInfo the {@link DelayedLaunchInfo}.
-     * @return a {@link String} with an error code, or <code>null</code> if success.
-     * @throws IOException
-     */
-    @SuppressWarnings("unused")
-    private String doUninstall(IDevice device, DelayedLaunchInfo launchInfo) throws IOException {
-        try {
-            return device.uninstallPackage(launchInfo.getPackageName());
-        } catch (IOException e) {
-            String msg = String.format(
-                    "Failed to uninstall %1$s: %2$s", launchInfo.getPackageName(), e.getMessage());
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
-            throw e;
-        }
-    }
-
-    /**
-     * Performs the installation of an application whose package has been uploaded on the device.
-     *
-     * @param launchInfo the {@link DelayedLaunchInfo}.
-     * @param remotePath the path of the application package in the device tmp folder.
-     * @param device the device on which to install the application.
-     * @param reinstall
-     * @return a {@link String} with an error code, or <code>null</code> if success.
-     * @throws IOException
-     */
-    private String doInstall(DelayedLaunchInfo launchInfo, final String remotePath,
-            final IDevice device, boolean reinstall) throws IOException {
-        return device.installRemotePackage(remotePath, reinstall);
-    }
-
-    /**
-     * launches an application on a device or emulator
-     *
-     * @param info the {@link DelayedLaunchInfo} that indicates the launch action
-     * @param device the device or emulator to launch the application on
-     */
-    public void launchApp(final DelayedLaunchInfo info, IDevice device) {
-        if (info.isDebugMode()) {
-            synchronized (sListLock) {
-                if (mWaitingForDebuggerApplications.contains(info) == false) {
-                    mWaitingForDebuggerApplications.add(info);
-                }
-            }
-        }
-        if (info.getLaunchAction().doLaunchAction(info, device)) {
-            // if the app is not a debug app, we need to do some clean up, as
-            // the process is done!
-            if (info.isDebugMode() == false) {
-                // stop the launch object, since there's no debug, and it can't
-                // provide any control over the app
-                stopLaunch(info);
-            }
-        } else {
-            // something went wrong or no further launch action needed
-            // lets stop the Launch
-            stopLaunch(info);
-        }
-    }
-
-    private boolean launchEmulator(AndroidLaunchConfiguration config, AvdInfo avdToLaunch) {
-
-        // split the custom command line in segments
-        ArrayList<String> customArgs = new ArrayList<String>();
-        boolean hasWipeData = false;
-        if (config.mEmulatorCommandLine != null && config.mEmulatorCommandLine.length() > 0) {
-            String[] segments = config.mEmulatorCommandLine.split("\\s+"); //$NON-NLS-1$
-
-            // we need to remove the empty strings
-            for (String s : segments) {
-                if (s.length() > 0) {
-                    customArgs.add(s);
-                    if (!hasWipeData && s.equals(FLAG_WIPE_DATA)) {
-                        hasWipeData = true;
-                    }
-                }
-            }
-        }
-
-        boolean needsWipeData = config.mWipeData && !hasWipeData;
-        if (needsWipeData) {
-            if (!AdtPlugin.displayPrompt("Android Launch", "Are you sure you want to wipe all user data when starting this emulator?")) {
-                needsWipeData = false;
-            }
-        }
-
-        // build the command line based on the available parameters.
-        ArrayList<String> list = new ArrayList<String>();
-
-        list.add(AdtPlugin.getOsAbsoluteEmulator());
-        list.add(FLAG_AVD);
-        list.add(avdToLaunch.getName());
-
-        if (config.mNetworkSpeed != null) {
-            list.add(FLAG_NETSPEED);
-            list.add(config.mNetworkSpeed);
-        }
-
-        if (config.mNetworkDelay != null) {
-            list.add(FLAG_NETDELAY);
-            list.add(config.mNetworkDelay);
-        }
-
-        if (needsWipeData) {
-            list.add(FLAG_WIPE_DATA);
-        }
-
-        if (config.mNoBootAnim) {
-            list.add(FLAG_NO_BOOT_ANIM);
-        }
-
-        list.addAll(customArgs);
-
-        // convert the list into an array for the call to exec.
-        String[] command = list.toArray(new String[list.size()]);
-
-        // launch the emulator
-        try {
-            Process process = Runtime.getRuntime().exec(command);
-            grabEmulatorOutput(process);
-        } catch (IOException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Looks for and returns an existing {@link ILaunchConfiguration} object for a
-     * specified project.
-     * @param manager The {@link ILaunchManager}.
-     * @param type The {@link ILaunchConfigurationType}.
-     * @param projectName The name of the project
-     * @return an existing <code>ILaunchConfiguration</code> object matching the project, or
-     *      <code>null</code>.
-     */
-    private static ILaunchConfiguration findConfig(ILaunchManager manager,
-            ILaunchConfigurationType type, String projectName) {
-        try {
-            ILaunchConfiguration[] configs = manager.getLaunchConfigurations(type);
-
-            for (ILaunchConfiguration config : configs) {
-                if (config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
-                        "").equals(projectName)) {  //$NON-NLS-1$
-                    return config;
-                }
-            }
-        } catch (CoreException e) {
-            MessageDialog.openError(AdtPlugin.getDisplay().getActiveShell(),
-                    "Launch Error", e.getStatus().getMessage());
-        }
-
-        // didn't find anything that matches. Return null
-        return null;
-
-    }
-
-
-    /**
-     * Connects a remote debugger on the specified port.
-     * @param debugPort The port to connect the debugger to
-     * @param launch The associated AndroidLaunch object.
-     * @param monitor A Progress monitor
-     * @return false if cancelled by the monitor
-     * @throws CoreException
-     */
-    public static boolean connectRemoteDebugger(int debugPort,
-            AndroidLaunch launch, IProgressMonitor monitor)
-                throws CoreException {
-        // get some default parameters.
-        int connectTimeout = JavaRuntime.getPreferences().getInt(JavaRuntime.PREF_CONNECT_TIMEOUT);
-
-        HashMap<String, String> newMap = new HashMap<String, String>();
-
-        newMap.put("hostname", "localhost");  //$NON-NLS-1$ //$NON-NLS-2$
-
-        newMap.put("port", Integer.toString(debugPort)); //$NON-NLS-1$
-
-        newMap.put("timeout", Integer.toString(connectTimeout));
-
-        // get the default VM connector
-        IVMConnector connector = JavaRuntime.getDefaultVMConnector();
-
-        // connect to remote VM
-        connector.connect(newMap, monitor, launch);
-
-        // check for cancellation
-        if (monitor.isCanceled()) {
-            IDebugTarget[] debugTargets = launch.getDebugTargets();
-            for (IDebugTarget target : debugTargets) {
-                if (target.canDisconnect()) {
-                    target.disconnect();
-                }
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Launch a new thread that connects a remote debugger on the specified port.
-     * @param debugPort The port to connect the debugger to
-     * @param androidLaunch The associated AndroidLaunch object.
-     * @param monitor A Progress monitor
-     * @see #connectRemoteDebugger(int, AndroidLaunch, IProgressMonitor)
-     */
-    public static void launchRemoteDebugger(final int debugPort, final AndroidLaunch androidLaunch,
-            final IProgressMonitor monitor) {
-        new Thread("Debugger connection") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                try {
-                    connectRemoteDebugger(debugPort, androidLaunch, monitor);
-                } catch (CoreException e) {
-                    androidLaunch.stopLaunch();
-                }
-                monitor.done();
-            }
-        }.start();
-    }
-
-    /**
-     * Sent when a new {@link AndroidDebugBridge} is started.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param bridge the new {@link AndroidDebugBridge} object.
-     *
-     * @see IDebugBridgeChangeListener#bridgeChanged(AndroidDebugBridge)
-     */
-    public void bridgeChanged(AndroidDebugBridge bridge) {
-        // The adb server has changed. We cancel any pending launches.
-        String message = "adb server change: cancelling '%1$s'!";
-        synchronized (sListLock) {
-            for (DelayedLaunchInfo launchInfo : mWaitingForReadyEmulatorList) {
-                AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                    String.format(message, launchInfo.getLaunchAction().getLaunchDescription()));
-                stopLaunch(launchInfo);
-            }
-            for (DelayedLaunchInfo launchInfo : mWaitingForDebuggerApplications) {
-                AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                        String.format(message,
-                                launchInfo.getLaunchAction().getLaunchDescription()));
-                stopLaunch(launchInfo);
-            }
-
-            mWaitingForReadyEmulatorList.clear();
-            mWaitingForDebuggerApplications.clear();
-        }
-    }
-
-    /**
-     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceConnected(IDevice)
-     */
-    public void deviceConnected(IDevice device) {
-        synchronized (sListLock) {
-            // look if there's an app waiting for a device
-            if (mWaitingForEmulatorLaunches.size() > 0) {
-                // get/remove first launch item from the list
-                // FIXME: what if we have multiple launches waiting?
-                DelayedLaunchInfo launchInfo = mWaitingForEmulatorLaunches.get(0);
-                mWaitingForEmulatorLaunches.remove(0);
-
-                // give the launch item its device for later use.
-                launchInfo.setDevice(device);
-
-                // and move it to the other list
-                mWaitingForReadyEmulatorList.add(launchInfo);
-
-                // and tell the user about it
-                AdtPlugin.printToConsole(launchInfo.getProject(),
-                        String.format("New emulator found: %1$s", device.getSerialNumber()));
-                AdtPlugin.printToConsole(launchInfo.getProject(),
-                        String.format("Waiting for HOME ('%1$s') to be launched...",
-                            AdtPlugin.getDefault().getPreferenceStore().getString(
-                                    AdtPlugin.PREFS_HOME_PACKAGE)));
-            }
-        }
-    }
-
-    /**
-     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceDisconnected(IDevice)
-     */
-    @SuppressWarnings("unchecked")
-    public void deviceDisconnected(IDevice device) {
-        // any pending launch on this device must be canceled.
-        String message = "%1$s disconnected! Cancelling '%2$s'!";
-        synchronized (sListLock) {
-            ArrayList<DelayedLaunchInfo> copyList =
-                (ArrayList<DelayedLaunchInfo>) mWaitingForReadyEmulatorList.clone();
-            for (DelayedLaunchInfo launchInfo : copyList) {
-                if (launchInfo.getDevice() == device) {
-                    AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                            String.format(message, device.getSerialNumber(),
-                                    launchInfo.getLaunchAction().getLaunchDescription()));
-                    stopLaunch(launchInfo);
-                }
-            }
-            copyList = (ArrayList<DelayedLaunchInfo>) mWaitingForDebuggerApplications.clone();
-            for (DelayedLaunchInfo launchInfo : copyList) {
-                if (launchInfo.getDevice() == device) {
-                    AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                            String.format(message, device.getSerialNumber(),
-                                    launchInfo.getLaunchAction().getLaunchDescription()));
-                    stopLaunch(launchInfo);
-                }
-            }
-        }
-    }
-
-    /**
-     * Sent when a device data changed, or when clients are started/terminated on the device.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the device that was updated.
-     * @param changeMask the mask indicating what changed.
-     *
-     * @see IDeviceChangeListener#deviceChanged(IDevice, int)
-     */
-    public void deviceChanged(IDevice device, int changeMask) {
-        // We could check if any starting device we care about is now ready, but we can wait for
-        // its home app to show up, so...
-    }
-
-    /**
-     * Sent when an existing client information changed.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param client the updated client.
-     * @param changeMask the bit mask describing the changed properties. It can contain
-     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
-     * {@link Client#CHANGE_DEBUGGER_STATUS}, {@link Client#CHANGE_THREAD_MODE},
-     * {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE},
-     * {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
-     *
-     * @see IClientChangeListener#clientChanged(Client, int)
-     */
-    public void clientChanged(final Client client, int changeMask) {
-        boolean connectDebugger = false;
-        if ((changeMask & Client.CHANGE_NAME) == Client.CHANGE_NAME) {
-            String applicationName = client.getClientData().getClientDescription();
-            if (applicationName != null) {
-                IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
-                String home = store.getString(AdtPlugin.PREFS_HOME_PACKAGE);
-
-                if (home.equals(applicationName)) {
-
-                    // looks like home is up, get its device
-                    IDevice device = client.getDevice();
-
-                    // look for application waiting for home
-                    synchronized (sListLock) {
-                        for (int i = 0; i < mWaitingForReadyEmulatorList.size(); ) {
-                            DelayedLaunchInfo launchInfo = mWaitingForReadyEmulatorList.get(i);
-                            if (launchInfo.getDevice() == device) {
-                                // it's match, remove from the list
-                                mWaitingForReadyEmulatorList.remove(i);
-
-                                // We couldn't check earlier the API level of the device
-                                // (it's asynchronous when the device boot, and usually
-                                // deviceConnected is called before it's queried for its build info)
-                                // so we check now
-                                if (checkBuildInfo(launchInfo, device) == false) {
-                                    // device is not the proper API!
-                                    AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                                            "Launch canceled!");
-                                    stopLaunch(launchInfo);
-                                    return;
-                                }
-
-                                AdtPlugin.printToConsole(launchInfo.getProject(),
-                                        String.format("HOME is up on device '%1$s'",
-                                                device.getSerialNumber()));
-
-                                // attempt to sync the new package onto the device.
-                                if (syncApp(launchInfo, device)) {
-                                    // application package is sync'ed, lets attempt to launch it.
-                                    launchApp(launchInfo, device);
-                                } else {
-                                    // failure! Cancel and return
-                                    AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                                    "Launch canceled!");
-                                    stopLaunch(launchInfo);
-                                }
-
-                                break;
-                            } else {
-                                i++;
-                            }
-                        }
-                    }
-                }
-
-                // check if it's already waiting for a debugger, and if so we connect to it.
-                if (client.getClientData().getDebuggerConnectionStatus() == DebuggerStatus.WAITING) {
-                    // search for this client in the list;
-                    synchronized (sListLock) {
-                        int index = mUnknownClientsWaitingForDebugger.indexOf(client);
-                        if (index != -1) {
-                            connectDebugger = true;
-                            mUnknownClientsWaitingForDebugger.remove(client);
-                        }
-                    }
-                }
-            }
-        }
-
-        // if it's not home, it could be an app that is now in debugger mode that we're waiting for
-        // lets check it
-
-        if ((changeMask & Client.CHANGE_DEBUGGER_STATUS) == Client.CHANGE_DEBUGGER_STATUS) {
-            ClientData clientData = client.getClientData();
-            String applicationName = client.getClientData().getClientDescription();
-            if (clientData.getDebuggerConnectionStatus() == DebuggerStatus.WAITING) {
-                // Get the application name, and make sure its valid.
-                if (applicationName == null) {
-                    // looks like we don't have the client yet, so we keep it around for when its
-                    // name becomes available.
-                    synchronized (sListLock) {
-                        mUnknownClientsWaitingForDebugger.add(client);
-                    }
-                    return;
-                } else {
-                    connectDebugger = true;
-                }
-            }
-        }
-
-        if (connectDebugger) {
-            Log.d("adt", "Debugging " + client);
-            // now check it against the apps waiting for a debugger
-            String applicationName = client.getClientData().getClientDescription();
-            Log.d("adt", "App Name: " + applicationName);
-            synchronized (sListLock) {
-                for (int i = 0; i < mWaitingForDebuggerApplications.size(); ) {
-                    final DelayedLaunchInfo launchInfo = mWaitingForDebuggerApplications.get(i);
-                    if (client.getDevice() == launchInfo.getDevice() &&
-                            applicationName.equals(launchInfo.getDebugPackageName())) {
-                        // this is a match. We remove the launch info from the list
-                        mWaitingForDebuggerApplications.remove(i);
-
-                        // and connect the debugger.
-                        String msg = String.format(
-                                "Attempting to connect debugger to '%1$s' on port %2$d",
-                                launchInfo.getDebugPackageName(), client.getDebuggerListenPort());
-                        AdtPlugin.printToConsole(launchInfo.getProject(), msg);
-
-                        new Thread("Debugger Connection") { //$NON-NLS-1$
-                            @Override
-                            public void run() {
-                                try {
-                                    if (connectRemoteDebugger(
-                                            client.getDebuggerListenPort(),
-                                            launchInfo.getLaunch(),
-                                            launchInfo.getMonitor()) == false) {
-                                        return;
-                                    }
-                                } catch (CoreException e) {
-                                    // well something went wrong.
-                                    AdtPlugin.printErrorToConsole(launchInfo.getProject(),
-                                            String.format("Launch error: %s", e.getMessage()));
-                                    // stop the launch
-                                    stopLaunch(launchInfo);
-                                }
-
-                                launchInfo.getMonitor().done();
-                            }
-                        }.start();
-
-                        // we're done processing this client.
-                        return;
-
-                    } else {
-                        i++;
-                    }
-                }
-            }
-
-            // if we get here, we haven't found an app that we were launching, so we look
-            // for opened android projects that contains the app asking for a debugger.
-            // If we find one, we automatically connect to it.
-            IProject project = ProjectHelper.findAndroidProjectByAppName(applicationName);
-
-            if (project != null) {
-                debugRunningApp(project, client.getDebuggerListenPort());
-            }
-        }
-    }
-
-    /**
-     * Get the stderr/stdout outputs of a process and return when the process is done.
-     * Both <b>must</b> be read or the process will block on windows.
-     * @param process The process to get the output from
-     */
-    private void grabEmulatorOutput(final Process process) {
-        // read the lines as they come. if null is returned, it's
-        // because the process finished
-        new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            AdtPlugin.printErrorToConsole("Emulator", line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        }.start();
-
-        new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            AdtPlugin.printToConsole("Emulator", line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        }.start();
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ide.eclipse.adt.launch.ILaunchController#stopLaunch(com.android.ide.eclipse.adt.launch.AndroidLaunchController.DelayedLaunchInfo)
-     */
-    public void stopLaunch(DelayedLaunchInfo launchInfo) {
-        launchInfo.getLaunch().stopLaunch();
-        synchronized (sListLock) {
-            mWaitingForReadyEmulatorList.remove(launchInfo);
-            mWaitingForDebuggerApplications.remove(launchInfo);
-        }
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DelayedLaunchInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DelayedLaunchInfo.java
deleted file mode 100644
index 01c94fe..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DelayedLaunchInfo.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.IDevice;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-/**
- * A delayed launch waiting for a device to be present or ready before the
- * application is launched.
- */
-public final class DelayedLaunchInfo {
-
-    /**
-     * Used to indicate behavior when Android app already exists
-     */
-    enum InstallRetryMode {
-        NEVER, ALWAYS, PROMPT;
-    }
-
-    /** The device on which to launch the app */
-    private IDevice mDevice = null;
-
-    /** The eclipse project */
-    private final IProject mProject;
-
-    /** Package name */
-    private final String mPackageName;
-
-    /** Debug package name */
-    private final String mDebugPackageName;
-
-    /** IFile to the package (.apk) file */
-    private final IFile mPackageFile;
-
-    /** debuggable attribute of the manifest file. */
-    private final Boolean mDebuggable;
-
-    /** Required Api level by the app. null means no requirements */
-    private final String mRequiredApiVersionNumber;
-
-    private InstallRetryMode mRetryMode = InstallRetryMode.NEVER;
-
-    /** Launch action. */
-    private final IAndroidLaunchAction mLaunchAction;
-
-    /** the launch object */
-    private final AndroidLaunch mLaunch;
-
-    /** the monitor object */
-    private final IProgressMonitor mMonitor;
-
-    /** debug mode flag */
-    private boolean mDebugMode;
-
-    /** current number of launch attempts */
-    private int mAttemptCount = 0;
-
-    /** cancellation state of launch */
-    private boolean mCancelled = false;
-
-    /**
-     * Basic constructor with activity and package info.
-     *
-     * @param project the eclipse project that corresponds to Android app
-     * @param packageName package name of Android app
-     * @param debugPackageName the package name of the Andriod app to debug
-     * @param launchAction action to perform after app install
-     * @param pack IFile to the package (.apk) file
-     * @param debuggable debuggable attribute of the app's manifest file.
-     * @param requiredApiVersionNumber required SDK version by the app. null means no requirements.
-     * @param launch the launch object
-     * @param monitor progress monitor for launch
-     */
-    public DelayedLaunchInfo(IProject project, String packageName, String debugPackageName,
-            IAndroidLaunchAction launchAction, IFile pack, Boolean debuggable,
-            String requiredApiVersionNumber, AndroidLaunch launch, IProgressMonitor monitor) {
-        mProject = project;
-        mPackageName = packageName;
-        mDebugPackageName = debugPackageName;
-        mPackageFile = pack;
-        mLaunchAction = launchAction;
-        mLaunch = launch;
-        mMonitor = monitor;
-        mDebuggable = debuggable;
-        mRequiredApiVersionNumber = requiredApiVersionNumber;
-    }
-
-    /**
-     * @return the device on which to launch the app
-     */
-    public IDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Set the device on which to launch the app
-     */
-    public void setDevice(IDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * @return the eclipse project that corresponds to Android app
-     */
-    public IProject getProject() {
-        return mProject;
-    }
-
-    /**
-     * @return the package name of the Android app
-     */
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /**
-     * Returns the Android app process name that the debugger should connect to. Typically this is
-     * the same value as {@link #getPackageName()}.
-     */
-    public String getDebugPackageName() {
-        if (mDebugPackageName == null) {
-            return getPackageName();
-        }
-        return mDebugPackageName;
-    }
-
-    /**
-     * @return the application package file
-     */
-    public IFile getPackageFile() {
-        return mPackageFile;
-    }
-
-    /**
-     * @return true if Android app is marked as debuggable in its manifest
-     */
-    public Boolean getDebuggable() {
-        return mDebuggable;
-    }
-
-    /**
-     * @return the required api version number for the Android app.
-     */
-    public String getRequiredApiVersionNumber() {
-        return mRequiredApiVersionNumber;
-    }
-
-    /**
-     * @param retryMode the install retry mode to set
-     */
-    public void setRetryMode(InstallRetryMode retryMode) {
-        this.mRetryMode = retryMode;
-    }
-
-    /**
-     * @return the installation retry mode
-     */
-    public InstallRetryMode getRetryMode() {
-        return mRetryMode;
-    }
-
-    /**
-     * @return the launch action
-     */
-    public IAndroidLaunchAction getLaunchAction() {
-        return mLaunchAction;
-    }
-
-    /**
-     * @return the launch
-     */
-    public AndroidLaunch getLaunch() {
-        return mLaunch;
-    }
-
-    /**
-     * @return the launch progress monitor
-     */
-    public IProgressMonitor getMonitor() {
-        return mMonitor;
-    }
-
-    /**
-     * @param debugMode the debug mode to set
-     */
-    public void setDebugMode(boolean debugMode) {
-        this.mDebugMode = debugMode;
-    }
-
-    /**
-     * @return true if this is a debug launch
-     */
-    public boolean isDebugMode() {
-        return mDebugMode;
-    }
-
-    /**
-     * Increases the number of launch attempts
-     */
-    public void incrementAttemptCount() {
-        mAttemptCount++;
-    }
-
-    /**
-     * @return the number of launch attempts made
-     */
-    public int getAttemptCount() {
-        return mAttemptCount;
-    }
-
-    /**
-     * Set if launch has been cancelled
-     */
-    public void setCancelled(boolean cancelled) {
-        this.mCancelled = cancelled;
-    }
-
-    /**
-     * @return true if launch has been cancelled
-     */
-    public boolean isCancelled() {
-        return mCancelled;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java
deleted file mode 100644
index 315f456..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ddmlib.IDevice.DeviceState;
-import com.android.ddmuilib.IImageLoader;
-import com.android.ddmuilib.ImageHelper;
-import com.android.ddmuilib.TableHelper;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-import com.android.sdkuilib.internal.widgets.AvdSelector;
-import com.android.sdkuilib.internal.widgets.AvdSelector.DisplayMode;
-import com.android.sdkuilib.internal.widgets.AvdSelector.IAvdFilter;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-
-/**
- * A dialog that lets the user choose a device to deploy an application.
- * The user can either choose an exiting running device (including running emulators)
- * or start a new emulator using an Android Virtual Device configuration that matches
- * the current project.
- */
-public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener {
-
-    private final static int ICON_WIDTH = 16;
-
-    private Table mDeviceTable;
-    private TableViewer mViewer;
-    private AvdSelector mPreferredAvdSelector;
-
-    private Image mDeviceImage;
-    private Image mEmulatorImage;
-    private Image mMatchImage;
-    private Image mNoMatchImage;
-    private Image mWarningImage;
-
-    private final DeviceChooserResponse mResponse;
-    private final String mPackageName;
-    private final IAndroidTarget mProjectTarget;
-    private final Sdk mSdk;
-
-    private Button mDeviceRadioButton;
-
-    private boolean mDisableAvdSelectionChange = false;
-
-    /**
-     * Basic Content Provider for a table full of {@link IDevice} objects. The input is
-     * a {@link AndroidDebugBridge}.
-     */
-    private class ContentProvider implements IStructuredContentProvider {
-        public Object[] getElements(Object inputElement) {
-            if (inputElement instanceof AndroidDebugBridge) {
-                return ((AndroidDebugBridge)inputElement).getDevices();
-            }
-
-            return new Object[0];
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            // pass
-        }
-    }
-
-
-    /**
-     * A Label Provider for the {@link TableViewer} in {@link DeviceChooserDialog}.
-     * It provides labels and images for {@link IDevice} objects.
-     */
-    private class LabelProvider implements ITableLabelProvider {
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            if (element instanceof IDevice) {
-                IDevice device = (IDevice)element;
-                switch (columnIndex) {
-                    case 0:
-                        return device.isEmulator() ? mEmulatorImage : mDeviceImage;
-
-                    case 2:
-                        // check for compatibility.
-                        if (device.isEmulator() == false) { // physical device
-                            // get the version of the device
-                            AndroidVersion deviceVersion = Sdk.getDeviceVersion(device);
-                            if (deviceVersion == null) {
-                                return mWarningImage;
-                            } else {
-                                if (deviceVersion.canRun(mProjectTarget.getVersion()) == false) {
-                                    return mNoMatchImage;
-                                }
-
-                                // if the project is compiling against an add-on,
-                                // the optional API may be missing from the device.
-                                return mProjectTarget.isPlatform() ?
-                                        mMatchImage : mWarningImage;
-                            }
-                        } else {
-                            // get the AvdInfo
-                            AvdInfo info = mSdk.getAvdManager().getAvd(device.getAvdName(),
-                                    true /*validAvdOnly*/);
-                            if (info == null) {
-                                return mWarningImage;
-                            }
-                            return mProjectTarget.isCompatibleBaseFor(info.getTarget()) ?
-                                    mMatchImage : mNoMatchImage;
-                        }
-                }
-            }
-
-            return null;
-        }
-
-        public String getColumnText(Object element, int columnIndex) {
-            if (element instanceof IDevice) {
-                IDevice device = (IDevice)element;
-                switch (columnIndex) {
-                    case 0:
-                        return device.getSerialNumber();
-                    case 1:
-                        if (device.isEmulator()) {
-                            return device.getAvdName();
-                        } else {
-                            return "N/A"; // devices don't have AVD names.
-                        }
-                    case 2:
-                        if (device.isEmulator()) {
-                            AvdInfo info = mSdk.getAvdManager().getAvd(device.getAvdName(),
-                                    true /*validAvdOnly*/);
-                            if (info == null) {
-                                return "?";
-                            }
-                            return info.getTarget().getFullName();
-                        } else {
-                            String deviceBuild = device.getProperty(IDevice.PROP_BUILD_VERSION);
-                            if (deviceBuild == null) {
-                                return "unknown";
-                            }
-                            return deviceBuild;
-                        }
-                    case 3:
-                        String debuggable = device.getProperty(IDevice.PROP_DEBUGGABLE);
-                        if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$
-                            return "Yes";
-                        } else {
-                            return "";
-                        }
-                    case 4:
-                        return getStateString(device);
-                }
-            }
-
-            return null;
-        }
-
-        public void addListener(ILabelProviderListener listener) {
-            // pass
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public boolean isLabelProperty(Object element, String property) {
-            // pass
-            return false;
-        }
-
-        public void removeListener(ILabelProviderListener listener) {
-            // pass
-        }
-    }
-
-    public static class DeviceChooserResponse {
-        private AvdInfo mAvdToLaunch;
-        private IDevice mDeviceToUse;
-
-        public void setDeviceToUse(IDevice d) {
-            mDeviceToUse = d;
-            mAvdToLaunch = null;
-        }
-
-        public void setAvdToLaunch(AvdInfo avd) {
-            mAvdToLaunch = avd;
-            mDeviceToUse = null;
-        }
-
-        public IDevice getDeviceToUse() {
-            return mDeviceToUse;
-        }
-
-        public AvdInfo getAvdToLaunch() {
-            return mAvdToLaunch;
-        }
-    }
-
-    public DeviceChooserDialog(Shell parent, DeviceChooserResponse response, String packageName,
-            IAndroidTarget projectTarget) {
-        super(parent);
-        mResponse = response;
-        mPackageName = packageName;
-        mProjectTarget = projectTarget;
-        mSdk = Sdk.getCurrent();
-
-        AndroidDebugBridge.addDeviceChangeListener(this);
-        loadImages();
-    }
-
-    private void cleanup() {
-        // done listening.
-        AndroidDebugBridge.removeDeviceChangeListener(this);
-
-        mEmulatorImage.dispose();
-        mDeviceImage.dispose();
-        mMatchImage.dispose();
-        mNoMatchImage.dispose();
-        mWarningImage.dispose();
-    }
-
-    @Override
-    protected void okPressed() {
-        cleanup();
-        super.okPressed();
-    }
-
-    @Override
-    protected void cancelPressed() {
-        cleanup();
-        super.cancelPressed();
-    }
-
-    @Override
-    protected Control createContents(Composite parent) {
-        Control content = super.createContents(parent);
-
-        // this must be called after createContents() has happened so that the
-        // ok button has been created (it's created after the call to createDialogArea)
-        updateDefaultSelection();
-
-        return content;
-    }
-
-
-    @Override
-    protected Control createDialogArea(Composite parent) {
-        // set dialog title
-        getShell().setText("Android Device Chooser");
-
-        Composite top = new Composite(parent, SWT.NONE);
-        top.setLayout(new GridLayout(1, true));
-
-        Label label = new Label(top, SWT.NONE);
-        label.setText(String.format("Select a device compatible with target %s.",
-                mProjectTarget.getFullName()));
-
-        mDeviceRadioButton = new Button(top, SWT.RADIO);
-        mDeviceRadioButton.setText("Choose a running Android device");
-        mDeviceRadioButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                boolean deviceMode = mDeviceRadioButton.getSelection();
-
-                mDeviceTable.setEnabled(deviceMode);
-                mPreferredAvdSelector.setEnabled(!deviceMode);
-
-                if (deviceMode) {
-                    handleDeviceSelection();
-                } else {
-                    mResponse.setAvdToLaunch(mPreferredAvdSelector.getSelected());
-                }
-
-                enableOkButton();
-            }
-        });
-        mDeviceRadioButton.setSelection(true);
-
-
-        // offset the selector from the radio button
-        Composite offsetComp = new Composite(top, SWT.NONE);
-        offsetComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        GridLayout layout = new GridLayout(1, false);
-        layout.marginRight = layout.marginHeight = 0;
-        layout.marginLeft = 30;
-        offsetComp.setLayout(layout);
-
-        mDeviceTable = new Table(offsetComp, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER);
-        GridData gd;
-        mDeviceTable.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
-        gd.heightHint = 100;
-
-        mDeviceTable.setHeaderVisible(true);
-        mDeviceTable.setLinesVisible(true);
-
-        TableHelper.createTableColumn(mDeviceTable, "Serial Number",
-                SWT.LEFT, "AAA+AAAAAAAAAAAAAAAAAAA", //$NON-NLS-1$
-                null /* prefs name */, null /* prefs store */);
-
-        TableHelper.createTableColumn(mDeviceTable, "AVD Name",
-                SWT.LEFT, "AAAAAAAAAAAAAAAAAAA", //$NON-NLS-1$
-                null /* prefs name */, null /* prefs store */);
-
-        TableHelper.createTableColumn(mDeviceTable, "Target",
-                SWT.LEFT, "AAA+Android 9.9.9", //$NON-NLS-1$
-                null /* prefs name */, null /* prefs store */);
-
-        TableHelper.createTableColumn(mDeviceTable, "Debug",
-                SWT.LEFT, "Debug", //$NON-NLS-1$
-                null /* prefs name */, null /* prefs store */);
-
-        TableHelper.createTableColumn(mDeviceTable, "State",
-                SWT.LEFT, "bootloader", //$NON-NLS-1$
-                null /* prefs name */, null /* prefs store */);
-
-        // create the viewer for it
-        mViewer = new TableViewer(mDeviceTable);
-        mViewer.setContentProvider(new ContentProvider());
-        mViewer.setLabelProvider(new LabelProvider());
-        mViewer.setInput(AndroidDebugBridge.getBridge());
-
-        mDeviceTable.addSelectionListener(new SelectionAdapter() {
-            /**
-             * Handles single-click selection on the device selector.
-             * {@inheritDoc}
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                handleDeviceSelection();
-            }
-
-            /**
-             * Handles double-click selection on the device selector.
-             * Note that the single-click handler will probably already have been called.
-             * {@inheritDoc}
-             */
-            @Override
-            public void widgetDefaultSelected(SelectionEvent e) {
-                handleDeviceSelection();
-                if (isOkButtonEnabled()) {
-                    okPressed();
-                }
-            }
-        });
-
-        Button radio2 = new Button(top, SWT.RADIO);
-        radio2.setText("Launch a new Android Virtual Device");
-
-        // offset the selector from the radio button
-        offsetComp = new Composite(top, SWT.NONE);
-        offsetComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        layout = new GridLayout(1, false);
-        layout.marginRight = layout.marginHeight = 0;
-        layout.marginLeft = 30;
-        offsetComp.setLayout(layout);
-
-        mPreferredAvdSelector = new AvdSelector(offsetComp,
-                mSdk.getSdkLocation(),
-                mSdk.getAvdManager(),
-                new NonRunningAvdFilter(),
-                DisplayMode.SIMPLE_SELECTION);
-        mPreferredAvdSelector.setTableHeightHint(100);
-        mPreferredAvdSelector.setEnabled(false);
-        mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
-            /**
-             * Handles single-click selection on the AVD selector.
-             * {@inheritDoc}
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mDisableAvdSelectionChange == false) {
-                    mResponse.setAvdToLaunch(mPreferredAvdSelector.getSelected());
-                    enableOkButton();
-                }
-            }
-
-            /**
-             * Handles double-click selection on the AVD selector.
-             *
-             * Note that the single-click handler will probably already have been called
-             * but the selected item can have changed in between.
-             *
-             * {@inheritDoc}
-             */
-            @Override
-            public void widgetDefaultSelected(SelectionEvent e) {
-                widgetSelected(e);
-                if (isOkButtonEnabled()) {
-                    okPressed();
-                }
-            }
-        });
-
-
-        return top;
-    }
-
-    private void loadImages() {
-        IImageLoader ddmsLoader = DdmsPlugin.getImageLoader();
-        Display display = DdmsPlugin.getDisplay();
-        IImageLoader adtLoader = AdtPlugin.getImageLoader();
-
-        if (mDeviceImage == null) {
-            mDeviceImage = ImageHelper.loadImage(ddmsLoader, display,
-                    "device.png", //$NON-NLS-1$
-                    ICON_WIDTH, ICON_WIDTH,
-                    display.getSystemColor(SWT.COLOR_RED));
-        }
-        if (mEmulatorImage == null) {
-            mEmulatorImage = ImageHelper.loadImage(ddmsLoader, display,
-                    "emulator.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
-                    display.getSystemColor(SWT.COLOR_BLUE));
-        }
-
-        if (mMatchImage == null) {
-            mMatchImage = ImageHelper.loadImage(adtLoader, display,
-                    "match.png", //$NON-NLS-1$
-                    ICON_WIDTH, ICON_WIDTH,
-                    display.getSystemColor(SWT.COLOR_GREEN));
-        }
-
-        if (mNoMatchImage == null) {
-            mNoMatchImage = ImageHelper.loadImage(adtLoader, display,
-                    "error.png", //$NON-NLS-1$
-                    ICON_WIDTH, ICON_WIDTH,
-                    display.getSystemColor(SWT.COLOR_RED));
-        }
-
-        if (mWarningImage == null) {
-            mWarningImage = ImageHelper.loadImage(adtLoader, display,
-                    "warning.png", //$NON-NLS-1$
-                    ICON_WIDTH, ICON_WIDTH,
-                    display.getSystemColor(SWT.COLOR_YELLOW));
-        }
-
-    }
-
-    /**
-     * Returns a display string representing the state of the device.
-     * @param d the device
-     */
-    private static String getStateString(IDevice d) {
-        DeviceState deviceState = d.getState();
-        if (deviceState == DeviceState.ONLINE) {
-            return "Online";
-        } else if (deviceState == DeviceState.OFFLINE) {
-            return "Offline";
-        } else if (deviceState == DeviceState.BOOTLOADER) {
-            return "Bootloader";
-        }
-
-        return "??";
-    }
-
-    /**
-     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceConnected(IDevice)
-     */
-    public void deviceConnected(IDevice device) {
-        final DeviceChooserDialog dialog = this;
-        exec(new Runnable() {
-            public void run() {
-                if (mDeviceTable.isDisposed() == false) {
-                    // refresh all
-                    mViewer.refresh();
-
-                    // update the selection
-                    updateDefaultSelection();
-
-                    // update the display of AvdInfo (since it's filtered to only display
-                    // non running AVD.)
-                    refillAvdList(false /*reloadAvds*/);
-                } else {
-                    // table is disposed, we need to do something.
-                    // lets remove ourselves from the listener.
-                    AndroidDebugBridge.removeDeviceChangeListener(dialog);
-                }
-
-            }
-        });
-    }
-
-    /**
-     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceDisconnected(IDevice)
-     */
-    public void deviceDisconnected(IDevice device) {
-        deviceConnected(device);
-    }
-
-    /**
-     * Sent when a device data changed, or when clients are started/terminated on the device.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the device that was updated.
-     * @param changeMask the mask indicating what changed.
-     *
-     * @see IDeviceChangeListener#deviceChanged(IDevice, int)
-     */
-    public void deviceChanged(final IDevice device, int changeMask) {
-        if ((changeMask & (IDevice.CHANGE_STATE | IDevice.CHANGE_BUILD_INFO)) != 0) {
-            final DeviceChooserDialog dialog = this;
-            exec(new Runnable() {
-                public void run() {
-                    if (mDeviceTable.isDisposed() == false) {
-                        // refresh the device
-                        mViewer.refresh(device);
-
-                        // update the defaultSelection.
-                        updateDefaultSelection();
-
-                        // update the display of AvdInfo (since it's filtered to only display
-                        // non running AVD). This is done on deviceChanged because the avd name
-                        // of a (emulator) device may be updated as the emulator boots.
-
-                        refillAvdList(false /*reloadAvds*/);
-
-                        // if the changed device is the current selection,
-                        // we update the OK button based on its state.
-                        if (device == mResponse.getDeviceToUse()) {
-                            enableOkButton();
-                        }
-
-                    } else {
-                        // table is disposed, we need to do something.
-                        // lets remove ourselves from the listener.
-                        AndroidDebugBridge.removeDeviceChangeListener(dialog);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Returns whether the dialog is in "device" mode (true), or in "avd" mode (false).
-     */
-    private boolean isDeviceMode() {
-        return mDeviceRadioButton.getSelection();
-    }
-
-    /**
-     * Enables or disables the OK button of the dialog based on various selections in the dialog.
-     */
-    private void enableOkButton() {
-        Button okButton = getButton(IDialogConstants.OK_ID);
-
-        if (isDeviceMode()) {
-            okButton.setEnabled(mResponse.getDeviceToUse() != null &&
-                    mResponse.getDeviceToUse().isOnline());
-        } else {
-            okButton.setEnabled(mResponse.getAvdToLaunch() != null);
-        }
-    }
-
-    /**
-     * Returns true if the ok button is enabled.
-     */
-    private boolean isOkButtonEnabled() {
-        Button okButton = getButton(IDialogConstants.OK_ID);
-        return okButton.isEnabled();
-    }
-
-    /**
-     * Executes the {@link Runnable} in the UI thread.
-     * @param runnable the runnable to execute.
-     */
-    private void exec(Runnable runnable) {
-        try {
-            Display display = mDeviceTable.getDisplay();
-            display.asyncExec(runnable);
-        } catch (SWTException e) {
-            // tree is disposed, we need to do something. lets remove ourselves from the listener.
-            AndroidDebugBridge.removeDeviceChangeListener(this);
-        }
-    }
-
-    private void handleDeviceSelection() {
-        int count = mDeviceTable.getSelectionCount();
-        if (count != 1) {
-            handleSelection(null);
-        } else {
-            int index = mDeviceTable.getSelectionIndex();
-            Object data = mViewer.getElementAt(index);
-            if (data instanceof IDevice) {
-                handleSelection((IDevice)data);
-            } else {
-                handleSelection(null);
-            }
-        }
-    }
-
-    private void handleSelection(IDevice device) {
-        mResponse.setDeviceToUse(device);
-        enableOkButton();
-    }
-
-    /**
-     * Look for a default device to select. This is done by looking for the running
-     * clients on each device and finding one similar to the one being launched.
-     * <p/>
-     * This is done every time the device list changed unless there is a already selection.
-     */
-    private void updateDefaultSelection() {
-        if (mDeviceTable.getSelectionCount() == 0) {
-            AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
-
-            IDevice[] devices = bridge.getDevices();
-
-            for (IDevice device : devices) {
-                Client[] clients = device.getClients();
-
-                for (Client client : clients) {
-
-                    if (mPackageName.equals(client.getClientData().getClientDescription())) {
-                        // found a match! Select it.
-                        mViewer.setSelection(new StructuredSelection(device));
-                        handleSelection(device);
-
-                        // and we're done.
-                        return;
-                    }
-                }
-            }
-        }
-
-        handleDeviceSelection();
-    }
-
-    private final class NonRunningAvdFilter implements IAvdFilter {
-
-        private IDevice[] mDevices;
-
-        public void prepare() {
-            mDevices = AndroidDebugBridge.getBridge().getDevices();
-        }
-
-        public boolean accept(AvdInfo avd) {
-            if (mDevices != null) {
-                for (IDevice d : mDevices) {
-                    if (mProjectTarget.isCompatibleBaseFor(avd.getTarget()) == false ||
-                            avd.getName().equals(d.getAvdName())) {
-                        return false;
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        public void cleanup() {
-            mDevices = null;
-        }
-    }
-
-    /**
-     * Refills the AVD list keeping the current selection.
-     */
-    private void refillAvdList(boolean reloadAvds) {
-        // save the current selection
-        AvdInfo selected = mPreferredAvdSelector.getSelected();
-
-        // disable selection change.
-        mDisableAvdSelectionChange = true;
-
-        // refresh the list
-        mPreferredAvdSelector.refresh(false);
-
-        // attempt to reselect the proper avd if needed
-        if (selected != null) {
-            if (mPreferredAvdSelector.setSelection(selected) == false) {
-                // looks like the selection is lost. this can happen if an emulator
-                // running the AVD that was selected was launched from outside of Eclipse).
-                mResponse.setAvdToLaunch(null);
-                enableOkButton();
-            }
-        }
-
-        // enable the selection change
-        mDisableAvdSelectionChange = false;
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmptyLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmptyLaunchAction.java
deleted file mode 100644
index 096d72a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmptyLaunchAction.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-/**
- * A launch action that does nothing after the application has been installed
- */
-public class EmptyLaunchAction implements IAndroidLaunchAction {
-
-    public boolean doLaunchAction(DelayedLaunchInfo info, IDevice device) {
-        // we're not supposed to do anything, just return;
-        String msg = String.format("%1$s installed on device",
-                info.getPackageFile().getFullPath().toOSString());
-        AdtPlugin.printToConsole(info.getProject(), msg, "Done!");
-        // return false so launch controller will not wait for debugger to attach
-        return false;
-    }
-
-    public String getLaunchDescription() {
-        return "sync";
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java
deleted file mode 100644
index 74d4c4b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration.TargetMode;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.NullSdkLog;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-import com.android.sdkuilib.internal.widgets.AvdSelector;
-import com.android.sdkuilib.internal.widgets.AvdSelector.DisplayMode;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Launch configuration tab to control the parameters of the Emulator
- */
-public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
-
-    private final static String[][] NETWORK_SPEEDS = new String[][] {
-        { "Full", "full" }, //$NON-NLS-2$
-        { "GSM", "gsm" }, //$NON-NLS-2$
-        { "HSCSD", "hscsd" }, //$NON-NLS-2$
-        { "GPRS", "gprs" }, //$NON-NLS-2$
-        { "EDGE", "edge" }, //$NON-NLS-2$
-        { "UMTS", "umts" }, //$NON-NLS-2$
-        { "HSPDA", "hsdpa" }, //$NON-NLS-2$
-    };
-
-    private final static String[][] NETWORK_LATENCIES = new String[][] {
-        { "None", "none" }, //$NON-NLS-2$
-        { "GPRS", "gprs" }, //$NON-NLS-2$
-        { "EDGE", "edge" }, //$NON-NLS-2$
-        { "UMTS", "umts" }, //$NON-NLS-2$
-    };
-
-    private Button mAutoTargetButton;
-    private Button mManualTargetButton;
-
-    private AvdSelector mPreferredAvdSelector;
-
-    private Combo mSpeedCombo;
-
-    private Combo mDelayCombo;
-
-    private Group mEmulatorOptionsGroup;
-
-    private Text mEmulatorCLOptions;
-
-    private Button mWipeDataButton;
-
-    private Button mNoBootAnimButton;
-
-    private Label mPreferredAvdLabel;
-
-    private IAndroidTarget mProjectTarget;
-
-    /**
-     * Returns the emulator ready speed option value.
-     * @param value The index of the combo selection.
-     */
-    public static String getSpeed(int value) {
-        try {
-            return NETWORK_SPEEDS[value][1];
-        } catch (ArrayIndexOutOfBoundsException e) {
-            return NETWORK_SPEEDS[LaunchConfigDelegate.DEFAULT_SPEED][1];
-        }
-    }
-
-    /**
-     * Returns the emulator ready network latency value.
-     * @param value The index of the combo selection.
-     */
-    public static String getDelay(int value) {
-        try {
-            return NETWORK_LATENCIES[value][1];
-        } catch (ArrayIndexOutOfBoundsException e) {
-            return NETWORK_LATENCIES[LaunchConfigDelegate.DEFAULT_DELAY][1];
-        }
-    }
-
-    /**
-     *
-     */
-    public EmulatorConfigTab() {
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    public void createControl(Composite parent) {
-        Font font = parent.getFont();
-
-        // reload the AVDs to make sure we are up to date
-        try {
-            Sdk.getCurrent().getAvdManager().reloadAvds(NullSdkLog.getLogger());
-        } catch (AndroidLocationException e1) {
-            // this happens if the AVD Manager failed to find the folder in which the AVDs are
-            // stored. There isn't much we can do at this point.
-        }
-
-        Composite topComp = new Composite(parent, SWT.NONE);
-        setControl(topComp);
-        GridLayout topLayout = new GridLayout();
-        topLayout.numColumns = 1;
-        topLayout.verticalSpacing = 0;
-        topComp.setLayout(topLayout);
-        topComp.setFont(font);
-
-        GridData gd;
-        GridLayout layout;
-
-        // radio button for the target mode
-        Group targetModeGroup = new Group(topComp, SWT.NONE);
-        targetModeGroup.setText("Deployment Target Selection Mode");
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        targetModeGroup.setLayoutData(gd);
-        layout = new GridLayout();
-        layout.numColumns = 1;
-        targetModeGroup.setLayout(layout);
-        targetModeGroup.setFont(font);
-
-        mManualTargetButton = new Button(targetModeGroup, SWT.RADIO);
-        mManualTargetButton.setText("Manual");
-        // Since there are only 2 radio buttons, we can put a listener on only one (they
-        // are both called on select and unselect event.
-
-        // add the radio button
-        mAutoTargetButton = new Button(targetModeGroup, SWT.RADIO);
-        mAutoTargetButton.setText("Automatic");
-        mAutoTargetButton.setSelection(true);
-        mAutoTargetButton.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateLaunchConfigurationDialog();
-
-                boolean auto = mAutoTargetButton.getSelection();
-                mPreferredAvdSelector.setEnabled(auto);
-                mPreferredAvdLabel.setEnabled(auto);
-            }
-        });
-
-        Composite offsetComp = new Composite(targetModeGroup, SWT.NONE);
-        offsetComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        layout = new GridLayout(1, false);
-        layout.marginRight = layout.marginHeight = 0;
-        layout.marginLeft = 30;
-        offsetComp.setLayout(layout);
-
-        mPreferredAvdLabel = new Label(offsetComp, SWT.NONE);
-        mPreferredAvdLabel.setText("Select a preferred Android Virtual Device for deployment:");
-
-        // create the selector with no manager, we'll reset the manager every time this is
-        // displayed to ensure we have the latest one (dialog is reused but SDK could have
-        // been changed in between.
-        mPreferredAvdSelector = new AvdSelector(offsetComp,
-                Sdk.getCurrent().getSdkLocation(),
-                null /* avd manager */,
-                DisplayMode.SIMPLE_CHECK);
-        mPreferredAvdSelector.setTableHeightHint(100);
-        mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateLaunchConfigurationDialog();
-            }
-        });
-
-        // emulator size
-        mEmulatorOptionsGroup = new Group(topComp, SWT.NONE);
-        mEmulatorOptionsGroup.setText("Emulator launch parameters:");
-        mEmulatorOptionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        layout = new GridLayout();
-        layout.numColumns = 2;
-        mEmulatorOptionsGroup.setLayout(layout);
-        mEmulatorOptionsGroup.setFont(font);
-
-        // network options
-        new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Network Speed:");
-
-        mSpeedCombo = new Combo(mEmulatorOptionsGroup, SWT.READ_ONLY);
-        for (String[] speed : NETWORK_SPEEDS) {
-            mSpeedCombo.add(speed[0]);
-        }
-        mSpeedCombo.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateLaunchConfigurationDialog();
-            }
-        });
-        mSpeedCombo.pack();
-
-        new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Network Latency:");
-
-        mDelayCombo = new Combo(mEmulatorOptionsGroup, SWT.READ_ONLY);
-
-        for (String[] delay : NETWORK_LATENCIES) {
-            mDelayCombo.add(delay[0]);
-        }
-        mDelayCombo.addSelectionListener(new SelectionAdapter() {
-            // called when selection changes
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateLaunchConfigurationDialog();
-            }
-        });
-        mDelayCombo.pack();
-
-        // wipe data option
-        mWipeDataButton = new Button(mEmulatorOptionsGroup, SWT.CHECK);
-        mWipeDataButton.setText("Wipe User Data");
-        mWipeDataButton.setToolTipText("Check this if you want to wipe your user data each time you start the emulator. You will be prompted for confirmation when the emulator starts.");
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        mWipeDataButton.setLayoutData(gd);
-        mWipeDataButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateLaunchConfigurationDialog();
-            }
-        });
-
-        // no boot anim option
-        mNoBootAnimButton = new Button(mEmulatorOptionsGroup, SWT.CHECK);
-        mNoBootAnimButton.setText("Disable Boot Animation");
-        mNoBootAnimButton.setToolTipText("Check this if you want to disable the boot animation. This can help the emulator start faster on slow machines.");
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        mNoBootAnimButton.setLayoutData(gd);
-        mNoBootAnimButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                updateLaunchConfigurationDialog();
-            }
-        });
-
-        // custom command line option for emulator
-        Label l = new Label(mEmulatorOptionsGroup, SWT.NONE);
-        l.setText("Additional Emulator Command Line Options");
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        l.setLayoutData(gd);
-
-        mEmulatorCLOptions = new Text(mEmulatorOptionsGroup, SWT.BORDER);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        mEmulatorCLOptions.setLayoutData(gd);
-        mEmulatorCLOptions.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                updateLaunchConfigurationDialog();
-            }
-        });
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
-     */
-    public String getName() {
-        return "Target";
-    }
-
-    @Override
-    public Image getImage() {
-        return DdmsPlugin.getImageLoader().loadImage("emulator.png", null); //$NON-NLS-1$
-    }
-
-
-    private void updateAvdList(AvdManager avdManager) {
-        if (avdManager == null) {
-            avdManager = Sdk.getCurrent().getAvdManager();
-        }
-
-        mPreferredAvdSelector.setManager(avdManager);
-        mPreferredAvdSelector.setFilter(mProjectTarget);
-        mPreferredAvdSelector.refresh(false);
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
-     */
-    public void initializeFrom(ILaunchConfiguration configuration) {
-        AvdManager avdManager = Sdk.getCurrent().getAvdManager();
-
-        TargetMode mode = LaunchConfigDelegate.DEFAULT_TARGET_MODE; // true == automatic
-        try {
-            mode = TargetMode.getMode(configuration.getAttribute(
-                    LaunchConfigDelegate.ATTR_TARGET_MODE, mode.getValue()));
-        } catch (CoreException e) {
-            // let's not do anything here, we'll use the default value
-        }
-        mAutoTargetButton.setSelection(mode.getValue());
-        mManualTargetButton.setSelection(!mode.getValue());
-
-        // look for the project name to get its target.
-        String stringValue = "";
-        try {
-            stringValue = configuration.getAttribute(
-                    IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, stringValue);
-        } catch (CoreException ce) {
-            // let's not do anything here, we'll use the default value
-        }
-
-        IProject project = null;
-
-        // get the list of existing Android projects from the workspace.
-        IJavaProject[] projects = BaseProjectHelper.getAndroidProjects();
-        if (projects != null) {
-            // look for the project whose name we read from the configuration.
-            for (IJavaProject p : projects) {
-                if (p.getElementName().equals(stringValue)) {
-                    project = p.getProject();
-                    break;
-                }
-            }
-        }
-
-        // update the AVD list
-        if (project != null) {
-            mProjectTarget = Sdk.getCurrent().getTarget(project);
-        }
-
-        updateAvdList(avdManager);
-
-        stringValue = "";
-        try {
-            stringValue = configuration.getAttribute(LaunchConfigDelegate.ATTR_AVD_NAME,
-                    stringValue);
-        } catch (CoreException e) {
-            // let's not do anything here, we'll use the default value
-        }
-
-        if (stringValue != null && stringValue.length() > 0 && avdManager != null) {
-            AvdInfo targetAvd = avdManager.getAvd(stringValue, true /*validAvdOnly*/);
-            mPreferredAvdSelector.setSelection(targetAvd);
-        } else {
-            mPreferredAvdSelector.setSelection(null);
-        }
-
-        boolean value = LaunchConfigDelegate.DEFAULT_WIPE_DATA;
-        try {
-            value = configuration.getAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA, value);
-        } catch (CoreException e) {
-            // let's not do anything here, we'll use the default value
-        }
-        mWipeDataButton.setSelection(value);
-
-        value = LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM;
-        try {
-            value = configuration.getAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM, value);
-        } catch (CoreException e) {
-            // let's not do anything here, we'll use the default value
-        }
-        mNoBootAnimButton.setSelection(value);
-
-        int index = -1;
-
-        index = LaunchConfigDelegate.DEFAULT_SPEED;
-        try {
-            index = configuration.getAttribute(LaunchConfigDelegate.ATTR_SPEED,
-                    index);
-        } catch (CoreException e) {
-            // let's not do anything here, we'll use the default value
-        }
-        if (index == -1) {
-            mSpeedCombo.clearSelection();
-        } else {
-            mSpeedCombo.select(index);
-        }
-
-        index = LaunchConfigDelegate.DEFAULT_DELAY;
-        try {
-            index = configuration.getAttribute(LaunchConfigDelegate.ATTR_DELAY,
-                    index);
-        } catch (CoreException e) {
-            // let's not do anything here, we'll put a proper value in
-            // performApply anyway
-        }
-        if (index == -1) {
-            mDelayCombo.clearSelection();
-        } else {
-            mDelayCombo.select(index);
-        }
-
-        String commandLine = null;
-        try {
-            commandLine = configuration.getAttribute(
-                    LaunchConfigDelegate.ATTR_COMMANDLINE, ""); //$NON-NLS-1$
-        } catch (CoreException e) {
-            // let's not do anything here, we'll use the default value
-        }
-        if (commandLine != null) {
-            mEmulatorCLOptions.setText(commandLine);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
-     */
-    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
-                mAutoTargetButton.getSelection());
-        AvdInfo avd = mPreferredAvdSelector.getSelected();
-        if (avd != null) {
-            configuration.setAttribute(LaunchConfigDelegate.ATTR_AVD_NAME, avd.getName());
-        } else {
-            configuration.setAttribute(LaunchConfigDelegate.ATTR_AVD_NAME, (String)null);
-        }
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
-                mSpeedCombo.getSelectionIndex());
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
-                mDelayCombo.getSelectionIndex());
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_COMMANDLINE,
-                mEmulatorCLOptions.getText());
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA,
-                mWipeDataButton.getSelection());
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM,
-                mNoBootAnimButton.getSelection());
-   }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
-     */
-    public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
-                LaunchConfigDelegate.DEFAULT_TARGET_MODE.getValue());
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
-                LaunchConfigDelegate.DEFAULT_SPEED);
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
-                LaunchConfigDelegate.DEFAULT_DELAY);
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA,
-                LaunchConfigDelegate.DEFAULT_WIPE_DATA);
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM,
-                LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM);
-
-        IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
-        String emuOptions = store.getString(AdtPlugin.PREFS_EMU_OPTIONS);
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_COMMANDLINE, emuOptions);
-   }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/IAndroidLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/IAndroidLaunchAction.java
deleted file mode 100644
index 1383f8c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/IAndroidLaunchAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.adt.internal.launch.DelayedLaunchInfo;
-
-/**
- * An action to perform after performing a launch of an Android application
- */
-public interface IAndroidLaunchAction {
-
-    /** 
-     * Do the launch
-     * 
-     * @param info the {@link DelayedLaunchInfo} that contains launch details
-     * @param device the Android device to perform action on
-     * @returns true if launch was successfully, and controller should wait for debugger to attach
-     *     (if applicable)
-     */
-    boolean doLaunchAction(DelayedLaunchInfo info, IDevice device);
-    
-    /**
-     * Return a description of launch, to be used for logging and error messages
-     */
-    String getLaunchDescription();
-    
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ILaunchController.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ILaunchController.java
deleted file mode 100644
index 6a5c009..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ILaunchController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.IDevice;
-
-/**
- * Interface for managing Android launches
- */
-public interface ILaunchController {
-
-   /**
-    * Launches an application on a device or emulator
-    *
-    * @param launchInfo the {@link DelayedLaunchInfo} that indicates the launch action
-    * @param device the device or emulator to launch the application on
-    */
-    public void launchApp(DelayedLaunchInfo launchInfo, IDevice device);
-    
-    /**
-     * Cancels a launch
-     * 
-     * @param launchInfo the {@link DelayedLaunchInfo} to cancel
-     */
-    void stopLaunch(DelayedLaunchInfo launchInfo);
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegate.java
deleted file mode 100644
index cbfcb24..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegate.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate;
-import org.osgi.framework.Bundle;
-import java.io.IOException;
-import java.net.URL;
-
-/**
- * <p>
- * For Android projects, android.jar gets added to the launch configuration of
- * JUnit tests as a bootstrap entry. This breaks JUnit tests as android.jar
- * contains a skeleton version of JUnit classes and the JVM will stop with an error similar
- * to: <blockquote> Error occurred during initialization of VM
- * java/lang/NoClassDefFoundError: java/lang/ref/FinalReference </blockquote>
- * <p>
- * At compile time, Eclipse does not know that there is no valid junit.jar in
- * the classpath since it can find a correct reference to all the necessary
- * org.junit.* classes in the android.jar so it does not prompt the user to add
- * the JUnit3 or JUnit4 jar.
- * <p>
- * This delegates removes the android.jar from the bootstrap path and if
- * necessary also puts back the junit.jar in the user classpath.
- * <p>
- * This delegate will be present for both Java and Android projects (delegates
- * setting instead of only the current project) but the behavior for Java
- * projects should be neutral since:
- * <ol>
- * <li>Java tests can only compile (and then run) when a valid junit.jar is
- * present
- * <li>There is no android.jar in Java projects
- * </ol>
- */
-public class JUnitLaunchConfigDelegate extends JUnitLaunchConfigurationDelegate {
-
-    private static final String JUNIT_JAR = "junit.jar"; //$NON-NLS-1$
-
-    @Override
-    public String[][] getBootpathExt(ILaunchConfiguration configuration) throws CoreException {
-        String[][] bootpath = super.getBootpathExt(configuration);
-        return fixBootpathExt(bootpath);
-    }
-
-    @Override
-    public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException {
-        String[] classpath = super.getClasspath(configuration);
-        return fixClasspath(classpath, getJavaProjectName(configuration));
-    }
-
-    /**
-     * Removes the android.jar from the bootstrap path if present.
-     * 
-     * @param bootpath Array of Arrays of bootstrap class paths
-     * @return a new modified (if applicable) bootpath
-     */
-    public static String[][] fixBootpathExt(String[][] bootpath) {
-        for (int i = 0; i < bootpath.length; i++) {
-            if (bootpath[i] != null) {
-                // we assume that the android.jar can only be present in the
-                // bootstrap path of android tests
-                if (bootpath[i][0].endsWith(SdkConstants.FN_FRAMEWORK_LIBRARY)) {
-                    bootpath[i] = null;
-                }
-            }
-        }
-        return bootpath;
-    }
-
-    /**
-     * Add the junit.jar to the user classpath; since Eclipse was relying on
-     * android.jar to provide the appropriate org.junit classes, it does not
-     * know it actually needs the junit.jar.
-     * 
-     * @param classpath Array containing classpath 
-     * @param projectName The name of the project (for logging purposes) 
-     * 
-     * @return a new modified (if applicable) classpath
-     */
-    public static String[] fixClasspath(String[] classpath, String projectName) {
-        // search for junit.jar; if any are found return immediately
-        for (int i = 0; i < classpath.length; i++) {
-            if (classpath[i].endsWith(JUNIT_JAR)) { 
-                return classpath;
-            }
-        }
-
-        // This delegate being called without a junit.jar present is only
-        // possible for Android projects. In a non-Android project, the test
-        // would not compile and would be unable to run.
-        try {
-            // junit4 is backward compatible with junit3 and they uses the
-            // same junit.jar from bundle org.junit:
-            // When a project has mixed JUnit3 and JUnit4 tests, if JUnit3 jar
-            // is added first it is then replaced by the JUnit4 jar when user is
-            // prompted to fix the JUnit4 test failure
-            String jarLocation = getJunitJarLocation();
-            // we extend the classpath by one element and append junit.jar
-            String[] newClasspath = new String[classpath.length + 1];
-            System.arraycopy(classpath, 0, newClasspath, 0, classpath.length);
-            newClasspath[newClasspath.length - 1] = jarLocation;
-            classpath = newClasspath;
-        } catch (IOException e) {
-            // This should not happen as we depend on the org.junit
-            // plugin explicitly; the error is logged here so that the user can
-            // trace back the cause when the test fails to run
-            AdtPlugin.log(e, "Could not find a valid junit.jar");
-            AdtPlugin.printErrorToConsole(projectName,
-                    "Could not find a valid junit.jar");
-            // Return the classpath as-is (with no junit.jar) anyway because we
-            // will let the actual launch config fails.
-        }
-
-        return classpath;
-    }
-
-    /**
-     * Returns the path of the junit jar in the highest version bundle.
-     * 
-     * (This is public only so that the test can call it)
-     * 
-     * @return the path as a string
-     * @throws IOException
-     */
-    public static String getJunitJarLocation() throws IOException {
-        Bundle bundle = Platform.getBundle("org.junit"); //$NON-NLS-1$
-        if (bundle == null) {
-            throw new IOException("Cannot find org.junit bundle");
-        }
-        URL jarUrl = bundle.getEntry(AndroidConstants.WS_SEP + JUNIT_JAR);
-        return FileLocator.resolve(jarUrl).getFile();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java
deleted file mode 100644
index 66762e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration.TargetMode;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.debug.core.ILaunch;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
-
-/**
- * Implementation of an eclipse LauncConfigurationDelegate to launch android
- * application in debug.
- */
-public class LaunchConfigDelegate extends LaunchConfigurationDelegate {
-    final static int INVALID_DEBUG_PORT = -1;
-    
-    public final static String ANDROID_LAUNCH_TYPE_ID =
-        "com.android.ide.eclipse.adt.debug.LaunchConfigType"; //$NON-NLS-1$
-
-    /** Target mode parameters: true is automatic, false is manual */
-    public static final String ATTR_TARGET_MODE = AdtPlugin.PLUGIN_ID + ".target"; //$NON-NLS-1$
-    public static final TargetMode DEFAULT_TARGET_MODE = TargetMode.AUTO;
-
-    /**
-     * Launch action:
-     * <ul>
-     * <li>0: launch default activity</li>
-     * <li>1: launch specified activity. See {@link #ATTR_ACTIVITY}</li>
-     * <li>2: Do Nothing</li>
-     * </ul>
-     */
-    public final static String ATTR_LAUNCH_ACTION = AdtPlugin.PLUGIN_ID + ".action"; //$NON-NLS-1$
-    
-    /** Default launch action. This launches the activity that is setup to be found in the HOME
-     * screen.
-     */
-    public final static int ACTION_DEFAULT = 0;
-    /** Launch action starting a specific activity. */
-    public final static int ACTION_ACTIVITY = 1;
-    /** Launch action that does nothing. */
-    public final static int ACTION_DO_NOTHING = 2;
-    /** Default launch action value. */
-    public final static int DEFAULT_LAUNCH_ACTION = ACTION_DEFAULT;
-
-    /**
-     * Activity to be launched if {@link #ATTR_LAUNCH_ACTION} is 1
-     */
-    public static final String ATTR_ACTIVITY = AdtPlugin.PLUGIN_ID + ".activity"; //$NON-NLS-1$
-
-    public static final String ATTR_AVD_NAME = AdtPlugin.PLUGIN_ID + ".avd"; //$NON-NLS-1$
-    
-    public static final String ATTR_SPEED = AdtPlugin.PLUGIN_ID + ".speed"; //$NON-NLS-1$
-
-    /**
-     * Index of the default network speed setting for the emulator.<br>
-     * Get the emulator option with <code>EmulatorConfigTab.getSpeed(index)</code>
-     */
-    public static final int DEFAULT_SPEED = 0;
-
-    public static final String ATTR_DELAY = AdtPlugin.PLUGIN_ID + ".delay"; //$NON-NLS-1$
-
-    /**
-     * Index of the default network latency setting for the emulator.<br>
-     * Get the emulator option with <code>EmulatorConfigTab.getDelay(index)</code>
-     */
-    public static final int DEFAULT_DELAY = 0;
-
-    public static final String ATTR_COMMANDLINE = AdtPlugin.PLUGIN_ID + ".commandline"; //$NON-NLS-1$
-
-    public static final String ATTR_WIPE_DATA = AdtPlugin.PLUGIN_ID + ".wipedata"; //$NON-NLS-1$
-    public static final boolean DEFAULT_WIPE_DATA = false;
-
-    public static final String ATTR_NO_BOOT_ANIM = AdtPlugin.PLUGIN_ID + ".nobootanim"; //$NON-NLS-1$
-    public static final boolean DEFAULT_NO_BOOT_ANIM = false;
-
-    public static final String ATTR_DEBUG_PORT = 
-        AdtPlugin.PLUGIN_ID + ".debugPort"; //$NON-NLS-1$
-
-    public void launch(ILaunchConfiguration configuration, String mode,
-            ILaunch launch, IProgressMonitor monitor) throws CoreException {
-        // We need to check if it's a standard launch or if it's a launch
-        // to debug an application already running.
-        int debugPort = AndroidLaunchController.getPortForConfig(configuration);
-
-        // get the project
-        IProject project = getProject(configuration);
-
-        // first we make sure the launch is of the proper type
-        AndroidLaunch androidLaunch = null;
-        if (launch instanceof AndroidLaunch) {
-            androidLaunch = (AndroidLaunch)launch;
-        } else {
-            // wrong type, not sure how we got there, but we don't do
-            // anything else
-            AdtPlugin.printErrorToConsole(project, "Wrong Launch Type!");
-            return;
-        }
-
-        // if we have a valid debug port, this means we're debugging an app
-        // that's already launched.
-        if (debugPort != INVALID_DEBUG_PORT) {
-            AndroidLaunchController.launchRemoteDebugger(debugPort, androidLaunch, monitor);
-            return;
-        }
-
-        if (project == null) {
-            AdtPlugin.printErrorToConsole("Couldn't get project object!");
-            androidLaunch.stopLaunch();
-            return;
-        }
-
-        // check if the project has errors, and abort in this case.
-        if (ProjectHelper.hasError(project, true)) {
-            AdtPlugin.displayError("Android Launch",
-                    "Your project contains error(s), please fix them before running your application.");
-            return;
-        }
-
-        AdtPlugin.printToConsole(project, "------------------------------"); //$NON-NLS-1$
-        AdtPlugin.printToConsole(project, "Android Launch!");
-
-        // check if the project is using the proper sdk.
-        // if that throws an exception, we simply let it propagate to the caller.
-        if (checkAndroidProject(project) == false) {
-            AdtPlugin.printErrorToConsole(project, "Project is not an Android Project. Aborting!");
-            androidLaunch.stopLaunch();
-            return;
-        }
-
-        // Check adb status and abort if needed.
-        AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
-        if (bridge == null || bridge.isConnected() == false) {
-            try {
-                int connections = -1;
-                int restarts = -1;
-                if (bridge != null) {
-                    connections = bridge.getConnectionAttemptCount();
-                    restarts = bridge.getRestartAttemptCount();
-                }
-
-                // if we get -1, the device monitor is not even setup (anymore?).
-                // We need to ask the user to restart eclipse.
-                // This shouldn't happen, but it's better to let the user know in case it does.
-                if (connections == -1 || restarts == -1) {
-                    AdtPlugin.printErrorToConsole(project, 
-                            "The connection to adb is down, and a severe error has occured.",
-                            "You must restart adb and Eclipse.",
-                            String.format(
-                                    "Please ensure that adb is correctly located at '%1$s' and can be executed.",
-                                    AdtPlugin.getOsAbsoluteAdb()));
-                    return;
-                }
-                
-                if (restarts == 0) {
-                    AdtPlugin.printErrorToConsole(project,
-                            "Connection with adb was interrupted.",
-                            String.format("%1$s attempts have been made to reconnect.", connections),
-                            "You may want to manually restart adb from the Devices view.");
-                } else {
-                    AdtPlugin.printErrorToConsole(project,
-                            "Connection with adb was interrupted, and attempts to reconnect have failed.",
-                            String.format("%1$s attempts have been made to restart adb.", restarts),
-                            "You may want to manually restart adb from the Devices view.");
-                    
-                }
-                return;
-            } finally {
-                androidLaunch.stopLaunch();
-            }
-        }
-        
-        // since adb is working, we let the user know
-        // TODO have a verbose mode for launch with more info (or some of the less useful info we now have).
-        AdtPlugin.printToConsole(project, "adb is running normally.");
-
-        // make a config class
-        AndroidLaunchConfiguration config = new AndroidLaunchConfiguration();
-
-        // fill it with the config coming from the ILaunchConfiguration object
-        config.set(configuration);
-
-        // get the launch controller singleton
-        AndroidLaunchController controller = AndroidLaunchController.getInstance();
-
-        // get the application package
-        IFile applicationPackage = ProjectHelper.getApplicationPackage(project);
-        if (applicationPackage == null) {
-            androidLaunch.stopLaunch();
-            return;
-        }
-
-        // we need some information from the manifest
-        AndroidManifestParser manifestParser = AndroidManifestParser.parse(
-                BaseProjectHelper.getJavaProject(project), null /* errorListener */,
-                true /* gatherData */, false /* markErrors */);
-        
-        if (manifestParser == null) {
-            AdtPlugin.printErrorToConsole(project, "Failed to parse AndroidManifest: aborting!");
-            androidLaunch.stopLaunch();
-            return;
-        }
-
-        doLaunch(configuration, mode, monitor, project, androidLaunch, config, controller,
-                applicationPackage, manifestParser);
-    }
-
-    protected void doLaunch(ILaunchConfiguration configuration, String mode,
-            IProgressMonitor monitor, IProject project, AndroidLaunch androidLaunch,
-            AndroidLaunchConfiguration config, AndroidLaunchController controller,
-            IFile applicationPackage, AndroidManifestParser manifestParser) {
-        
-       String activityName = null;
-        
-        if (config.mLaunchAction == ACTION_ACTIVITY) { 
-            // Get the activity name defined in the config
-            activityName = getActivityName(configuration);
-    
-            // Get the full activity list and make sure the one we got matches.
-            Activity[] activities = manifestParser.getActivities();
-    
-            // first we check that there are, in fact, activities.
-            if (activities.length == 0) {
-                // if the activities list is null, then the manifest is empty
-                // and we can't launch the app. We'll revert to a sync-only launch
-                AdtPlugin.printErrorToConsole(project,
-                        "The Manifest defines no activity!",
-                        "The launch will only sync the application package on the device!");
-                config.mLaunchAction = ACTION_DO_NOTHING;
-            } else if (activityName == null) {
-                // if the activity we got is null, we look for the default one.
-                AdtPlugin.printErrorToConsole(project,
-                        "No activity specified! Getting the launcher activity.");
-                Activity launcherActivity = manifestParser.getLauncherActivity();
-                if (launcherActivity != null) {
-                    activityName = launcherActivity.getName();
-                }
-
-                // if there's no default activity. We revert to a sync-only launch.
-                if (activityName == null) {
-                    revertToNoActionLaunch(project, config);
-                }
-            } else {
-    
-                // check the one we got from the config matches any from the list
-                boolean match = false;
-                for (Activity a : activities) {
-                    if (a != null && a.getName().equals(activityName)) {
-                        match = true;
-                        break;
-                    }
-                }
-    
-                // if we didn't find a match, we revert to the default activity if any.
-                if (match == false) {
-                    AdtPlugin.printErrorToConsole(project,
-                            "The specified activity does not exist! Getting the launcher activity.");
-                    Activity launcherActivity = manifestParser.getLauncherActivity();
-                    if (launcherActivity != null) {
-                        activityName = launcherActivity.getName();
-                    }
-            
-                    // if there's no default activity. We revert to a sync-only launch.
-                    if (activityName == null) {
-                        revertToNoActionLaunch(project, config);
-                    }
-                }
-            }
-        } else if (config.mLaunchAction == ACTION_DEFAULT) {
-            Activity launcherActivity = manifestParser.getLauncherActivity();
-            if (launcherActivity != null) {
-                activityName = launcherActivity.getName();
-            }
-            
-            // if there's no default activity. We revert to a sync-only launch.
-            if (activityName == null) {
-                revertToNoActionLaunch(project, config);
-            }
-        }
-
-        IAndroidLaunchAction launchAction = new EmptyLaunchAction();
-        if (activityName != null) {
-            launchAction = new ActivityLaunchAction(activityName, controller);
-        }
-
-        // everything seems fine, we ask the launch controller to handle
-        // the rest
-        controller.launch(project, mode, applicationPackage,manifestParser.getPackage(),
-                manifestParser.getPackage(), manifestParser.getDebuggable(),
-                manifestParser.getApiLevelRequirement(), launchAction, config, androidLaunch,
-                monitor);
-    }
-    
-    @Override
-    public boolean buildForLaunch(ILaunchConfiguration configuration,
-            String mode, IProgressMonitor monitor) throws CoreException {
-
-        // need to check we have everything
-        IProject project = getProject(configuration);
-
-        if (project != null) {
-            // force an incremental build to be sure the resources will
-            // be updated if they were not saved before the launch was launched.
-            return true;
-        }
-
-        throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                        1 /* code, unused */, "Can't find the project!", null /* exception */));
-    }
-
-    /**
-     * {@inheritDoc}
-     * @throws CoreException
-     */
-    @Override
-    public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
-            throws CoreException {
-        return new AndroidLaunch(configuration, mode, null);
-    }
-
-    /**
-     * Returns the IProject object matching the name found in the configuration
-     * object under the name
-     * <code>IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME</code>
-     * @param configuration
-     * @return The IProject object or null
-     */
-    private IProject getProject(ILaunchConfiguration configuration){
-        // get the project name from the config
-        String projectName;
-        try {
-            projectName = configuration.getAttribute(
-                    IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, "");
-        } catch (CoreException e) {
-            return null;
-        }
-
-        // get the current workspace
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-
-        // and return the project with the name from the config
-        return workspace.getRoot().getProject(projectName);
-    }
-
-    /**
-     * Checks the project is an android project.
-     * @param project The project to check
-     * @return true if the project is an android SDK.
-     * @throws CoreException
-     */
-    private boolean checkAndroidProject(IProject project) throws CoreException {
-        // check if the project is a java and an android project.
-        if (project.hasNature(JavaCore.NATURE_ID) == false) {
-            String msg = String.format("%1$s is not a Java project!", project.getName());
-            AdtPlugin.displayError("Android Launch", msg);
-            return false;
-        }
-
-        if (project.hasNature(AndroidConstants.NATURE) == false) {
-            String msg = String.format("%1$s is not an Android project!", project.getName());
-            AdtPlugin.displayError("Android Launch", msg);
-            return false;
-        }
-
-        return true;
-    }
-
-
-    /**
-     * Returns the name of the activity.
-     */
-    private String getActivityName(ILaunchConfiguration configuration) {
-        String empty = "";
-        String activityName;
-        try {
-            activityName = configuration.getAttribute(ATTR_ACTIVITY, empty);
-        } catch (CoreException e) {
-            return null;
-        }
-
-        return (activityName != empty) ? activityName : null;
-    }
-    
-    private final void revertToNoActionLaunch(IProject project, AndroidLaunchConfiguration config) {
-        AdtPlugin.printErrorToConsole(project,
-                "No Launcher activity found!",
-                "The launch will only sync the application package on the device!");
-        config.mLaunchAction = ACTION_DO_NOTHING;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigTabGroup.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigTabGroup.java
deleted file mode 100644
index e1496eb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigTabGroup.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
-import org.eclipse.debug.ui.CommonTab;
-import org.eclipse.debug.ui.ILaunchConfigurationDialog;
-import org.eclipse.debug.ui.ILaunchConfigurationTab;
-
-/**
- * Tab group object for Android Launch Config type.
- */
-public class LaunchConfigTabGroup extends AbstractLaunchConfigurationTabGroup {
-
-    public LaunchConfigTabGroup() {
-    }
-
-    public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
-        ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
-                new MainLaunchConfigTab(),
-                new EmulatorConfigTab(),
-                new CommonTab()
-            };
-            setTabs(tabs);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchShortcut.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchShortcut.java
deleted file mode 100644
index 1235f9d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchShortcut.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.ui.DebugUITools;
-import org.eclipse.debug.ui.ILaunchShortcut;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.IEditorPart;
-
-/**
- * Launch shortcut to launch debug/run configuration directly.
- */
-public class LaunchShortcut implements ILaunchShortcut {
-
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchShortcut#launch(
-     * org.eclipse.jface.viewers.ISelection, java.lang.String)
-     */
-    public void launch(ISelection selection, String mode) {
-        if (selection instanceof IStructuredSelection) {
-
-            // get the object and the project from it
-            IStructuredSelection structSelect = (IStructuredSelection)selection;
-            Object o = structSelect.getFirstElement();
-
-            // get the first (and normally only) element
-            if (o instanceof IAdaptable) {
-                IResource r = (IResource)((IAdaptable)o).getAdapter(IResource.class);
-
-                // get the project from the resource
-                if (r != null) {
-                    IProject project = r.getProject();
-
-                    if (project != null)  {
-                        // and launch
-                        launch(project, mode);
-                    }
-                }
-            }
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchShortcut#launch(
-     * org.eclipse.ui.IEditorPart, java.lang.String)
-     */
-    public void launch(IEditorPart editor, String mode) {
-        // since we force the shortcut to only work on selection in the
-        // package explorer, this will never be called.
-    }
-
-
-    /**
-     * Launch a config for the specified project.
-     * @param project The project to launch
-     * @param mode The launch mode ("debug", "run" or "profile")
-     */
-    private void launch(IProject project, String mode) {
-        // get an existing or new launch configuration
-        ILaunchConfiguration config = AndroidLaunchController.getLaunchConfig(project);
-
-        if (config != null) {
-            // and launch!
-            DebugUITools.launch(config, mode);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java
deleted file mode 100644
index 2b57f30..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
-import org.eclipse.debug.ui.ILaunchConfigurationTab;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.ArrayList;
-
-/**
- * Class for the main launch configuration tab.
- */
-public class MainLaunchConfigTab extends AbstractLaunchConfigurationTab {
-
-    /**
-     * 
-     */
-    public static final String LAUNCH_TAB_IMAGE = "mainLaunchTab.png"; //$NON-NLS-1$
-
-    protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
-    
-    protected Text mProjText;
-    private Button mProjButton;
-
-    private Combo mActivityCombo;
-    private final ArrayList<Activity> mActivities = new ArrayList<Activity>();
-
-    private WidgetListener mListener = new WidgetListener();
-
-    private Button mDefaultActionButton;
-    private Button mActivityActionButton;
-    private Button mDoNothingActionButton;
-    private int mLaunchAction = LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION;
-    
-    private ProjectChooserHelper mProjectChooserHelper;
-    
-    /**
-     * A listener which handles widget change events for the controls in this
-     * tab.
-     */
-    private class WidgetListener implements ModifyListener, SelectionListener {
-
-        public void modifyText(ModifyEvent e) {
-            IProject project = checkParameters();
-            loadActivities(project);
-            setDirty(true);
-        }
-
-        public void widgetDefaultSelected(SelectionEvent e) {/* do nothing */
-        }
-
-        public void widgetSelected(SelectionEvent e) {
-            Object source = e.getSource();
-            if (source == mProjButton) {
-                handleProjectButtonSelected();
-            } else {
-                checkParameters();
-            }
-        }
-    }
-
-    public MainLaunchConfigTab() {
-    }
-
-    public void createControl(Composite parent) {
-        mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
-
-        Font font = parent.getFont();
-        Composite comp = new Composite(parent, SWT.NONE);
-        setControl(comp);
-        GridLayout topLayout = new GridLayout();
-        topLayout.verticalSpacing = 0;
-        comp.setLayout(topLayout);
-        comp.setFont(font);
-        createProjectEditor(comp);
-        createVerticalSpacer(comp, 1);
-
-        // create the combo for the activity chooser
-        Group group = new Group(comp, SWT.NONE);
-        group.setText("Launch Action:");
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        group.setLayoutData(gd);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-        group.setFont(font);
-
-        mDefaultActionButton = new Button(group, SWT.RADIO);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        mDefaultActionButton.setLayoutData(gd);
-        mDefaultActionButton.setText("Launch Default Activity");
-        mDefaultActionButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // event are received for both selection and deselection, so we only process
-                // the selection event to avoid doing it twice.
-                if (mDefaultActionButton.getSelection() == true) {
-                    mLaunchAction = LaunchConfigDelegate.ACTION_DEFAULT;
-                    mActivityCombo.setEnabled(false);
-                    checkParameters();
-                }
-            }
-        });
-
-        mActivityActionButton = new Button(group, SWT.RADIO);
-        mActivityActionButton.setText("Launch:");
-        mActivityActionButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // event are received for both selection and deselection, so we only process
-                // the selection event to avoid doing it twice.
-                if (mActivityActionButton.getSelection() == true) {
-                    mLaunchAction = LaunchConfigDelegate.ACTION_ACTIVITY;
-                    mActivityCombo.setEnabled(true);
-                    checkParameters();
-                }
-            }
-        });
-
-        mActivityCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        mActivityCombo.setLayoutData(gd);
-        mActivityCombo.clearSelection();
-        mActivityCombo.setEnabled(false);
-        mActivityCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                checkParameters();
-            }
-        });
-        
-        mDoNothingActionButton = new Button(group, SWT.RADIO);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        mDoNothingActionButton.setLayoutData(gd);
-        mDoNothingActionButton.setText("Do Nothing");
-        mDoNothingActionButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // event are received for both selection and deselection, so we only process
-                // the selection event to avoid doing it twice.
-                if (mDoNothingActionButton.getSelection() == true) {
-                    mLaunchAction = LaunchConfigDelegate.ACTION_DO_NOTHING;
-                    mActivityCombo.setEnabled(false);
-                    checkParameters();
-                }
-            }
-        });
-        
-    }
-
-    public String getName() {
-        return "Android";
-    }
-
-    @Override
-    public Image getImage() {
-        return AdtPlugin.getImageLoader().loadImage(LAUNCH_TAB_IMAGE, null);
-    }
-
-
-    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
-        configuration.setAttribute(
-                IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, mProjText.getText());
-        configuration.setAttribute(
-                IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, true);
-
-        // add the launch mode
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION, mLaunchAction);
-        
-        // add the activity
-        int selection = mActivityCombo.getSelectionIndex();
-        if (mActivities != null && selection >=0 && selection < mActivities.size()) {
-            configuration.setAttribute(LaunchConfigDelegate.ATTR_ACTIVITY,
-                    mActivities.get(selection).getName());
-        }
-        
-        // link the project and the launch config.
-        mapResources(configuration);
-    }
-
-    public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
-        configuration.setAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
-                LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION);
-    }
-
-    /**
-     * Creates the widgets for specifying a main type.
-     *
-     * @param parent the parent composite
-     */
-    protected void createProjectEditor(Composite parent) {
-        Font font = parent.getFont();
-        Group group = new Group(parent, SWT.NONE);
-        group.setText("Project:");
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        group.setLayoutData(gd);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-        group.setFont(font);
-        mProjText = new Text(group, SWT.SINGLE | SWT.BORDER);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        mProjText.setLayoutData(gd);
-        mProjText.setFont(font);
-        mProjText.addModifyListener(mListener);
-        mProjButton = createPushButton(group, "Browse...", null);
-        mProjButton.addSelectionListener(mListener);
-    }
-
-    /**
-     * returns the default listener from this class. For all subclasses this
-     * listener will only provide the functi Jaonality of updating the current
-     * tab
-     *
-     * @return a widget listener
-     */
-    protected WidgetListener getDefaultListener() {
-        return mListener;
-    }
-
-    /**
-     * Return the {@link IJavaProject} corresponding to the project name in the project
-     * name text field, or null if the text does not match a project name.
-     * @param javaModel the Java Model object corresponding for the current workspace root.
-     * @return a IJavaProject object or null.
-     */
-    protected IJavaProject getJavaProject(IJavaModel javaModel) {
-        String projectName = mProjText.getText().trim();
-        if (projectName.length() < 1) {
-            return null;
-        }
-        return javaModel.getJavaProject(projectName);
-    }
-
-    /**
-     * Show a dialog that lets the user select a project. This in turn provides
-     * context for the main type, allowing the user to key a main type name, or
-     * constraining the search for main types to the specified project.
-     */
-    protected void handleProjectButtonSelected() {
-        IJavaProject javaProject = mProjectChooserHelper.chooseJavaProject(
-                mProjText.getText().trim());
-        if (javaProject == null) {
-            return;
-        }// end if
-        String projectName = javaProject.getElementName();
-        mProjText.setText(projectName);
-        
-        // get the list of activities and fill the combo
-        IProject project = javaProject.getProject();
-        loadActivities(project);
-    }// end handle selected
-
-    /**
-     * Initializes this tab's controls with values from the given
-     * launch configuration. This method is called when
-     * a configuration is selected to view or edit, after this
-     * tab's control has been created.
-     * 
-     * @param config launch configuration
-     * 
-     * @see ILaunchConfigurationTab
-     */
-    public void initializeFrom(ILaunchConfiguration config) {
-        String projectName = EMPTY_STRING;
-        try {
-            projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
-                    EMPTY_STRING);
-        }// end try
-        catch (CoreException ce) {
-        }
-        mProjText.setText(projectName);
-
-        IProject proj = mProjectChooserHelper.getAndroidProject(projectName);
-        loadActivities(proj);
-        
-        // load the launch action.
-        mLaunchAction = LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION;
-        try {
-            mLaunchAction = config.getAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
-                    mLaunchAction);
-        } catch (CoreException e) {
-            // nothing to be done really. launchAction will keep its default value.
-        }
-        
-        mDefaultActionButton.setSelection(mLaunchAction == LaunchConfigDelegate.ACTION_DEFAULT);
-        mActivityActionButton.setSelection(mLaunchAction == LaunchConfigDelegate.ACTION_ACTIVITY);
-        mDoNothingActionButton.setSelection(
-                mLaunchAction == LaunchConfigDelegate.ACTION_DO_NOTHING);
-
-        // now look for the activity and load it if present, otherwise, revert
-        // to the current one.
-        String activityName = EMPTY_STRING;
-        try {
-            activityName = config.getAttribute(LaunchConfigDelegate.ATTR_ACTIVITY, EMPTY_STRING);
-        }// end try
-        catch (CoreException ce) {
-            // nothing to be done really. activityName will stay empty
-        }
-
-        if (mLaunchAction != LaunchConfigDelegate.ACTION_ACTIVITY) {
-            mActivityCombo.setEnabled(false);
-            mActivityCombo.clearSelection();
-        } else {
-            mActivityCombo.setEnabled(true);
-            if (activityName == null || activityName.equals(EMPTY_STRING)) {
-                mActivityCombo.clearSelection();
-            } else if (mActivities != null && mActivities.size() > 0) {
-                // look for the name of the activity in the combo.
-                boolean found = false;
-                for (int i = 0 ; i < mActivities.size() ; i++) {
-                    if (activityName.equals(mActivities.get(i).getName())) {
-                        found = true;
-                        mActivityCombo.select(i);
-                        break;
-                    }
-                }
-    
-                // if we haven't found a matching activity we clear the combo selection
-                if (found == false) {
-                    mActivityCombo.clearSelection();
-                }
-            }
-        }
-    }
-
-    /**
-     * Associates the launch config and the project. This allows Eclipse to delete the launch
-     * config when the project is deleted.
-     *
-     * @param config the launch config working copy.
-     */
-    protected void mapResources(ILaunchConfigurationWorkingCopy config) {
-        // get the java model
-        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
-        IJavaModel javaModel = JavaCore.create(workspaceRoot);
-
-        // get the IJavaProject described by the text field.
-        IJavaProject javaProject = getJavaProject(javaModel);
-        IResource[] resources = null;
-        if (javaProject != null) {
-            resources = AndroidLaunchController.getResourcesToMap(javaProject.getProject());
-        }
-        config.setMappedResources(resources);
-    }
-
-    /**
-     * Loads the ui with the activities of the specified project, and stores the
-     * activities in <code>mActivities</code>.
-     * <p/>
-     * First activity is selected by default if present.
-     * 
-     * @param project The project to load the activities from.
-     */
-    private void loadActivities(IProject project) {
-        if (project != null) {
-            try {
-                // parse the manifest for the list of activities.
-                AndroidManifestParser manifestParser = AndroidManifestParser.parse(
-                        BaseProjectHelper.getJavaProject(project), null /* errorListener */,
-                        true /* gatherData */, false /* markErrors */);
-                if (manifestParser != null) {
-                    Activity[] activities = manifestParser.getActivities();
-
-                    mActivities.clear();
-                    mActivityCombo.removeAll();
-                    
-                    for (Activity activity : activities) {
-                        if (activity.isExported() && activity.hasAction()) {
-                            mActivities.add(activity);
-                            mActivityCombo.add(activity.getName());
-                        }
-                    }
-                    
-                    if (mActivities.size() > 0) {
-                        if (mLaunchAction == LaunchConfigDelegate.ACTION_ACTIVITY) {
-                            mActivityCombo.setEnabled(true);
-                        }
-                    } else {
-                        mActivityCombo.setEnabled(false);
-                    }
-    
-                    // the selection will be set when we update the ui from the current
-                    // config object.
-                    mActivityCombo.clearSelection();
-    
-                    return;
-                }
-
-            } catch (CoreException e) {
-                // The AndroidManifest parsing failed. The builders must have reported the errors
-                // already so there's nothing to do.
-            }
-        }
-        
-        // if we reach this point, either project is null, or we got an exception during
-        // the parsing. In either case, we empty the activity list.
-        mActivityCombo.removeAll();
-        mActivities.clear();
-    }
-    
-    /**
-     * Checks the parameters for correctness, and update the error message and buttons.
-     * @return the current IProject of this launch config.
-     */
-    private IProject checkParameters() {
-        try {
-            //test the project name first!
-            String text = mProjText.getText();
-            if (text.length() == 0) {
-                setErrorMessage("Project Name is required!");
-            } else if (text.matches("[a-zA-Z0-9_ \\.-]+") == false) {
-                setErrorMessage("Project name contains unsupported characters!");
-            } else {
-                IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null);
-                IProject found = null;
-                for (IJavaProject javaProject : projects) {
-                    if (javaProject.getProject().getName().equals(text)) {
-                        found = javaProject.getProject();
-                        break;
-                    }
-                    
-                }
-                
-                if (found != null) {
-                    setErrorMessage(null);
-                } else {
-                    setErrorMessage(String.format("There is no android project named '%1$s'",
-                            text));
-                }
-                
-                return found;
-            }
-        } finally {
-            updateLaunchConfigurationDialog();
-        }
-        
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java
deleted file mode 100644
index 523db3e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.launch.junit;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.launch.DelayedLaunchInfo;
-import com.android.ide.eclipse.adt.internal.launch.IAndroidLaunchAction;
-import com.android.ide.eclipse.adt.internal.launch.junit.runtime.AndroidJUnitLaunchInfo;
-import com.android.ide.eclipse.adt.internal.launch.junit.runtime.RemoteAdtTestRunner;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.debug.core.ILaunch;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.debug.core.model.IProcess;
-import org.eclipse.debug.core.model.IStreamsProxy;
-import org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate;
-import org.eclipse.jdt.launching.IVMRunner;
-import org.eclipse.jdt.launching.VMRunnerConfiguration;
-
-/**
- * A launch action that executes a instrumentation test run on an Android device.
- */
-class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
-
-    private final AndroidJUnitLaunchInfo mLaunchInfo;
-    
-    /**
-     * Creates a AndroidJUnitLaunchAction.
-     * 
-     * @param launchInfo the {@link AndroidJUnitLaunchInfo} for the JUnit run 
-     */
-    public AndroidJUnitLaunchAction(AndroidJUnitLaunchInfo launchInfo) {
-        mLaunchInfo = launchInfo;
-    }
-    
-    /**
-     * Launch a instrumentation test run on given Android device. 
-     * Reuses JDT JUnit launch delegate so results can be communicated back to JDT JUnit UI.
-     * 
-     * @see IAndroidLaunchAction#doLaunchAction(DelayedLaunchInfo, IDevice)
-     */
-    public boolean doLaunchAction(DelayedLaunchInfo info, IDevice device) {
-        String msg = String.format("Launching instrumentation %s on device %s",
-                mLaunchInfo.getRunner(), device.getSerialNumber());
-        AdtPlugin.printToConsole(info.getProject(), msg);
-        
-        try {
-           mLaunchInfo.setDebugMode(info.isDebugMode());
-           mLaunchInfo.setDevice(info.getDevice());
-           JUnitLaunchDelegate junitDelegate = new JUnitLaunchDelegate(mLaunchInfo);
-           final String mode = info.isDebugMode() ? ILaunchManager.DEBUG_MODE : 
-               ILaunchManager.RUN_MODE; 
-
-           junitDelegate.launch(info.getLaunch().getLaunchConfiguration(), mode, info.getLaunch(),
-                   info.getMonitor());
-
-           // TODO: need to add AMReceiver-type functionality somewhere
-        } catch (CoreException e) {
-            AdtPlugin.printErrorToConsole(info.getProject(), "Failed to launch test");
-        }
-        return true;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getLaunchDescription() {
-        return String.format("%s JUnit launch", mLaunchInfo.getRunner());
-    }
-
-    /**
-     * Extends the JDT JUnit launch delegate to allow for JUnit UI reuse. 
-     */
-    private static class JUnitLaunchDelegate extends JUnitLaunchConfigurationDelegate {
-        
-        private AndroidJUnitLaunchInfo mLaunchInfo;
-
-        public JUnitLaunchDelegate(AndroidJUnitLaunchInfo launchInfo) {
-            mLaunchInfo = launchInfo;
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
-         */
-        @Override
-        public synchronized void launch(ILaunchConfiguration configuration, String mode,
-                ILaunch launch, IProgressMonitor monitor) throws CoreException {
-            // TODO: is progress monitor adjustment needed here?
-            super.launch(configuration, mode, launch, monitor);
-        }
-
-        /**
-         * {@inheritDoc}
-         * @see org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate#verifyMainTypeName(org.eclipse.debug.core.ILaunchConfiguration)
-         */
-        @Override
-        public String verifyMainTypeName(ILaunchConfiguration configuration) {
-            return "com.android.ide.eclipse.adt.junit.internal.runner.RemoteAndroidTestRunner"; //$NON-NLS-1$
-        }
-
-        /**
-         * Overrides parent to return a VM Runner implementation which launches a thread, rather
-         * than a separate VM process
-         */
-        @Override
-        public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) {
-            return new VMTestRunner(mLaunchInfo);
-        }
-
-        /**
-         * {@inheritDoc}
-         * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getLaunch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
-         */
-        @Override
-        public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) {
-            return mLaunchInfo.getLaunch();
-        }     
-    }
-
-    /**
-     * Provides a VM runner implementation which starts a thread implementation of a launch process
-     */
-    private static class VMTestRunner implements IVMRunner {
-        
-        private final AndroidJUnitLaunchInfo mJUnitInfo;
-        
-        VMTestRunner(AndroidJUnitLaunchInfo info) {
-            mJUnitInfo = info;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @throws CoreException
-         */
-        public void run(final VMRunnerConfiguration config, ILaunch launch,
-                IProgressMonitor monitor) throws CoreException {
-            
-            TestRunnerProcess runnerProcess = 
-                new TestRunnerProcess(config, mJUnitInfo);
-            runnerProcess.start();
-            launch.addProcess(runnerProcess);
-        }
-    }
-
-    /**
-     * Launch process that executes the tests.
-     */
-    private static class TestRunnerProcess extends Thread implements IProcess  {
-
-        private final VMRunnerConfiguration mRunConfig;
-        private final AndroidJUnitLaunchInfo mJUnitInfo;
-        private RemoteAdtTestRunner mTestRunner = null;
-        private boolean mIsTerminated = false;
-        
-        TestRunnerProcess(VMRunnerConfiguration runConfig, AndroidJUnitLaunchInfo info) {
-            mRunConfig = runConfig;
-            mJUnitInfo = info;
-        }
-        
-        /* (non-Javadoc)
-         * @see org.eclipse.debug.core.model.IProcess#getAttribute(java.lang.String)
-         */
-        public String getAttribute(String key) {
-            return null;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @see org.eclipse.debug.core.model.IProcess#getExitValue()
-         */
-        public int getExitValue() {
-            return 0;
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.debug.core.model.IProcess#getLabel()
-         */
-        public String getLabel() {
-            return mJUnitInfo.getLaunch().getLaunchMode();
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.debug.core.model.IProcess#getLaunch()
-         */
-        public ILaunch getLaunch() {
-            return mJUnitInfo.getLaunch();
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.debug.core.model.IProcess#getStreamsProxy()
-         */
-        public IStreamsProxy getStreamsProxy() {
-            return null;
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.debug.core.model.IProcess#setAttribute(java.lang.String, 
-         * java.lang.String)
-         */
-        public void setAttribute(String key, String value) {
-            // ignore           
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
-         */
-        @SuppressWarnings("unchecked")
-        public Object getAdapter(Class adapter) {
-            return null;
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
-         */
-        public boolean canTerminate() {
-            return true;
-        }
-
-        /* (non-Javadoc)
-         * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
-         */
-        public boolean isTerminated() {
-            return mIsTerminated;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @see org.eclipse.debug.core.model.ITerminate#terminate()
-         */
-        public void terminate() {
-            if (mTestRunner != null) {
-                mTestRunner.terminate();
-            }    
-            mIsTerminated = true;
-        } 
-
-        /**
-         * Launches a test runner that will communicate results back to JDT JUnit UI
-         */
-        @Override
-        public void run() {
-            mTestRunner = new RemoteAdtTestRunner();
-            mTestRunner.runTests(mRunConfig.getProgramArguments(), mJUnitInfo);
-        }
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java
deleted file mode 100755
index 3872bc8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.launch.AndroidLaunch;
-import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration;
-import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchController;
-import com.android.ide.eclipse.adt.internal.launch.IAndroidLaunchAction;
-import com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate;
-import com.android.ide.eclipse.adt.internal.launch.junit.runtime.AndroidJUnitLaunchInfo;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Instrumentation;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
-import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
-
-/**
- * Run configuration that can execute JUnit tests on an Android platform.
- * <p/>
- * Will deploy apps on target Android platform by reusing functionality from ADT
- * LaunchConfigDelegate, and then run JUnits tests by reusing functionality from JDT
- * JUnitLaunchConfigDelegate.
- */
-@SuppressWarnings("restriction")
-public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
-
-    /** Launch config attribute that stores instrumentation runner. */
-    static final String ATTR_INSTR_NAME = AdtPlugin.PLUGIN_ID + ".instrumentation"; //$NON-NLS-1$
-
-    private static final String EMPTY_STRING = ""; //$NON-NLS-1$
-
-    @Override
-    protected void doLaunch(final ILaunchConfiguration configuration, final String mode,
-            IProgressMonitor monitor, IProject project, final AndroidLaunch androidLaunch,
-            AndroidLaunchConfiguration config, AndroidLaunchController controller,
-            IFile applicationPackage, AndroidManifestParser manifestParser) {
-
-        String runner = getRunner(project, configuration, manifestParser);
-        if (runner == null) {
-            AdtPlugin.displayError("Android Launch",
-                    "An instrumention test runner is not specified!");
-            androidLaunch.stopLaunch();
-            return;
-        }
-        // get the target app's package
-        String targetAppPackage = getTargetPackage(manifestParser, runner); 
-        if (targetAppPackage == null) {
-            AdtPlugin.displayError("Android Launch",
-                    String.format("A target package for instrumention test runner %1$s could not be found!", 
-                    runner));
-            androidLaunch.stopLaunch();
-            return; 
-        }
-        String testAppPackage = manifestParser.getPackage();
-        AndroidJUnitLaunchInfo junitLaunchInfo = new AndroidJUnitLaunchInfo(project, 
-                testAppPackage, runner);
-        junitLaunchInfo.setTestClass(getTestClass(configuration));
-        junitLaunchInfo.setTestPackage(getTestPackage(configuration));
-        junitLaunchInfo.setTestMethod(getTestMethod(configuration));
-        junitLaunchInfo.setLaunch(androidLaunch);
-        IAndroidLaunchAction junitLaunch = new AndroidJUnitLaunchAction(junitLaunchInfo);
-        
-        controller.launch(project, mode, applicationPackage, testAppPackage, targetAppPackage,
-                manifestParser.getDebuggable(), manifestParser.getApiLevelRequirement(),
-                junitLaunch, config, androidLaunch, monitor);
-    }
-
-    /**
-     * Get the target Android application's package for the given instrumentation runner, or 
-     * <code>null</code> if it could not be found.
-     *
-     * @param manifestParser the {@link AndroidManifestParser} for the test project
-     * @param runner the instrumentation runner class name
-     * @return the target package or <code>null</code>
-     */
-    private String getTargetPackage(AndroidManifestParser manifestParser, String runner) {
-        for (Instrumentation instr : manifestParser.getInstrumentations()) {
-            if (instr.getName().equals(runner)) {
-                return instr.getTargetPackage();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the test package stored in the launch configuration, or <code>null</code> if not 
-     * specified.
-     * 
-     * @param configuration the {@link ILaunchConfiguration} to retrieve the test package info from
-     * @return the test package or <code>null</code>.
-     */
-    private String getTestPackage(ILaunchConfiguration configuration) {
-        // try to retrieve a package name from the JUnit container attribute
-        String containerHandle = getStringLaunchAttribute(
-                JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, configuration);
-        if (containerHandle != null && containerHandle.length() > 0) {
-            IJavaElement element = JavaCore.create(containerHandle);
-            // containerHandle could be a IProject, check if its a java package
-            if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
-                return element.getElementName();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the test class stored in the launch configuration.
-     *
-     * @param configuration the {@link ILaunchConfiguration} to retrieve the test class info from
-     * @return the test class. <code>null</code> if not specified.
-     */
-    private String getTestClass(ILaunchConfiguration configuration) {
-        return getStringLaunchAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
-                configuration);
-    }
-    
-    /**
-     * Returns the test method stored in the launch configuration.
-     *
-     * @param configuration the {@link ILaunchConfiguration} to retrieve the test method info from
-     * @return the test method. <code>null</code> if not specified.
-     */
-    private String getTestMethod(ILaunchConfiguration configuration) {
-        return getStringLaunchAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
-                configuration);
-    }
-
-    /**
-     * Gets a instrumentation runner for the launch. 
-     * <p/>
-     * If a runner is stored in the given <code>configuration</code>, will return that.
-     * Otherwise, will try to find the first valid runner for the project.
-     * If a runner can still not be found, will return <code>null</code>.
-     * 
-     * @param project the {@link IProject} for the app 
-     * @param configuration the {@link ILaunchConfiguration} for the launch
-     * @param manifestParser the {@link AndroidManifestParser} for the project
-     * 
-     * @return <code>null</code> if no instrumentation runner can be found, otherwise return
-     *   the fully qualified runner name.
-     */
-    private String getRunner(IProject project, ILaunchConfiguration configuration,
-            AndroidManifestParser manifestParser) {
-        try {
-            String runner = getRunnerFromConfig(configuration);
-            if (runner != null) {
-                return runner;
-            }
-            final InstrumentationRunnerValidator instrFinder = new InstrumentationRunnerValidator(
-                    BaseProjectHelper.getJavaProject(project), manifestParser);
-            runner = instrFinder.getValidInstrumentationTestRunner();
-            if (runner != null) {
-                AdtPlugin.printErrorToConsole(project,
-                        String.format("Warning: No instrumentation runner found for the launch, " +
-                                "using %1$s", runner));
-                return runner;
-            }
-            AdtPlugin.printErrorToConsole(project,
-                    String.format("ERROR: Application does not specify a %1$s instrumentation or does not declare uses-library %2$s",
-                    AndroidConstants.CLASS_INSTRUMENTATION_RUNNER, 
-                    AndroidConstants.LIBRARY_TEST_RUNNER));
-            return null;
-        } catch (CoreException e) {
-            AdtPlugin.log(e, "Error when retrieving instrumentation info"); //$NON-NLS-1$           
-        }
-        return null;
-
-    }
-
-    private String getRunnerFromConfig(ILaunchConfiguration configuration) throws CoreException {
-        return getStringLaunchAttribute(ATTR_INSTR_NAME, configuration);
-    }
-    
-    /**
-     * Helper method to retrieve a string attribute from the launch configuration
-     * 
-     * @param attributeName name of the launch attribute
-     * @param configuration the {@link ILaunchConfiguration} to retrieve the attribute from
-     * @return the attribute's value. <code>null</code> if not found.
-     */
-    private String getStringLaunchAttribute(String attributeName,
-            ILaunchConfiguration configuration) {
-        try {
-            String attrValue = configuration.getAttribute(attributeName, EMPTY_STRING);
-            if (attrValue.length() < 1) {
-                return null;
-            }
-            return attrValue;
-        } catch (CoreException e) {
-            AdtPlugin.log(e, String.format("Error when retrieving launch info %1$s",  //$NON-NLS-1$
-                    attributeName));
-        }
-        return null;
-    }
-
-    /**
-     * Helper method to set JUnit-related attributes expected by JDT JUnit runner
-     * 
-     * @param config the launch configuration to modify
-     */
-    static void setJUnitDefaults(ILaunchConfigurationWorkingCopy config) {
-        // set the test runner to JUnit3 to placate JDT JUnit runner logic
-        config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND, 
-                TestKindRegistry.JUNIT3_TEST_KIND_ID);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java
deleted file mode 100644
index 8f162a6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.launch.junit;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.launch.MainLaunchConfigTab;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.ISourceReference;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.junit.Messages;
-import org.eclipse.jdt.internal.junit.launcher.ITestKind;
-import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
-import org.eclipse.jdt.internal.junit.launcher.JUnitMigrationDelegate;
-import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
-import org.eclipse.jdt.internal.junit.launcher.TestSelectionDialog;
-import org.eclipse.jdt.internal.junit.ui.JUnitMessages;
-import org.eclipse.jdt.internal.junit.util.LayoutUtil;
-import org.eclipse.jdt.internal.junit.util.TestSearchEngine;
-import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
-import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
-import org.eclipse.jdt.ui.JavaElementComparator;
-import org.eclipse.jdt.ui.JavaElementLabelProvider;
-import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
-import org.eclipse.ui.dialogs.SelectionDialog;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * The launch config UI tab for Android JUnit
- * <p/>
- * Based on org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationTab
- */
-@SuppressWarnings("restriction")
-public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurationTab {
-
-    // Project UI widgets
-    private Label mProjLabel;
-    private Text mProjText;
-    private Button mProjButton;
-    
-    // Test class UI widgets
-    private Text mTestText;
-    private Button mSearchButton;
-    private String mOriginalTestMethodName;
-    private Label mTestMethodLabel;
-    private Text mContainerText;
-    private IJavaElement mContainerElement;
-    private final ILabelProvider mJavaElementLabelProvider = new JavaElementLabelProvider();
-
-    private Button mContainerSearchButton;
-    private Button mTestContainerRadioButton;
-    private Button mTestRadioButton;
-    private Label mTestLabel; 
-
-    // Android specific members
-    private Image mTabIcon = null;
-    private Combo mInstrumentationCombo;
-    private static final String EMPTY_STRING = ""; //$NON-NLS-1$
-    private static final String TAG = "AndroidJUnitLaunchConfigurationTab"; //$NON-NLS-1$
-    private String[] mInstrumentations = null;
-    private InstrumentationRunnerValidator mInstrValidator = null;
-    private ProjectChooserHelper mProjectChooserHelper;
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    public void createControl(Composite parent) {
-        mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
-
-        Composite comp = new Composite(parent, SWT.NONE);
-        setControl(comp);
-
-        GridLayout topLayout = new GridLayout();
-        topLayout.numColumns = 3;
-        comp.setLayout(topLayout);      
-        
-        createSingleTestSection(comp);
-        createTestContainerSelectionGroup(comp);
-        
-        createSpacer(comp);
-        
-        createInstrumentationGroup(comp);
-
-        createSpacer(comp);
-        
-        Dialog.applyDialogFont(comp);
-        // TODO: add help link here when available
-        //PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), 
-        //      IJUnitHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_JUNIT_MAIN_TAB);
-        validatePage();
-    }
-
-
-    private void createSpacer(Composite comp) {
-        Label label = new Label(comp, SWT.NONE);
-        GridData gd = new GridData();
-        gd.horizontalSpan = 3;
-        label.setLayoutData(gd);
-    }
-    
-    private void createSingleTestSection(Composite comp) {
-        mTestRadioButton = new Button(comp, SWT.RADIO);
-        mTestRadioButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_oneTest); 
-        GridData gd = new GridData();
-        gd.horizontalSpan = 3;
-        mTestRadioButton.setLayoutData(gd); 
-        mTestRadioButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                if (mTestRadioButton.getSelection()) {
-                    testModeChanged();
-                }    
-            }
-        });
-        
-        mProjLabel = new Label(comp, SWT.NONE);
-        mProjLabel.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_project); 
-        gd = new GridData();
-        gd.horizontalIndent = 25;
-        mProjLabel.setLayoutData(gd);
-        
-        mProjText = new Text(comp, SWT.SINGLE | SWT.BORDER);
-        mProjText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mProjText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent evt) {
-                validatePage();
-                updateLaunchConfigurationDialog();              
-                mSearchButton.setEnabled(mTestRadioButton.getSelection() && 
-                        mProjText.getText().length() > 0);
-            }
-        });
-            
-        mProjButton = new Button(comp, SWT.PUSH);
-        mProjButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_browse); 
-        mProjButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent evt) {
-                handleProjectButtonSelected();
-            }
-        });
-        setButtonGridData(mProjButton);
-        
-        mTestLabel = new Label(comp, SWT.NONE);
-        gd = new GridData();
-        gd.horizontalIndent = 25;
-        mTestLabel.setLayoutData(gd);
-        mTestLabel.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_test); 
-        
-    
-        mTestText = new Text(comp, SWT.SINGLE | SWT.BORDER);
-        mTestText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mTestText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent evt) {
-                validatePage();
-                updateLaunchConfigurationDialog();
-            }
-        });
-        
-        mSearchButton = new Button(comp, SWT.PUSH);
-        mSearchButton.setEnabled(mProjText.getText().length() > 0);
-        mSearchButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_search); 
-        mSearchButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent evt) {
-                handleSearchButtonSelected();
-            }
-        });
-        setButtonGridData(mSearchButton);
-        
-        new Label(comp, SWT.NONE);
-        
-        mTestMethodLabel = new Label(comp, SWT.NONE);
-        mTestMethodLabel.setText("");  //$NON-NLS-1$
-        gd = new GridData();
-        gd.horizontalSpan = 2;
-        mTestMethodLabel.setLayoutData(gd);
-    }
-
-    private void createTestContainerSelectionGroup(Composite comp) {
-        mTestContainerRadioButton = new Button(comp, SWT.RADIO);
-        mTestContainerRadioButton.setText(
-                "Run all tests in the selected project, or package"); 
-        GridData gd = new GridData();
-        gd.horizontalSpan = 3;
-        mTestContainerRadioButton.setLayoutData(gd);
-        mTestContainerRadioButton.addSelectionListener(new SelectionListener() {
-            public void widgetSelected(SelectionEvent e) {
-                if (mTestContainerRadioButton.getSelection()) {
-                    testModeChanged();
-                }
-            }
-            public void widgetDefaultSelected(SelectionEvent e) {
-            }
-        });
-
-        mContainerText = new Text(comp, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalIndent = 25;
-        gd.horizontalSpan = 2;
-        mContainerText.setLayoutData(gd);
-        mContainerText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent evt) {
-                updateLaunchConfigurationDialog();
-            }
-        });
-
-        mContainerSearchButton = new Button(comp, SWT.PUSH);
-        mContainerSearchButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_search); 
-        mContainerSearchButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent evt) {
-                handleContainerSearchButtonSelected();
-            }
-        });
-        setButtonGridData(mContainerSearchButton);  
-    }
-    
-    private void createInstrumentationGroup(Composite comp) {
-        Label loaderLabel = new Label(comp, SWT.NONE);
-        loaderLabel.setText("Instrumentation runner:");
-        GridData gd = new GridData();
-        gd.horizontalIndent = 0;
-        loaderLabel.setLayoutData(gd);
-        
-        mInstrumentationCombo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY);
-        gd = new GridData(GridData.FILL_HORIZONTAL);
-        mInstrumentationCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mInstrumentationCombo.clearSelection();
-        mInstrumentationCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                validatePage();
-                updateLaunchConfigurationDialog();
-            }
-        });
-    }
-
-    private void handleContainerSearchButtonSelected() {
-        IJavaElement javaElement = chooseContainer(mContainerElement);
-        if (javaElement != null) {
-            setContainerElement(javaElement);
-        }    
-    }
-
-    private void setContainerElement(IJavaElement javaElement) {
-        mContainerElement = javaElement;
-        mContainerText.setText(getPresentationName(javaElement));
-        validatePage();
-        updateLaunchConfigurationDialog();
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
-     */
-    public void initializeFrom(ILaunchConfiguration config) {
-        String projectName = updateProjectFromConfig(config);
-        String containerHandle = EMPTY_STRING;
-        try {
-            containerHandle = config.getAttribute(
-                    JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, EMPTY_STRING);
-        } catch (CoreException ce) {
-            // ignore
-        }
-        
-        if (containerHandle.length() > 0) {
-            updateTestContainerFromConfig(config);
-        } else {
-            updateTestTypeFromConfig(config);
-        }    
-
-        IProject proj = mProjectChooserHelper.getAndroidProject(projectName);
-        loadInstrumentations(proj);
-        updateInstrumentationFromConfig(config);
-        
-        validatePage();
-    }
-
-    private void updateInstrumentationFromConfig(ILaunchConfiguration config) {
-        boolean found = false;
-        try {
-            String currentInstrumentation = config.getAttribute(
-                    AndroidJUnitLaunchConfigDelegate.ATTR_INSTR_NAME, EMPTY_STRING);
-            if (mInstrumentations != null) {
-                // look for the name of the instrumentation in the combo.
-                for (int i = 0; i < mInstrumentations.length; i++) {
-                   if (currentInstrumentation.equals(mInstrumentations[i])) {
-                       found = true;
-                       mInstrumentationCombo.select(i);
-                       break;
-                    }
-                }
-            }
-        } catch (CoreException ce) {
-            // ignore
-        }
-        if (!found) {
-            mInstrumentationCombo.clearSelection();
-        }    
-    }
-
-    private String updateProjectFromConfig(ILaunchConfiguration config) {
-        String projectName = EMPTY_STRING;
-        try {
-            projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
-                    EMPTY_STRING);
-        } catch (CoreException ce) {
-            // ignore
-        }
-        mProjText.setText(projectName);
-        return projectName;
-    }
-
-    private void updateTestTypeFromConfig(ILaunchConfiguration config) {
-        String testTypeName = EMPTY_STRING;
-        mOriginalTestMethodName = EMPTY_STRING;
-        try {
-            testTypeName = config.getAttribute(
-                    IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, ""); //$NON-NLS-1$
-            mOriginalTestMethodName = config.getAttribute(
-                    JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME, ""); //$NON-NLS-1$
-        } catch (CoreException ce) {
-            // ignore
-        }
-        mTestRadioButton.setSelection(true);
-        setEnableSingleTestGroup(true);
-        setEnableContainerTestGroup(false);     
-        mTestContainerRadioButton.setSelection(false);
-        mTestText.setText(testTypeName);
-        mContainerText.setText(EMPTY_STRING); 
-        setTestMethodLabel(mOriginalTestMethodName);
-    }
-
-    private void setTestMethodLabel(String testMethodName) {
-        if (!EMPTY_STRING.equals(testMethodName)) {
-            mTestMethodLabel.setText(
-                    JUnitMessages.JUnitLaunchConfigurationTab_label_method + 
-                    mOriginalTestMethodName); 
-        } else {
-            mTestMethodLabel.setText(EMPTY_STRING);
-        }
-    }
-
-    private void updateTestContainerFromConfig(ILaunchConfiguration config) {
-        String containerHandle = EMPTY_STRING;
-        IJavaElement containerElement = null;
-        try {
-            containerHandle = config.getAttribute(
-                    JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, EMPTY_STRING);
-            if (containerHandle.length() > 0) {
-                containerElement = JavaCore.create(containerHandle);
-            }
-        } catch (CoreException ce) {
-            // ignore
-        }
-        if (containerElement != null) {
-            mContainerElement = containerElement;
-        }    
-        mTestContainerRadioButton.setSelection(true);
-        setEnableSingleTestGroup(false);
-        setEnableContainerTestGroup(true);              
-        mTestRadioButton.setSelection(false);
-        if (mContainerElement != null) {
-            mContainerText.setText(getPresentationName(mContainerElement));
-        }    
-        mTestText.setText(EMPTY_STRING);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
-     */
-    public void performApply(ILaunchConfigurationWorkingCopy config) {
-        if (mTestContainerRadioButton.getSelection() && mContainerElement != null) {
-            config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, 
-                    mContainerElement.getJavaProject().getElementName());
-            config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, 
-                    mContainerElement.getHandleIdentifier());
-            config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
-                    EMPTY_STRING);
-             //workaround for Eclipse bug 65399
-            config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
-                    EMPTY_STRING);
-        } else {
-            config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
-                    mProjText.getText());
-            config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
-                    mTestText.getText());
-            config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER,
-                    EMPTY_STRING);
-            config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
-                    mOriginalTestMethodName);
-        }
-        try {
-            mapResources(config);
-        } catch (CoreException e) {
-            // TODO: does the real error need to be extracted out of CoreException
-            AdtPlugin.log(e, "Error occurred saving configuration"); //$NON-NLS-1$
-        }
-        AndroidJUnitLaunchConfigDelegate.setJUnitDefaults(config);
-        
-        config.setAttribute(AndroidJUnitLaunchConfigDelegate.ATTR_INSTR_NAME,
-                getSelectedInstrumentation());
-    }
-
-    private void mapResources(ILaunchConfigurationWorkingCopy config)  throws CoreException {
-        JUnitMigrationDelegate.mapResources(config);
-    }   
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#dispose()
-     */
-    @Override
-    public void dispose() {
-        super.dispose();
-        if (mTabIcon != null) {
-            mTabIcon.dispose();
-            mTabIcon = null;
-        }
-        mJavaElementLabelProvider.dispose();
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getImage()
-     */
-    @Override
-    public Image getImage() {
-        // reuse icon from the Android App Launch config tab
-        if (mTabIcon == null) {
-            mTabIcon = AdtPlugin.getImageLoader().loadImage(MainLaunchConfigTab.LAUNCH_TAB_IMAGE,
-                    null);
-        }
-        return mTabIcon;
-    }
-
-    /**
-     * Show a dialog that lists all main types
-     */
-    private void handleSearchButtonSelected() {
-        Shell shell = getShell();
-
-        IJavaProject javaProject = getJavaProject();
-
-        IType[] types = new IType[0];
-        boolean[] radioSetting = new boolean[2];
-        try {
-            // fix for Eclipse bug 66922 Wrong radio behaviour when switching
-            // remember the selected radio button
-            radioSetting[0] = mTestRadioButton.getSelection();
-            radioSetting[1] = mTestContainerRadioButton.getSelection();
-            
-            types = TestSearchEngine.findTests(getLaunchConfigurationDialog(), javaProject,
-                    getTestKind()); 
-        } catch (InterruptedException e) {
-            setErrorMessage(e.getMessage());
-            return;
-        } catch (InvocationTargetException e) {
-            AdtPlugin.log(e.getTargetException(), "Error finding test types"); //$NON-NLS-1$
-            return;
-        } finally {
-            mTestRadioButton.setSelection(radioSetting[0]);
-            mTestContainerRadioButton.setSelection(radioSetting[1]);
-        }
-
-        SelectionDialog dialog = new TestSelectionDialog(shell, types);
-        dialog.setTitle(JUnitMessages.JUnitLaunchConfigurationTab_testdialog_title); 
-        dialog.setMessage(JUnitMessages.JUnitLaunchConfigurationTab_testdialog_message); 
-        if (dialog.open() == Window.CANCEL) {
-            return;
-        }
-
-        Object[] results = dialog.getResult();
-        if ((results == null) || (results.length < 1)) {
-            return;
-        }       
-        IType type = (IType) results[0];
-
-        if (type != null) {
-            mTestText.setText(type.getFullyQualifiedName('.'));
-            javaProject = type.getJavaProject();
-            mProjText.setText(javaProject.getElementName());
-        }
-    }
-
-    private ITestKind getTestKind() {
-        // harddcode this to JUnit 3
-        return TestKindRegistry.getDefault().getKind(TestKindRegistry.JUNIT3_TEST_KIND_ID);
-    }
-
-    /**
-     * Show a dialog that lets the user select a Android project.  This in turn provides
-     * context for the main type, allowing the user to key a main type name, or
-     * constraining the search for main types to the specified project.
-     */
-    private void handleProjectButtonSelected() {
-        IJavaProject project = mProjectChooserHelper.chooseJavaProject(getProjectName());
-        if (project == null) {
-            return;
-        }
-
-        String projectName = project.getElementName();
-        mProjText.setText(projectName);
-        loadInstrumentations(project.getProject());   
-    }
-
-    /**
-     * Return the IJavaProject corresponding to the project name in the project name
-     * text field, or null if the text does not match a Android project name.
-     */
-    private IJavaProject getJavaProject() {
-        String projectName = getProjectName();
-        return getJavaModel().getJavaProject(projectName);      
-    }
-
-    /**
-     * Returns the name of the currently specified project. Null if no project is selected.
-     */
-    private String getProjectName() {
-        String projectName = mProjText.getText().trim();
-        if (projectName.length() < 1) {
-            return null;
-        }
-        return projectName;
-    }
-
-    /**
-     * Convenience method to get the workspace root.
-     */
-    private IWorkspaceRoot getWorkspaceRoot() {
-        return ResourcesPlugin.getWorkspace().getRoot();
-    }
-
-    /**
-     * Convenience method to get access to the java model.
-     */
-    private IJavaModel getJavaModel() {
-        return JavaCore.create(getWorkspaceRoot());
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
-     */
-    @Override
-    public boolean isValid(ILaunchConfiguration config) {
-        validatePage();
-        return getErrorMessage() == null;
-    }
-
-    private void testModeChanged() {
-        boolean isSingleTestMode = mTestRadioButton.getSelection();
-        setEnableSingleTestGroup(isSingleTestMode);
-        setEnableContainerTestGroup(!isSingleTestMode);
-        if (!isSingleTestMode && mContainerText.getText().length() == 0) {
-            String projText = mProjText.getText();
-            if (Path.EMPTY.isValidSegment(projText)) {
-                IJavaProject javaProject = getJavaModel().getJavaProject(projText);
-                if (javaProject != null && javaProject.exists()) {
-                    setContainerElement(javaProject);
-                }    
-            }
-        }
-        validatePage();
-        updateLaunchConfigurationDialog();
-    }
-
-    private void validatePage() {       
-        setErrorMessage(null);
-        setMessage(null);
-
-        if (mTestContainerRadioButton.getSelection()) {
-            if (mContainerElement == null) {
-                setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_noContainer);
-                return;
-            }
-            validateJavaProject(mContainerElement.getJavaProject());
-            return;
-        }
-
-        String projectName = mProjText.getText().trim();
-        if (projectName.length() == 0) {
-            setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_projectnotdefined);
-            return;
-        }
-
-        IStatus status = ResourcesPlugin.getWorkspace().validatePath(IPath.SEPARATOR + projectName,
-                IResource.PROJECT);
-        if (!status.isOK() || !Path.ROOT.isValidSegment(projectName)) {
-            setErrorMessage(Messages.format(
-                    JUnitMessages.JUnitLaunchConfigurationTab_error_invalidProjectName, 
-                    projectName));
-            return;
-        }
-
-        IProject project = getWorkspaceRoot().getProject(projectName);
-        if (!project.exists()) {
-            setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_projectnotexists);
-            return;
-        }
-        IJavaProject javaProject = JavaCore.create(project);
-        validateJavaProject(javaProject);
-
-        try {
-            if (!project.hasNature(AndroidConstants.NATURE)) {
-                setErrorMessage("Specified project is not an Android project");
-                return;
-            }
-            String className = mTestText.getText().trim();
-            if (className.length() == 0) {
-                setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_testnotdefined);
-                return;
-            }
-            if (javaProject.findType(className) == null) {
-                setErrorMessage(Messages.format(
-                        JUnitMessages.JUnitLaunchConfigurationTab_error_test_class_not_found,
-                        new String[] { className, projectName }));
-                return;
-            }          
-        } catch (CoreException e) {
-            AdtPlugin.log(e, "validatePage failed"); //$NON-NLS-1$
-        }
-
-        validateInstrumentation();
-    }
-
-    private void validateJavaProject(IJavaProject javaProject) {
-        if (!TestSearchEngine.hasTestCaseType(javaProject)) {
-            setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_testcasenotonpath); 
-            return;             
-        }
-    }
-
-    private void validateInstrumentation() {
-        String instrumentation = getSelectedInstrumentation();
-        if (instrumentation == null) {
-            setErrorMessage("Instrumentation runner not specified");
-            return;
-        }
-        String result = mInstrValidator.validateInstrumentationRunner(instrumentation);
-        if (result != InstrumentationRunnerValidator.INSTRUMENTATION_OK) {
-            setErrorMessage(result);
-            return;
-        }
-    }
-
-    private String getSelectedInstrumentation() {
-        int selectionIndex = mInstrumentationCombo.getSelectionIndex();
-        if (mInstrumentations != null && selectionIndex >= 0 && 
-                selectionIndex < mInstrumentations.length) {
-            return mInstrumentations[selectionIndex];
-        }
-        return null;
-    }
-
-    private void setEnableContainerTestGroup(boolean enabled) {
-        mContainerSearchButton.setEnabled(enabled);
-        mContainerText.setEnabled(enabled);
-    }
-
-    private void setEnableSingleTestGroup(boolean enabled) {
-        mProjLabel.setEnabled(enabled);
-        mProjText.setEnabled(enabled);
-        mProjButton.setEnabled(enabled);
-        mTestLabel.setEnabled(enabled);
-        mTestText.setEnabled(enabled);
-        mSearchButton.setEnabled(enabled && mProjText.getText().length() > 0);
-        mTestMethodLabel.setEnabled(enabled);
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
-     */
-    public void setDefaults(ILaunchConfigurationWorkingCopy config) {
-        IJavaElement javaElement = getContext();
-        if (javaElement != null) {
-            initializeJavaProject(javaElement, config);
-        } else {
-            // We set empty attributes for project & main type so that when one config is
-            // compared to another, the existence of empty attributes doesn't cause an
-            // incorrect result (the performApply() method can result in empty values
-            // for these attributes being set on a config if there is nothing in the
-            // corresponding text boxes)
-            config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, EMPTY_STRING);
-            config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER,
-                    EMPTY_STRING);
-        }
-        initializeTestAttributes(javaElement, config);
-    }
-
-    private void initializeTestAttributes(IJavaElement javaElement,
-            ILaunchConfigurationWorkingCopy config) {
-        if (javaElement != null && javaElement.getElementType() < IJavaElement.COMPILATION_UNIT) { 
-            initializeTestContainer(javaElement, config);
-        } else {
-            initializeTestType(javaElement, config);
-        }    
-    }
-
-    private void initializeTestContainer(IJavaElement javaElement,
-            ILaunchConfigurationWorkingCopy config) {
-        config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER,
-                javaElement.getHandleIdentifier());
-        initializeName(config, javaElement.getElementName());
-    }
-
-    private void initializeName(ILaunchConfigurationWorkingCopy config, String name) {
-        if (name == null) {
-            name = EMPTY_STRING;
-        }
-        if (name.length() > 0) {
-            int index = name.lastIndexOf('.');
-            if (index > 0) {
-                name = name.substring(index + 1);
-            }
-            name = getLaunchConfigurationDialog().generateName(name);
-            config.rename(name);
-        }
-    }
-
-    /**
-     * Sets the main type & name attributes on the working copy based on the IJavaElement
-     */
-    private void initializeTestType(IJavaElement javaElement,
-            ILaunchConfigurationWorkingCopy config) {
-        String name = EMPTY_STRING;
-        String testKindId = null;
-        try {
-            // only do a search for compilation units or class files or source references
-            if (javaElement instanceof ISourceReference) {
-                ITestKind testKind = TestKindRegistry.getContainerTestKind(javaElement);
-                testKindId = testKind.getId();
-
-                IType[] types = TestSearchEngine.findTests(getLaunchConfigurationDialog(),
-                        javaElement, testKind); 
-                if ((types == null) || (types.length < 1)) {
-                    return;
-                }
-                // Simply grab the first main type found in the searched element
-                name = types[0].getFullyQualifiedName('.');
-                
-            }   
-        } catch (InterruptedException ie) {
-            // ignore
-        } catch (InvocationTargetException ite) {
-            // ignore
-        }
-        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, name);
-        if (testKindId != null) {
-            config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND,
-                    testKindId);
-        }    
-        initializeName(config, name);
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
-     */
-    public String getName() {
-        return JUnitMessages.JUnitLaunchConfigurationTab_tab_label; 
-    }
-
-    @SuppressWarnings("unchecked")
-    private IJavaElement chooseContainer(IJavaElement initElement) {
-        Class[] acceptedClasses = new Class[] { IJavaProject.class,
-                IPackageFragment.class };
-        TypedElementSelectionValidator validator = new TypedElementSelectionValidator(
-                acceptedClasses, false) {
-            @Override
-            public boolean isSelectedValid(Object element) {
-                return true;
-            }
-        };
-
-        acceptedClasses = new Class[] { IJavaModel.class, IPackageFragmentRoot.class,
-                IJavaProject.class, IPackageFragment.class };
-        ViewerFilter filter = new TypedViewerFilter(acceptedClasses) {
-            @Override
-            public boolean select(Viewer viewer, Object parent, Object element) {
-                if (element instanceof IPackageFragmentRoot && 
-                        ((IPackageFragmentRoot) element).isArchive()) {
-                    return false;
-                }
-                try {
-                    if (element instanceof IPackageFragment &&
-                            !((IPackageFragment) element).hasChildren()) {
-                        return false;
-                    }
-                } catch (JavaModelException e) {
-                    return false;
-                }
-                return super.select(viewer, parent, element);
-            }
-        };      
-
-        AndroidJavaElementContentProvider provider = new AndroidJavaElementContentProvider();
-        ILabelProvider labelProvider = new JavaElementLabelProvider(
-                JavaElementLabelProvider.SHOW_DEFAULT); 
-        ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), 
-                labelProvider, provider);
-        dialog.setValidator(validator);
-        dialog.setComparator(new JavaElementComparator());
-        dialog.setTitle(JUnitMessages.JUnitLaunchConfigurationTab_folderdialog_title);  
-        dialog.setMessage(JUnitMessages.JUnitLaunchConfigurationTab_folderdialog_message);  
-        dialog.addFilter(filter);
-        dialog.setInput(JavaCore.create(getWorkspaceRoot()));
-        dialog.setInitialSelection(initElement);
-        dialog.setAllowMultiple(false);
-
-        if (dialog.open() == Window.OK) {
-            Object element = dialog.getFirstResult();
-            return (IJavaElement) element;
-        }
-        return null;
-    }
-
-    private String getPresentationName(IJavaElement element) {
-        return mJavaElementLabelProvider.getText(element);
-    }
-
-    /**
-     * Returns the current Java element context from which to initialize
-     * default settings, or <code>null</code> if none.
-     * 
-     * @return Java element context.
-     */
-    private IJavaElement getContext() {
-        IWorkbenchWindow activeWorkbenchWindow =
-            PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-        if (activeWorkbenchWindow == null) {
-            return null;
-        }
-        IWorkbenchPage page = activeWorkbenchWindow.getActivePage();
-        if (page != null) {
-            ISelection selection = page.getSelection();
-            if (selection instanceof IStructuredSelection) {
-                IStructuredSelection ss = (IStructuredSelection) selection;
-                if (!ss.isEmpty()) {
-                    Object obj = ss.getFirstElement();
-                    if (obj instanceof IJavaElement) {
-                        return (IJavaElement) obj;
-                    }
-                    if (obj instanceof IResource) {
-                        IJavaElement je = JavaCore.create((IResource) obj);
-                        if (je == null) {
-                            IProject pro = ((IResource) obj).getProject();
-                            je = JavaCore.create(pro);
-                        }
-                        if (je != null) {
-                            return je;
-                        }
-                    }
-                }
-            }
-            IEditorPart part = page.getActiveEditor();
-            if (part != null) {
-                IEditorInput input = part.getEditorInput();
-                return (IJavaElement) input.getAdapter(IJavaElement.class);
-            }
-        }
-        return null;
-    }
-
-    private void initializeJavaProject(IJavaElement javaElement,
-            ILaunchConfigurationWorkingCopy config) {
-        IJavaProject javaProject = javaElement.getJavaProject();
-        String name = null;
-        if (javaProject != null && javaProject.exists()) {
-            name = javaProject.getElementName();
-        }
-        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, name);
-    }
-
-    private void setButtonGridData(Button button) {
-        GridData gridData = new GridData();
-        button.setLayoutData(gridData);
-        LayoutUtil.setButtonDimensionHint(button);
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getId()
-     */
-    @Override
-    public String getId() {
-        return "com.android.ide.eclipse.adt.launch.AndroidJUnitLaunchConfigurationTab"; //$NON-NLS-1$
-    }
-
-    /**
-     * Loads the UI with the instrumentations of the specified project, and stores the
-     * instrumentations in <code>mInstrumentations</code>.
-     * 
-     * @param project the {@link IProject} to load the instrumentations from.
-     */
-    private void loadInstrumentations(IProject project) {
-        try {
-        mInstrValidator = new InstrumentationRunnerValidator(project);
-        mInstrumentations = (mInstrValidator == null ? null : 
-            mInstrValidator.getInstrumentationNames());
-        if (mInstrumentations != null) {
-            mInstrumentationCombo.removeAll();
-            for (String instrumentation : mInstrumentations) {
-                mInstrumentationCombo.add(instrumentation);
-            }
-            // the selection will be set when we update the ui from the current
-            // config object.
-            return;
-        }
-        } catch (CoreException e) {
-            AdtPlugin.logAndPrintError(e, TAG, "ERROR: Failed to get instrumentations for %1$s",
-                    project.getName());
-        }
-        // if we reach this point, either project is null, or we got an exception during
-        // the parsing. In either case, we empty the instrumentation list.
-        mInstrValidator = null;
-        mInstrumentations = null;
-        mInstrumentationCombo.removeAll();
-    }
-
-    /**
-     * Overrides the {@link StandardJavaElementContentProvider} to only display Android projects
-     */
-    private static class AndroidJavaElementContentProvider
-            extends StandardJavaElementContentProvider {
-
-        /**
-         * Override parent to return only Android projects if at the root. Otherwise, use parent 
-         * functionality.
-         */
-        @Override
-        public Object[] getChildren(Object element) {
-            if (element instanceof IJavaModel) {
-                return BaseProjectHelper.getAndroidProjects((IJavaModel) element);
-            }
-            return super.getChildren(element);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchShortcut.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchShortcut.java
deleted file mode 100755
index b94ced8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchShortcut.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.junit.launcher.JUnitLaunchShortcut;
-
-/**
- * Launch shortcut to launch debug/run Android JUnit configuration directly.
- */
-public class AndroidJUnitLaunchShortcut extends JUnitLaunchShortcut {
-
-    @Override
-    protected String getLaunchConfigurationTypeId() {
-        return "com.android.ide.eclipse.adt.junit.launchConfigurationType"; //$NON-NLS-1$
-    }
-
-    /**
-     * Creates a default Android JUnit launch configuration. Sets the instrumentation runner to the
-     * first instrumentation found in the AndroidManifest.
-     */
-    @Override
-    protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(IJavaElement element)
-            throws CoreException {
-        ILaunchConfigurationWorkingCopy config = super.createLaunchConfiguration(element);
-        // just get first valid instrumentation runner
-        String instrumentation = new InstrumentationRunnerValidator(element.getJavaProject()).
-                getValidInstrumentationTestRunner();
-        if (instrumentation != null) {
-            config.setAttribute(AndroidJUnitLaunchConfigDelegate.ATTR_INSTR_NAME, 
-                    instrumentation);
-        }
-        // if a valid runner is not found, rely on launch delegate to log error.
-        // This method is called without explicit user action to launch Android JUnit, so avoid
-        // logging an error here.
-
-        AndroidJUnitLaunchConfigDelegate.setJUnitDefaults(config);
-        return config;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitPropertyTester.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitPropertyTester.java
deleted file mode 100644
index b45cc41..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitPropertyTester.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.launch.junit;
-
-import org.eclipse.core.expressions.PropertyTester;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.jdt.core.IClassFile;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.junit.util.TestSearchEngine;
-
-/**
- * A {@link PropertyTester} that checks if selected elements can be run as Android
- * JUnit tests.
- * <p/>
- * Based on org.eclipse.jdt.internal.junit.JUnitPropertyTester. The only substantial difference in
- * this implementation is source folders cannot be run as Android JUnit.
- */
-@SuppressWarnings("restriction")
-public class AndroidJUnitPropertyTester extends PropertyTester {
-    private static final String PROPERTY_IS_TEST = "isTest";  //$NON-NLS-1$
-    
-    private static final String PROPERTY_CAN_LAUNCH_AS_JUNIT_TEST = "canLaunchAsJUnit"; //$NON-NLS-1$
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jdt.internal.corext.refactoring.participants.properties.IPropertyEvaluator#test(java.lang.Object, java.lang.String, java.lang.String)
-     */
-    public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
-        if (!(receiver instanceof IAdaptable)) {
-            final String elementName = (receiver == null ? "null" : //$NON-NLS-1$
-                receiver.getClass().getName());
-            throw new IllegalArgumentException(
-                    String.format("Element must be of type IAdaptable, is %s", //$NON-NLS-1$
-                            elementName));
-        }
-
-        IJavaElement element;
-        if (receiver instanceof IJavaElement) {
-            element = (IJavaElement) receiver;
-        } else if (receiver instanceof IResource) {
-            element = JavaCore.create((IResource) receiver);
-            if (element == null) {
-                return false;
-            }
-        } else { // is IAdaptable
-            element= (IJavaElement) ((IAdaptable) receiver).getAdapter(IJavaElement.class);
-            if (element == null) {
-                IResource resource = (IResource) ((IAdaptable) receiver).getAdapter(
-                        IResource.class);
-                element = JavaCore.create(resource);
-                if (element == null) {
-                    return false;
-                }
-            }
-        }
-        if (PROPERTY_IS_TEST.equals(property)) { 
-            return isJUnitTest(element);
-        } else if (PROPERTY_CAN_LAUNCH_AS_JUNIT_TEST.equals(property)) {
-            return canLaunchAsJUnitTest(element);
-        }
-        throw new IllegalArgumentException(
-                String.format("Unknown test property '%s'", property)); //$NON-NLS-1$
-    }
-    
-    private boolean canLaunchAsJUnitTest(IJavaElement element) {
-        try {
-            switch (element.getElementType()) {
-                case IJavaElement.JAVA_PROJECT:
-                    return true; // can run, let JDT detect if there are tests
-                case IJavaElement.PACKAGE_FRAGMENT_ROOT:
-                    return false; // not supported by Android test runner
-                case IJavaElement.PACKAGE_FRAGMENT:
-                    return ((IPackageFragment) element).hasChildren(); 
-                case IJavaElement.COMPILATION_UNIT:
-                case IJavaElement.CLASS_FILE:
-                case IJavaElement.TYPE:
-                case IJavaElement.METHOD:
-                    return isJUnitTest(element);
-                default:
-                    return false;
-            }
-        } catch (JavaModelException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Return whether the target resource is a JUnit test.
-     */
-    private boolean isJUnitTest(IJavaElement element) {
-        try {
-            IType testType = null;
-            if (element instanceof ICompilationUnit) {
-                testType = (((ICompilationUnit) element)).findPrimaryType();
-            } else if (element instanceof IClassFile) {
-                testType = (((IClassFile) element)).getType();
-            } else if (element instanceof IType) {
-                testType = (IType) element;
-            } else if (element instanceof IMember) {
-                testType = ((IMember) element).getDeclaringType();
-            }
-            if (testType != null && testType.exists()) {
-                return TestSearchEngine.isTestOrTestSuite(testType);
-            }
-        } catch (CoreException e) {
-            // ignore, return false
-        }
-        return false;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitTabGroup.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitTabGroup.java
deleted file mode 100644
index 0555dea..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitTabGroup.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit;
-
-import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
-import org.eclipse.debug.ui.CommonTab;
-import org.eclipse.debug.ui.ILaunchConfigurationDialog;
-import org.eclipse.debug.ui.ILaunchConfigurationTab;
-
-import com.android.ide.eclipse.adt.internal.launch.EmulatorConfigTab;
-
-/**
- * Tab group object for Android JUnit launch configuration type.
- */
-public class AndroidJUnitTabGroup extends AbstractLaunchConfigurationTabGroup {
-
-    /**
-     * Creates the UI tabs for the Android JUnit configuration
-     */
-    public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
-        ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
-                new AndroidJUnitLaunchConfigurationTab(),
-                new EmulatorConfigTab(),
-                new CommonTab()
-        };
-        setTabs(tabs);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java
deleted file mode 100644
index 856b20b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.launch.junit;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Instrumentation;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IJavaProject;
-
-/**
- * Provides validation for Android instrumentation test runner 
- */
-class InstrumentationRunnerValidator {
-    private final IJavaProject mJavaProject;
-    private String[] mInstrumentationNames = null;
-    private boolean mHasRunnerLibrary = false;
-    
-    static final String INSTRUMENTATION_OK = null;
-
-    /**
-     * Initializes the InstrumentationRunnerValidator.
-     * 
-     * @param javaProject the {@link IJavaProject} for the Android project to validate
-     */
-    InstrumentationRunnerValidator(IJavaProject javaProject) {
-        mJavaProject = javaProject;
-        try {
-            AndroidManifestParser manifestParser = AndroidManifestParser.parse(javaProject, 
-                    null /* errorListener */, true /* gatherData */, false /* markErrors */);
-            init(manifestParser);
-        } catch (CoreException e) {
-            AdtPlugin.printErrorToConsole(javaProject.getProject(), "ERROR: Failed to parse %1$s",
-                    AndroidConstants.FN_ANDROID_MANIFEST);
-        }
-    }
-
-    /**
-     * Initializes the InstrumentationRunnerValidator.
-     * 
-     * @param project the {@link IProject} for the Android project to validate
-     * @throws CoreException if a fatal error occurred in initialization
-     */
-    InstrumentationRunnerValidator(IProject project) throws CoreException {
-        this(BaseProjectHelper.getJavaProject(project));
-    }
-
-    /**
-     * Initializes the InstrumentationRunnerValidator with an existing {@link AndroidManifestParser}
-     * 
-     * @param javaProject the {@link IJavaProject} for the Android project to validate
-     * @param manifestParser the {@link AndroidManifestParser} for the Android project
-     */
-    InstrumentationRunnerValidator(IJavaProject javaProject, AndroidManifestParser manifestParser) {
-        mJavaProject = javaProject;
-        init(manifestParser);
-    }
-    
-    private void init(AndroidManifestParser manifestParser) {
-        Instrumentation[] instrumentations = manifestParser.getInstrumentations();
-        mInstrumentationNames = new String[instrumentations.length];
-        for (int i = 0; i < instrumentations.length; i++) {
-            mInstrumentationNames[i] = instrumentations[i].getName();
-        }
-        mHasRunnerLibrary = hasTestRunnerLibrary(manifestParser);
-    }
-    
-    /**
-     * Helper method to determine if given manifest has a <code>AndroidConstants.LIBRARY_TEST_RUNNER
-     * </code> library reference
-     *
-     * @param manifestParser the {@link AndroidManifestParser} to search
-     * @return true if test runner library found, false otherwise
-     */
-    private boolean hasTestRunnerLibrary(AndroidManifestParser manifestParser) {
-       for (String lib : manifestParser.getUsesLibraries()) {
-           if (lib.equals(AndroidConstants.LIBRARY_TEST_RUNNER)) {
-               return true;
-           }
-       }
-       return false;
-    }
-
-    /**
-     * Return the set of instrumentation names for the Android project.
-     * 
-     * @return <code>null</code if error occurred parsing instrumentations, otherwise returns array
-     * of instrumentation class names
-     */
-    String[] getInstrumentationNames() {
-        return mInstrumentationNames;
-    }
-
-    /**
-     * Helper method to get the first instrumentation that can be used as a test runner.
-     * 
-     * @return fully qualified instrumentation class name. <code>null</code> if no valid
-     * instrumentation can be found.
-     */
-    String getValidInstrumentationTestRunner() {
-        for (String instrumentation : getInstrumentationNames()) {
-            if (validateInstrumentationRunner(instrumentation) == INSTRUMENTATION_OK) {
-                return instrumentation;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Helper method to determine if specified instrumentation can be used as a test runner
-     * 
-     * @param instrumentation the instrumentation class name to validate. Assumes this
-     *   instrumentation is one of {@link #getInstrumentationNames()}
-     * @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message
-     */
-    String validateInstrumentationRunner(String instrumentation) {
-        if (!mHasRunnerLibrary) {
-            return String.format("The application does not declare uses-library %1$s", 
-                    AndroidConstants.LIBRARY_TEST_RUNNER);
-        }
-        // check if this instrumentation is the standard test runner
-        if (!instrumentation.equals(AndroidConstants.CLASS_INSTRUMENTATION_RUNNER)) {
-            // check if it extends the standard test runner
-            String result = BaseProjectHelper.testClassForManifest(mJavaProject,
-                    instrumentation, AndroidConstants.CLASS_INSTRUMENTATION_RUNNER, true);
-             if (result != BaseProjectHelper.TEST_CLASS_OK) {
-                return String.format("The instrumentation runner must be of type %s", 
-                        AndroidConstants.CLASS_INSTRUMENTATION_RUNNER);
-             }
-        }
-        return INSTRUMENTATION_OK;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidJUnitLaunchInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidJUnitLaunchInfo.java
deleted file mode 100644
index eea999e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidJUnitLaunchInfo.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.launch.junit.runtime;
-
-import com.android.ddmlib.IDevice;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.debug.core.ILaunch;
-
-/**
- * Contains info about Android JUnit launch
- */
-public class AndroidJUnitLaunchInfo {
-    private final IProject mProject;
-    private final String mAppPackage;
-    private final String mRunner;
-
-    private boolean mDebugMode = false;
-    private IDevice mDevice = null;
-    private String mTestPackage = null;
-    private String mTestClass = null;
-    private String mTestMethod = null;
-    private ILaunch mLaunch = null;
-
-    public AndroidJUnitLaunchInfo(IProject project, String appPackage, String runner) {
-        mProject = project;
-        mAppPackage = appPackage;
-        mRunner = runner;
-    }
-
-    public IProject getProject() {
-        return mProject;
-    }
-
-    public String getAppPackage() {
-        return mAppPackage;
-    }
-
-    public String getRunner() {
-        return mRunner;
-    }
-
-    public boolean isDebugMode() {
-        return mDebugMode;
-    }
-    
-    public void setDebugMode(boolean debugMode) {
-        mDebugMode = debugMode;
-    }
-
-    public IDevice getDevice() {
-        return mDevice;
-    }
-
-    public void setDevice(IDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * Specify to run all tests within given package.
-     *
-     * @param testPackage fully qualified java package
-     */
-    public void setTestPackage(String testPackage) {
-        mTestPackage = testPackage;
-    }
-
-    /**
-     * Return the package of tests to run.
-     *
-     * @return fully qualified java package. <code>null</code> if not specified.
-     */
-    public String getTestPackage() {
-        return mTestPackage;       
-    }
-
-    /**
-     * Sets the test class to run.
-     * 
-     * @param testClass fully qualfied test class to run
-     *    Expected format: x.y.x.testclass
-     */
-    public void setTestClass(String testClass) {
-        mTestClass = testClass;
-    }
-
-    /** 
-     * Returns the test class to run.
-     *
-     * @return fully qualfied test class to run.
-     *   <code>null</code> if not specified.
-     */
-    public String getTestClass() {
-        return mTestClass;
-    }
-    
-    /**
-     * Sets the test method to run. testClass must also be set. 
-     * 
-     * @param testMethod test method to run
-     */
-    public void setTestMethod(String testMethod) {
-        mTestMethod = testMethod;
-    }
-
-    /** 
-     * Returns the test method to run.
-     *
-     * @return test method to run. <code>null</code> if not specified.
-     */
-    public String getTestMethod() {
-        return mTestMethod;
-    }
-
-    public ILaunch getLaunch() {
-        return mLaunch;
-    }
-
-    public void setLaunch(ILaunch launch) {
-        mLaunch = launch;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidTestReference.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidTestReference.java
deleted file mode 100644
index 8477ca8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidTestReference.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit.runtime;
-
-import org.eclipse.jdt.internal.junit.runner.ITestIdentifier;
-import org.eclipse.jdt.internal.junit.runner.ITestReference;
-import org.eclipse.jdt.internal.junit.runner.TestExecution;
-
-/**
- * Base implementation of the Eclipse {@link ITestReference} and {@link ITestIdentifier} interfaces
- * for Android tests.
- * <p/>
- * Provides generic equality/hashcode services
- */
-@SuppressWarnings("restriction")  //$NON-NLS-1$
-abstract class AndroidTestReference implements ITestReference, ITestIdentifier {
-
-    /**
-     * Gets the {@link ITestIdentifier} for this test reference.
-     */
-    public ITestIdentifier getIdentifier() {
-        // this class serves as its own test identifier
-        return this;
-    }
-
-    /**
-     * Not supported.
-     */
-    public void run(TestExecution execution) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Compares {@link ITestIdentifier} using names
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof ITestIdentifier) {
-            ITestIdentifier testid = (ITestIdentifier) obj;
-            return getName().equals(testid.getName());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return getName().hashCode();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java
deleted file mode 100755
index e2afc40..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit.runtime;
-
-import com.android.ddmlib.testrunner.ITestRunListener;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import org.eclipse.jdt.internal.junit.runner.MessageIds;
-import org.eclipse.jdt.internal.junit.runner.RemoteTestRunner;
-import org.eclipse.jdt.internal.junit.runner.TestExecution;
-import org.eclipse.jdt.internal.junit.runner.TestReferenceFailure;
-
-/**
- * Supports Eclipse JUnit execution of Android tests.
- * <p/>
- * Communicates back to a Eclipse JDT JUnit client via a socket connection.
- * 
- * @see org.eclipse.jdt.internal.junit.runner.RemoteTestRunner for more details on the protocol
- */
-@SuppressWarnings("restriction")
-public class RemoteAdtTestRunner extends RemoteTestRunner {
-
-    private AndroidJUnitLaunchInfo mLaunchInfo;
-    private TestExecution mExecution;
-    
-    /**
-     * Initialize the JDT JUnit test runner parameters from the {@code args}.
-     * 
-     * @param args name-value pair of arguments to pass to parent JUnit runner. 
-     * @param launchInfo the Android specific test launch info
-     */
-    protected void init(String[] args, AndroidJUnitLaunchInfo launchInfo) {
-        defaultInit(args);
-        mLaunchInfo = launchInfo;
-    }   
-
-    /**
-     * Runs a set of tests, and reports back results using parent class.
-     * <p/>
-     * JDT Unit expects to be sent data in the following sequence:
-     * <ol>
-     *   <li>The total number of tests to be executed.</li>
-     *   <li>The test 'tree' data about the tests to be executed, which is composed of the set of
-     *   test class names, the number of tests in each class, and the names of each test in the
-     *   class.</li>
-     *   <li>The test execution result for each test method. Expects individual notifications of
-     *   the test execution start, any failures, and the end of the test execution.</li>
-     *   <li>The end of the test run, with its elapsed time.</li>
-     * </ol>  
-     * <p/>
-     * In order to satisfy this, this method performs two actual Android instrumentation runs.
-     * The first is a 'log only' run that will collect the test tree data, without actually
-     * executing the tests,  and send it back to JDT JUnit. The second is the actual test execution,
-     * whose results will be communicated back in real-time to JDT JUnit.
-     * 
-     * @param testClassNames ignored - the AndroidJUnitLaunchInfo will be used to determine which
-     *     tests to run.
-     * @param testName ignored
-     * @param execution used to report test progress
-     */
-    @Override
-    public void runTests(String[] testClassNames, String testName, TestExecution execution) {
-        // hold onto this execution reference so it can be used to report test progress
-        mExecution = execution;
-        
-        RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mLaunchInfo.getAppPackage(), 
-                mLaunchInfo.getRunner(), mLaunchInfo.getDevice()); 
-
-        if (mLaunchInfo.getTestClass() != null) {
-            if (mLaunchInfo.getTestMethod() != null) {
-                runner.setMethodName(mLaunchInfo.getTestClass(), mLaunchInfo.getTestMethod());
-            } else {    
-                runner.setClassName(mLaunchInfo.getTestClass());
-            }    
-        }
-
-        if (mLaunchInfo.getTestPackage() != null) {
-            runner.setTestPackageName(mLaunchInfo.getTestPackage());
-        }
-
-        // set log only to first collect test case info, so Eclipse has correct test case count/
-        // tree info
-        runner.setLogOnly(true);
-        TestCollector collector = new TestCollector();        
-        runner.run(collector);
-        if (collector.getErrorMessage() != null) {
-            // error occurred during test collection.
-            reportError(collector.getErrorMessage());
-            // abort here
-            notifyTestRunEnded(0);
-            return;
-        }
-        notifyTestRunStarted(collector.getTestCaseCount());
-        collector.sendTrees(this);
-        
-        // now do real execution
-        runner.setLogOnly(false);
-        if (mLaunchInfo.isDebugMode()) {
-            runner.setDebug(true);
-        }
-        runner.run(new TestRunListener());
-    }
-    
-    /**
-     * Main entry method to run tests
-     * 
-     * @param programArgs JDT JUnit program arguments to be processed by parent
-     * @param junitInfo the {@link AndroidJUnitLaunchInfo} containing info about this test ru
-     */
-    public void runTests(String[] programArgs, AndroidJUnitLaunchInfo junitInfo) {
-        init(programArgs, junitInfo);
-        run();
-    } 
-
-    /**
-     * Stop the current test run.
-     */
-    public void terminate() {
-        stop();
-    }
-
-    @Override
-    protected void stop() {
-        if (mExecution != null) {
-            mExecution.stop();
-        }    
-    }
-
-    private void notifyTestRunEnded(long elapsedTime) {
-        // copy from parent - not ideal, but method is private
-        sendMessage(MessageIds.TEST_RUN_END + elapsedTime);
-        flush();
-        //shutDown();
-    }
-
-    /**
-     * @param errorMessage
-     */
-    private void reportError(String errorMessage) {
-        AdtPlugin.printErrorToConsole(mLaunchInfo.getProject(), 
-                String.format("Test run failed: %s", errorMessage));
-        // is this needed?
-        //notifyTestRunStopped(-1);
-    }
-
-    /**
-     * TestRunListener that communicates results in real-time back to JDT JUnit 
-     */
-    private class TestRunListener implements ITestRunListener {
-
-        /* (non-Javadoc)
-         * @see com.android.ddmlib.testrunner.ITestRunListener#testEnded(com.android.ddmlib.testrunner.TestIdentifier)
-         */
-        public void testEnded(TestIdentifier test) {
-            mExecution.getListener().notifyTestEnded(new TestCaseReference(test));
-        }
-
-        /* (non-Javadoc)
-         * @see com.android.ddmlib.testrunner.ITestRunListener#testFailed(com.android.ddmlib.testrunner.ITestRunListener.TestFailure, com.android.ddmlib.testrunner.TestIdentifier, java.lang.String)
-         */
-        public void testFailed(TestFailure status, TestIdentifier test, String trace) {
-            String statusString;
-            if (status == TestFailure.ERROR) {
-                statusString = MessageIds.TEST_ERROR;
-            } else {
-                statusString = MessageIds.TEST_FAILED;
-            }
-            TestReferenceFailure failure = 
-                new TestReferenceFailure(new TestCaseReference(test), 
-                        statusString, trace, null);
-            mExecution.getListener().notifyTestFailed(failure);
-        }
-
-        /* (non-Javadoc)
-         * @see com.android.ddmlib.testrunner.ITestRunListener#testRunEnded(long)
-         */
-        public void testRunEnded(long elapsedTime) {
-            notifyTestRunEnded(elapsedTime);
-            AdtPlugin.printToConsole(mLaunchInfo.getProject(), "Test run complete");
-        }
-
-        /* (non-Javadoc)
-         * @see com.android.ddmlib.testrunner.ITestRunListener#testRunFailed(java.lang.String)
-         */
-        public void testRunFailed(String errorMessage) {
-            reportError(errorMessage);
-        }
-
-        /* (non-Javadoc)
-         * @see com.android.ddmlib.testrunner.ITestRunListener#testRunStarted(int)
-         */
-        public void testRunStarted(int testCount) {
-            // ignore
-        }
-
-        /* (non-Javadoc)
-         * @see com.android.ddmlib.testrunner.ITestRunListener#testRunStopped(long)
-         */
-        public void testRunStopped(long elapsedTime) {
-            notifyTestRunStopped(elapsedTime);
-            AdtPlugin.printToConsole(mLaunchInfo.getProject(), "Test run stopped");
-        }
-
-        /* (non-Javadoc)
-         * @see com.android.ddmlib.testrunner.ITestRunListener#testStarted(com.android.ddmlib.testrunner.TestIdentifier)
-         */
-        public void testStarted(TestIdentifier test) {
-            TestCaseReference testId = new TestCaseReference(test);
-            mExecution.getListener().notifyTestStarted(testId);
-        }
-    }
-}
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCaseReference.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCaseReference.java
deleted file mode 100644
index 1164956..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCaseReference.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit.runtime;
-
-import com.android.ddmlib.testrunner.TestIdentifier;
-
-import org.eclipse.jdt.internal.junit.runner.IVisitsTestTrees;
-import org.eclipse.jdt.internal.junit.runner.MessageIds;
-
-import java.text.MessageFormat;
-
-/**
- * Reference for a single Android test method.
- */
-@SuppressWarnings("restriction")
-class TestCaseReference extends AndroidTestReference {
-
-    private final String mClassName;
-    private final String mTestName;
-    
-    /**
-     * Creates a TestCaseReference from a class and method name
-     */
-    TestCaseReference(String className, String testName) {
-        mClassName = className;
-        mTestName = testName;
-    }
-
-    /**
-     * Creates a TestCaseReference from a {@link TestIdentifier}
-     * @param test
-     */
-    TestCaseReference(TestIdentifier test) {
-        mClassName = test.getClassName();
-        mTestName = test.getTestName();
-    }
-
-    /**
-     * Returns a count of the number of test cases referenced. Is always one for this class.
-     */
-    public int countTestCases() {
-        return 1;
-    }
-
-    /**
-     * Sends test identifier and test count information for this test
-     * 
-     * @param notified the {@link IVisitsTestTrees} to send test info to
-     */
-    public void sendTree(IVisitsTestTrees notified) {
-        notified.visitTreeEntry(getIdentifier(), false, countTestCases());
-    }
-
-    /**
-     * Returns the identifier of this test, in a format expected by JDT JUnit
-     */
-    public String getName() {
-        return MessageFormat.format(MessageIds.TEST_IDENTIFIER_MESSAGE_FORMAT, 
-                new Object[] { mTestName, mClassName});
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCollector.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCollector.java
deleted file mode 100644
index b64ede3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCollector.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit.runtime;
-
-import com.android.ddmlib.testrunner.ITestRunListener;
-import com.android.ddmlib.testrunner.TestIdentifier;
-
-import org.eclipse.jdt.internal.junit.runner.ITestReference;
-import org.eclipse.jdt.internal.junit.runner.IVisitsTestTrees;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Collects info about tests to be executed by listening to the results of an Android test run.
- */
-@SuppressWarnings("restriction")
-class TestCollector implements ITestRunListener {
-
-    private int mTotalTestCount;
-    /** test name to test suite reference map. */
-    private Map<String, TestSuiteReference> mTestTree;
-    private String mErrorMessage = null;
-
-    TestCollector() {
-        mTotalTestCount = 0; 
-        mTestTree = new HashMap<String, TestSuiteReference>();
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.testrunner.ITestRunListener#testEnded(com.android.ddmlib.testrunner.TestIdentifier)
-     */
-    public void testEnded(TestIdentifier test) {
-        // ignore
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.testrunner.ITestRunListener#testFailed(com.android.ddmlib.testrunner.ITestRunListener.TestFailure, com.android.ddmlib.testrunner.TestIdentifier, java.lang.String)
-     */
-    public void testFailed(TestFailure status, TestIdentifier test, String trace) {
-        // ignore - should be impossible since this is only collecting test information
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.testrunner.ITestRunListener#testRunEnded(long)
-     */
-    public void testRunEnded(long elapsedTime) {
-        // ignore
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.testrunner.ITestRunListener#testRunFailed(java.lang.String)
-     */
-    public void testRunFailed(String errorMessage) {
-        mErrorMessage = errorMessage;
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.testrunner.ITestRunListener#testRunStarted(int)
-     */
-    public void testRunStarted(int testCount) {
-        mTotalTestCount = testCount;
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.testrunner.ITestRunListener#testRunStopped(long)
-     */
-    public void testRunStopped(long elapsedTime) {
-        // ignore
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ddmlib.testrunner.ITestRunListener#testStarted(com.android.ddmlib.testrunner.TestIdentifier)
-     */
-    public void testStarted(TestIdentifier test) {
-        TestSuiteReference suiteRef = mTestTree.get(test.getClassName());
-        if (suiteRef == null) {
-            // this test suite has not been seen before, create it
-            suiteRef = new TestSuiteReference(test.getClassName());
-            mTestTree.put(test.getClassName(), suiteRef);
-        }
-        suiteRef.addTest(new TestCaseReference(test));
-    }
-
-    /**
-     * Returns the total test count in the test run.
-     */
-    public int getTestCaseCount() {
-        return mTotalTestCount;
-    }
-
-    /**
-     * Sends info about the test tree to be executed (ie the suites and their enclosed tests) 
-     * 
-     * @param notified the {@link IVisitsTestTrees} to send test data to
-     */
-    public void sendTrees(IVisitsTestTrees notified) {
-        for (ITestReference ref : mTestTree.values()) {
-            ref.sendTree(notified);
-        }
-    }
-
-    /**
-     * Returns the error message that was reported when collecting test info. 
-     * Returns <code>null</code> if no error occurred.
-     */
-    public String getErrorMessage() {
-        return mErrorMessage;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestSuiteReference.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestSuiteReference.java
deleted file mode 100644
index 9bf1e8d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestSuiteReference.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch.junit.runtime;
-
-import org.eclipse.jdt.internal.junit.runner.IVisitsTestTrees;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Reference for an Android test suite aka class.
- */
-@SuppressWarnings("restriction")
-class TestSuiteReference extends AndroidTestReference {
-
-    private final String mClassName;
-    private List<TestCaseReference> mTests;
-
-    /**
-     * Creates a TestSuiteReference
-     * 
-     * @param className the fully qualified name of the test class
-     */
-    TestSuiteReference(String className) {
-         mClassName = className; 
-         mTests = new ArrayList<TestCaseReference>();
-    }
-
-    /**
-     * Returns a count of the number of test cases included in this suite. 
-     */
-    public int countTestCases() {
-        return mTests.size();
-    }
-
-    /**
-     * Sends test identifier and test count information for this test class, and all its included
-     * test methods.
-     * 
-     * @param notified the {@link IVisitsTestTrees} to send test info too
-     */
-    public void sendTree(IVisitsTestTrees notified) {
-        notified.visitTreeEntry(getIdentifier(), true, countTestCases());
-        for (TestCaseReference ref : mTests) {
-            ref.sendTree(notified);
-        }
-    }
-
-    /**
-     * Return the name of this test class.
-     */
-    public String getName() {
-        return mClassName;
-    }
-
-    /**
-     * Adds a test method to this suite.
-     * 
-     * @param testRef the {@link TestCaseReference} to add
-     */
-    void addTest(TestCaseReference testRef) {
-        mTests.add(testRef);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AndroidPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AndroidPreferencePage.java
deleted file mode 100644
index 6f4772b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AndroidPreferencePage.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.preferences;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdkuilib.internal.widgets.SdkTargetSelector;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.preference.DirectoryFieldEditor;
-import org.eclipse.jface.preference.FieldEditorPreferencePage;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-import java.io.File;
-
-/**
- * This class represents a preference page that is contributed to the
- * Preferences dialog. By subclassing <samp>FieldEditorPreferencePage</samp>,
- * we can use the field support built into JFace that allows us to create a page
- * that is small and knows how to save, restore and apply itself.
- * <p>
- * This page is used to modify preferences only. They are stored in the
- * preference store that belongs to the main plug-in class. That way,
- * preferences can be accessed directly via the preference store.
- */
-
-public class AndroidPreferencePage extends FieldEditorPreferencePage implements
-        IWorkbenchPreferencePage {
-
-    private SdkDirectoryFieldEditor mDirectoryField;
-
-    public AndroidPreferencePage() {
-        super(GRID);
-        setPreferenceStore(AdtPlugin.getDefault().getPreferenceStore());
-        setDescription(Messages.AndroidPreferencePage_Title);
-    }
-
-    /**
-     * Creates the field editors. Field editors are abstractions of the common
-     * GUI blocks needed to manipulate various types of preferences. Each field
-     * editor knows how to save and restore itself.
-     */
-    @Override
-    public void createFieldEditors() {
-
-        mDirectoryField = new SdkDirectoryFieldEditor(AdtPlugin.PREFS_SDK_DIR,
-                Messages.AndroidPreferencePage_SDK_Location_, getFieldEditorParent());
-
-        addField(mDirectoryField);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-     */
-    public void init(IWorkbench workbench) {
-    }
-
-    @Override
-    public void dispose() {
-        super.dispose();
-
-        if (mDirectoryField != null) {
-            mDirectoryField.dispose();
-            mDirectoryField = null;
-        }
-    }
-
-    /**
-     * Custom version of DirectoryFieldEditor which validates that the directory really
-     * contains an SDK.
-     *
-     * There's a known issue here, which is really a rare edge-case: if the pref dialog is open
-     * which a given sdk directory and the *content* of the directory changes such that the sdk
-     * state changed (i.e. from valid to invalid or vice versa), the pref panel will display or
-     * hide the error as appropriate but the pref panel will fail to validate the apply/ok buttons
-     * appropriately. The easy workaround is to cancel the pref panel and enter it again.
-     */
-    private static class SdkDirectoryFieldEditor extends DirectoryFieldEditor {
-
-        private SdkTargetSelector mTargetSelector;
-        private TargetChangedListener mTargetChangeListener;
-
-        public SdkDirectoryFieldEditor(String name, String labelText, Composite parent) {
-            super(name, labelText, parent);
-            setEmptyStringAllowed(false);
-        }
-
-        /**
-         * Method declared on StringFieldEditor and overridden in DirectoryFieldEditor.
-         * Checks whether the text input field contains a valid directory.
-         *
-         * @return True if the apply/ok button should be enabled in the pref panel
-         */
-        @Override
-        protected boolean doCheckState() {
-            String fileName = getTextControl().getText();
-            fileName = fileName.trim();
-
-            if (fileName.indexOf(',') >= 0 || fileName.indexOf(';') >= 0) {
-                setErrorMessage(Messages.AndroidPreferencePage_ERROR_Reserved_Char);
-                return false;  // Apply/OK must be disabled
-            }
-
-            File file = new File(fileName);
-            if (!file.isDirectory()) {
-                setErrorMessage(JFaceResources.getString(
-                    "DirectoryFieldEditor.errorMessage")); //$NON-NLS-1$
-                return false;
-            }
-
-            boolean ok = AdtPlugin.getDefault().checkSdkLocationAndId(fileName,
-                    new AdtPlugin.CheckSdkErrorHandler() {
-                @Override
-                public boolean handleError(String message) {
-                    setErrorMessage(message.replaceAll("\n", " ")); //$NON-NLS-1$ //$NON-NLS-2$
-                    return false;  // Apply/OK must be disabled
-                }
-
-                @Override
-                public boolean handleWarning(String message) {
-                    showMessage(message.replaceAll("\n", " ")); //$NON-NLS-1$ //$NON-NLS-2$
-                    return true;  // Apply/OK must be enabled
-                }
-            });
-            if (ok) clearMessage();
-            return ok;
-        }
-
-        @Override
-        public Text getTextControl(Composite parent) {
-            setValidateStrategy(VALIDATE_ON_KEY_STROKE);
-            return super.getTextControl(parent);
-        }
-
-        /* (non-Javadoc)
-         * Method declared on StringFieldEditor (and FieldEditor).
-         */
-        @Override
-        protected void doFillIntoGrid(Composite parent, int numColumns) {
-            super.doFillIntoGrid(parent, numColumns);
-
-            GridData gd;
-            Label l = new Label(parent, SWT.NONE);
-            l.setText("Note: The list of SDK Targets below is only reloaded once you hit 'Apply' or 'OK'.");
-            gd = new GridData(GridData.FILL_HORIZONTAL);
-            gd.horizontalSpan = numColumns;
-            l.setLayoutData(gd);
-
-            try {
-                // We may not have an sdk if the sdk path pref is empty or not valid.
-                Sdk sdk = Sdk.getCurrent();
-                IAndroidTarget[] targets = sdk != null ? sdk.getTargets() : null;
-
-                mTargetSelector = new SdkTargetSelector(parent,
-                        targets,
-                        false /*allowSelection*/);
-                gd = (GridData) mTargetSelector.getLayoutData();
-                gd.horizontalSpan = numColumns;
-
-                if (mTargetChangeListener == null) {
-                    mTargetChangeListener = new TargetChangedListener();
-                    AdtPlugin.getDefault().addTargetListener(mTargetChangeListener);
-                }
-            } catch (Exception e) {
-                // We need to catch *any* exception that arises here, otherwise it disables
-                // the whole pref panel. We can live without the Sdk target selector but
-                // not being able to actually set an sdk path.
-                AdtPlugin.log(e, "SdkTargetSelector failed");
-            }
-        }
-
-        @Override
-        public void dispose() {
-            super.dispose();
-            if (mTargetChangeListener != null) {
-                AdtPlugin.getDefault().removeTargetListener(mTargetChangeListener);
-                mTargetChangeListener = null;
-            }
-        }
-
-        private class TargetChangedListener implements ITargetChangeListener {
-            public void onProjectTargetChange(IProject changedProject) {
-                // do nothing.
-            }
-
-            public void onTargetsLoaded() {
-                if (mTargetSelector != null) {
-                    // We may not have an sdk if the sdk path pref is empty or not valid.
-                    Sdk sdk = Sdk.getCurrent();
-                    IAndroidTarget[] targets = sdk != null ? sdk.getTargets() : null;
-
-                    mTargetSelector.setTargets(targets);
-                }
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/BuildPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/BuildPreferencePage.java
deleted file mode 100644
index 7adfc23..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/BuildPreferencePage.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.preferences;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.jarutils.DebugKeyProvider;
-import com.android.jarutils.DebugKeyProvider.KeytoolException;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-
-import org.eclipse.jface.preference.BooleanFieldEditor;
-import org.eclipse.jface.preference.FieldEditorPreferencePage;
-import org.eclipse.jface.preference.FileFieldEditor;
-import org.eclipse.jface.preference.RadioGroupFieldEditor;
-import org.eclipse.jface.preference.StringFieldEditor;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-
-/**
- * Preference page for build options.
- *
- */
-public class BuildPreferencePage extends FieldEditorPreferencePage implements
-        IWorkbenchPreferencePage {
-
-    final static String BUILD_STR_SILENT = "silent"; //$NON-NLS-1$
-    final static String BUILD_STR_NORMAL = "normal"; //$NON-NLS-1$
-    final static String BUILD_STR_VERBOSE = "verbose"; //$NON-NLS-1$
-
-    public BuildPreferencePage() {
-        super(GRID);
-        setPreferenceStore(AdtPlugin.getDefault().getPreferenceStore());
-        setDescription(Messages.BuildPreferencePage_Title);
-    }
-
-    public static int getBuildLevel(String buildPrefValue) {
-        if (BUILD_STR_SILENT.equals(buildPrefValue)) {
-            return AdtConstants.BUILD_ALWAYS;
-        } else if (BUILD_STR_VERBOSE.equals(buildPrefValue)) {
-            return AdtConstants.BUILD_VERBOSE;
-        }
-
-        return AdtConstants.BUILD_NORMAL;
-    }
-
-    @Override
-    protected void createFieldEditors() {
-        addField(new BooleanFieldEditor(AdtPlugin.PREFS_RES_AUTO_REFRESH,
-                Messages.BuildPreferencePage_Auto_Refresh_Resources_on_Build,
-                getFieldEditorParent()));
-
-        RadioGroupFieldEditor rgfe = new RadioGroupFieldEditor(
-                AdtPlugin.PREFS_BUILD_VERBOSITY,
-                Messages.BuildPreferencePage_Build_Output, 1, new String[][] {
-                    { Messages.BuildPreferencePage_Silent, BUILD_STR_SILENT },
-                    { Messages.BuildPreferencePage_Normal, BUILD_STR_NORMAL },
-                    { Messages.BuildPreferencePage_Verbose, BUILD_STR_VERBOSE }
-                    },
-                getFieldEditorParent(), true);
-        addField(rgfe);
-
-        addField(new ReadOnlyFieldEditor(AdtPlugin.PREFS_DEFAULT_DEBUG_KEYSTORE,
-                Messages.BuildPreferencePage_Default_KeyStore, getFieldEditorParent()));
-
-        addField(new KeystoreFieldEditor(AdtPlugin.PREFS_CUSTOM_DEBUG_KEYSTORE,
-                Messages.BuildPreferencePage_Custom_Keystore, getFieldEditorParent()));
-
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-     */
-    public void init(IWorkbench workbench) {
-    }
-
-    /**
-     * A read-only string field editor.
-     */
-    private static class ReadOnlyFieldEditor extends StringFieldEditor {
-
-        public ReadOnlyFieldEditor(String name, String labelText, Composite parent) {
-            super(name, labelText, parent);
-        }
-
-        @Override
-        protected void createControl(Composite parent) {
-            super.createControl(parent);
-            
-            Text control = getTextControl();
-            control.setEditable(false);
-        }
-    }
-    
-    /**
-     * Custom {@link FileFieldEditor} that checks that the keystore is valid.
-     */
-    private static class KeystoreFieldEditor extends FileFieldEditor {
-        public KeystoreFieldEditor(String name, String label, Composite parent) {
-            super(name, label, parent);
-            setValidateStrategy(VALIDATE_ON_KEY_STROKE);
-        }
-        
-        @Override
-        protected boolean checkState() {
-            String fileName = getTextControl().getText();
-            fileName = fileName.trim();
-            
-            // empty values are considered ok.
-            if (fileName.length() > 0) {
-                File file = new File(fileName);
-                if (file.isFile()) {
-                    // attempt to load the debug key.
-                    try {
-                        DebugKeyProvider provider = new DebugKeyProvider(fileName,
-                                null /* storeType */, null /* key gen output */);
-                        PrivateKey key = provider.getDebugKey();
-                        X509Certificate certificate = (X509Certificate)provider.getCertificate();
-                        
-                        if (key == null || certificate == null) {
-                            showErrorMessage("Unable to find debug key in keystore!");
-                            return false;
-                        }
-                        
-                        Date today = new Date();
-                        if (certificate.getNotAfter().compareTo(today) < 0) {
-                            showErrorMessage("Certificate is expired!");
-                            return false;
-                        }
-                        
-                        if (certificate.getNotBefore().compareTo(today) > 0) {
-                            showErrorMessage("Certificate validity is in the future!");
-                            return false;
-                        }
-
-                        // we're good!
-                        clearErrorMessage();
-                        return true;
-                    } catch (GeneralSecurityException e) {
-                        handleException(e);
-                        return false;
-                    } catch (IOException e) {
-                        handleException(e);
-                        return false;
-                    } catch (KeytoolException e) {
-                        handleException(e);
-                        return false;
-                    } catch (AndroidLocationException e) {
-                        handleException(e);
-                        return false;
-                    }
-
-            
-                } else {
-                    // file does not exist.
-                    showErrorMessage("Not a valid keystore path.");
-                    return false;  // Apply/OK must be disabled
-                }
-            }
-
-            clearErrorMessage();
-            return true;
-        }
-        
-        @Override
-        public Text getTextControl(Composite parent) {
-            setValidateStrategy(VALIDATE_ON_KEY_STROKE);
-            return super.getTextControl(parent);
-        }
-
-        /**
-         * Set the error message from a {@link Throwable}. If the exception has no message, try
-         * to get the message from the cause.
-         * @param t the Throwable.
-         */
-        private void handleException(Throwable t) {
-            String msg = t.getMessage();
-            if (msg == null) {
-                Throwable cause = t.getCause();
-                if (cause != null) {
-                    handleException(cause);
-                } else {
-                    setErrorMessage("Uknown error when getting the debug key!");
-                }
-                
-                return;
-            }
-
-            // valid text, display it.
-            showErrorMessage(msg);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/LaunchPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/LaunchPreferencePage.java
deleted file mode 100644
index df30eb5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/LaunchPreferencePage.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.preferences;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import org.eclipse.jface.preference.FieldEditorPreferencePage;
-import org.eclipse.jface.preference.StringFieldEditor;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-/**
- * Settings page for launch related preferences.
- */
-public class LaunchPreferencePage extends FieldEditorPreferencePage implements
-        IWorkbenchPreferencePage {
-    
-    public LaunchPreferencePage() {
-        super(GRID);
-        setPreferenceStore(AdtPlugin.getDefault().getPreferenceStore());
-        setDescription(Messages.LaunchPreferencePage_Title);
-    }
-
-    @Override
-    protected void createFieldEditors() {
-        addField(new StringFieldEditor(AdtPlugin.PREFS_EMU_OPTIONS,
-                Messages.LaunchPreferencePage_Default_Emu_Options, getFieldEditorParent()));
-
-        addField(new StringFieldEditor(AdtPlugin.PREFS_HOME_PACKAGE,
-                Messages.LaunchPreferencePage_Default_HOME_Package, getFieldEditorParent()));
-    }
-
-    public void init(IWorkbench workbench) {
-        // pass
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/Messages.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/Messages.java
deleted file mode 100644
index 1474102..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/Messages.java
+++ /dev/null
@@ -1,43 +0,0 @@
-
-package com.android.ide.eclipse.adt.internal.preferences;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-    private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.internal.preferences.messages"; //$NON-NLS-1$
-
-    public static String AndroidPreferencePage_ERROR_Reserved_Char;
-
-    public static String AndroidPreferencePage_SDK_Location_;
-
-    public static String AndroidPreferencePage_Title;
-
-    public static String BuildPreferencePage_Auto_Refresh_Resources_on_Build;
-
-    public static String BuildPreferencePage_Build_Output;
-
-    public static String BuildPreferencePage_Custom_Keystore;
-
-    public static String BuildPreferencePage_Default_KeyStore;
-
-    public static String BuildPreferencePage_Normal;
-
-    public static String BuildPreferencePage_Silent;
-
-    public static String BuildPreferencePage_Title;
-
-    public static String BuildPreferencePage_Verbose;
-
-    public static String LaunchPreferencePage_Default_Emu_Options;
-
-    public static String LaunchPreferencePage_Default_HOME_Package;
-
-    public static String LaunchPreferencePage_Title;
-    static {
-        // initialize resource bundle
-        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
-    }
-
-    private Messages() {
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/PreferenceInitializer.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/PreferenceInitializer.java
deleted file mode 100644
index 4617e96..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/PreferenceInitializer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.preferences;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.jarutils.DebugKeyProvider;
-import com.android.jarutils.DebugKeyProvider.KeytoolException;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-
-import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * Class used to initialize default preference values.
- */
-public class PreferenceInitializer extends AbstractPreferenceInitializer {
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer
-     * #initializeDefaultPreferences()
-     */
-    @Override
-    public void initializeDefaultPreferences() {
-        IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
-
-        store.setDefault(AdtPlugin.PREFS_RES_AUTO_REFRESH, true);
-
-        store.setDefault(AdtPlugin.PREFS_BUILD_VERBOSITY, BuildPreferencePage.BUILD_STR_NORMAL);
-        
-        store.setDefault(AdtPlugin.PREFS_HOME_PACKAGE, "android.process.acore"); //$NON-NLS-1$
-        
-        try {
-            store.setDefault(AdtPlugin.PREFS_DEFAULT_DEBUG_KEYSTORE,
-                    DebugKeyProvider.getDefaultKeyStoreOsPath());
-        } catch (KeytoolException e) {
-            AdtPlugin.log(e, "Get default debug keystore path failed"); //$NON-NLS-1$
-        } catch (AndroidLocationException e) {
-            AdtPlugin.log(e, "Get default debug keystore path failed"); //$NON-NLS-1$
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/UsagePreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/UsagePreferencePage.java
deleted file mode 100644
index acdfefd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/UsagePreferencePage.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.preferences;
-
-import com.android.sdkstats.SdkStatsService;
-
-import org.eclipse.jface.preference.BooleanFieldEditor;
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.jface.preference.PreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-import java.io.IOException;
-
-public class UsagePreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
-
-    private BooleanFieldEditor mOptInCheckBox;
-
-    public UsagePreferencePage() {
-    }
-
-    public void init(IWorkbench workbench) {
-        // pass
-    }
-
-    @Override
-    protected Control createContents(Composite parent) {
-        Composite top = new Composite(parent, SWT.NONE);
-        top.setLayout(new GridLayout(1, false));
-        top.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        Link text = new Link(top, SWT.WRAP);
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.widthHint = 200;
-        text.setLayoutData(gd);
-        text.setText(SdkStatsService.BODY_TEXT);
-
-        text.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent event) {
-                SdkStatsService.openUrl(event.text);
-            }
-        });
-
-        mOptInCheckBox = new BooleanFieldEditor(SdkStatsService.PING_OPT_IN,
-                SdkStatsService.CHECKBOX_TEXT, top);
-        mOptInCheckBox.setPage(this);
-        mOptInCheckBox.setPreferenceStore(SdkStatsService.getPreferenceStore());
-        mOptInCheckBox.load();
-        
-        return top;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.preference.PreferencePage#performCancel()
-     */
-    @Override
-    public boolean performCancel() {
-        mOptInCheckBox.load();
-        return super.performCancel();
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
-     */
-    @Override
-    protected void performDefaults() {
-        mOptInCheckBox.loadDefault();
-        super.performDefaults();
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.preference.PreferencePage#performOk()
-     */
-    @Override
-    public boolean performOk() {
-        save();
-        return super.performOk();
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.preference.PreferencePage#performApply()
-     */
-    @Override
-    protected void performApply() {
-        save();
-        super.performApply();
-    }
-    
-    private void save() {
-        try {
-            PreferenceStore store = SdkStatsService.getPreferenceStore();
-            if (store !=  null) {
-                store.setValue(SdkStatsService.PING_OPT_IN, mOptInCheckBox.getBooleanValue());
-                store.save();
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/messages.properties
deleted file mode 100644
index 865ac19..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/messages.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-BuildPreferencePage_Title=Build Settings:
-BuildPreferencePage_Auto_Refresh_Resources_on_Build=Automatically refresh Resources and Assets folder on build
-BuildPreferencePage_Build_Output=Build output
-BuildPreferencePage_Silent=Silent
-BuildPreferencePage_Normal=Normal
-BuildPreferencePage_Verbose=Verbose
-BuildPreferencePage_Default_KeyStore=Default debug keystore:
-BuildPreferencePage_Custom_Keystore=Custom debug keystore:
-LaunchPreferencePage_Title=Launch Settings:
-LaunchPreferencePage_Default_Emu_Options=Default emulator options:
-LaunchPreferencePage_Default_HOME_Package=Default HOME package:
-AndroidPreferencePage_Title=Android Preferences
-AndroidPreferencePage_SDK_Location_=SDK Location:
-AndroidPreferencePage_ERROR_Reserved_Char=Reserved characters ',' and ';' cannot be used in the SDK Location.
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainer.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainer.java
deleted file mode 100644
index bbef6b9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.jdt.core.IClasspathContainer;
-import org.eclipse.jdt.core.IClasspathEntry;
-
-/**
- * Classpath container for the Android projects.
- */
-class AndroidClasspathContainer implements IClasspathContainer {
-    
-    private IClasspathEntry[] mClasspathEntry;
-    private IPath mContainerPath;
-    private String mName;
-    
-    /**
-     * Constructs the container with the {@link IClasspathEntry} representing the android
-     * framework jar file and the container id
-     * @param entries the entries representing the android framework and optional libraries.
-     * @param path the path containing the classpath container id.
-     * @param name the name of the container to display.
-     */
-    AndroidClasspathContainer(IClasspathEntry[] entries, IPath path, String name) {
-        mClasspathEntry = entries;
-        mContainerPath = path;
-        mName = name;
-    }
-    
-    public IClasspathEntry[] getClasspathEntries() {
-        return mClasspathEntry;
-    }
-
-    public String getDescription() {
-        return mName;
-    }
-
-    public int getKind() {
-        return IClasspathContainer.K_DEFAULT_SYSTEM;
-    }
-
-    public IPath getPath() {
-        return mContainerPath;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
deleted file mode 100644
index 44956bc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.ClasspathContainerInitializer;
-import org.eclipse.jdt.core.IAccessRule;
-import org.eclipse.jdt.core.IClasspathAttribute;
-import org.eclipse.jdt.core.IClasspathContainer;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.regex.Pattern;
-
-/**
- * Classpath container initializer responsible for binding {@link AndroidClasspathContainer} to
- * {@link IProject}s. This removes the hard-coded path to the android.jar.
- */
-public class AndroidClasspathContainerInitializer extends ClasspathContainerInitializer {
-    /** The container id for the android framework jar file */
-    private final static String CONTAINER_ID =
-        "com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"; //$NON-NLS-1$
-
-    /** path separator to store multiple paths in a single property. This is guaranteed to not
-     * be in a path.
-     */
-    private final static String PATH_SEPARATOR = "\u001C"; //$NON-NLS-1$
-
-    private final static String PROPERTY_CONTAINER_CACHE = "androidContainerCache"; //$NON-NLS-1$
-    private final static String PROPERTY_TARGET_NAME = "androidTargetCache"; //$NON-NLS-1$
-    private final static String CACHE_VERSION = "01"; //$NON-NLS-1$
-    private final static String CACHE_VERSION_SEP = CACHE_VERSION + PATH_SEPARATOR;
-    
-    private final static int CACHE_INDEX_JAR = 0;
-    private final static int CACHE_INDEX_SRC = 1;
-    private final static int CACHE_INDEX_DOCS_URI = 2;
-    private final static int CACHE_INDEX_OPT_DOCS_URI = 3;
-    private final static int CACHE_INDEX_ADD_ON_START = CACHE_INDEX_OPT_DOCS_URI;
-    
-    public AndroidClasspathContainerInitializer() {
-        // pass
-    }
-
-    /**
-     * Binds a classpath container  to a {@link IClasspathContainer} for a given project,
-     * or silently fails if unable to do so.
-     * @param containerPath the container path that is the container id.
-     * @param project the project to bind
-     */
-    @Override
-    public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
-        if (CONTAINER_ID.equals(containerPath.toString())) {
-            JavaCore.setClasspathContainer(new Path(CONTAINER_ID),
-                    new IJavaProject[] { project },
-                    new IClasspathContainer[] { allocateAndroidContainer(project) },
-                    new NullProgressMonitor());
-        }
-    }
-
-    /**
-     * Creates a new {@link IClasspathEntry} of type {@link IClasspathEntry#CPE_CONTAINER}
-     * linking to the Android Framework.
-     */
-    public static IClasspathEntry getContainerEntry() {
-        return JavaCore.newContainerEntry(new Path(CONTAINER_ID));
-    }
-
-    /**
-     * Checks the {@link IPath} objects against the android framework container id and
-     * returns <code>true</code> if they are identical.
-     * @param path the <code>IPath</code> to check.
-     */
-    public static boolean checkPath(IPath path) {
-        return CONTAINER_ID.equals(path.toString());
-    }
-    
-    /**
-     * Updates the {@link IJavaProject} objects with new android framework container. This forces
-     * JDT to recompile them.
-     * @param androidProjects the projects to update.
-     * @return <code>true</code> if success, <code>false</code> otherwise.
-     */
-    public static boolean updateProjects(IJavaProject[] androidProjects) {
-        try {
-            // Allocate a new AndroidClasspathContainer, and associate it to the android framework 
-            // container id for each projects.
-            // By providing a new association between a container id and a IClasspathContainer,
-            // this forces the JDT to query the IClasspathContainer for new IClasspathEntry (with
-            // IClasspathContainer#getClasspathEntries()), and therefore force recompilation of 
-            // the projects.
-            int projectCount = androidProjects.length;
-
-            IClasspathContainer[] containers = new IClasspathContainer[projectCount];
-            for (int i = 0 ; i < projectCount; i++) {
-                containers[i] = allocateAndroidContainer(androidProjects[i]);
-            }
-
-            // give each project their new container in one call.
-            JavaCore.setClasspathContainer(
-                    new Path(CONTAINER_ID),
-                    androidProjects, containers, new NullProgressMonitor());
-            
-            return true;
-        } catch (JavaModelException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Allocates and returns an {@link AndroidClasspathContainer} object with the proper
-     * path to the framework jar file.
-     * @param javaProject The java project that will receive the container.
-     */
-    private static IClasspathContainer allocateAndroidContainer(IJavaProject javaProject) {
-        final IProject iProject = javaProject.getProject();
-
-        String markerMessage = null;
-        boolean outputToConsole = true;
-        
-        try {
-            AdtPlugin plugin = AdtPlugin.getDefault();
-            
-            // get the lock object for project manipulation during SDK load.
-            Object lock = plugin.getSdkLockObject();
-            synchronized (lock) {
-                boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED;
-                
-                // check if the project has a valid target.
-                IAndroidTarget target = null;
-                if (sdkIsLoaded) {
-                    target = Sdk.getCurrent().getTarget(iProject);
-                }
-
-                // if we are loaded and the target is non null, we create a valid ClassPathContainer
-                if (sdkIsLoaded && target != null) {
-                    
-                    String targetName = target.getClasspathName();
-
-                    return new AndroidClasspathContainer(
-                            createClasspathEntries(iProject, target, targetName),
-                            new Path(CONTAINER_ID), targetName);
-                }
-
-                // In case of error, we'll try different thing to provide the best error message
-                // possible.
-                // Get the project's target's hash string (if it exists)
-                String hashString = Sdk.getProjectTargetHashString(iProject);
-
-                if (hashString == null || hashString.length() == 0) {
-                    // if there is no hash string we only show this if the SDK is loaded.
-                    // For a project opened at start-up with no target, this would be displayed
-                    // twice, once when the project is opened, and once after the SDK has
-                    // finished loading.
-                    // By testing the sdk is loaded, we only show this once in the console.
-                    if (sdkIsLoaded) {
-                        markerMessage = String.format(
-                                "Project has no target set. Edit the project properties to set one.");
-                    }
-                } else if (sdkIsLoaded) {
-                    markerMessage = String.format(
-                            "Unable to resolve target '%s'", hashString);
-                } else {
-                    // this is the case where there is a hashString but the SDK is not yet
-                    // loaded and therefore we can't get the target yet.
-                    // We check if there is a cache of the needed information.
-                    AndroidClasspathContainer container = getContainerFromCache(iProject);
-                    
-                    if (container == null) {
-                        // either the cache was wrong (ie folder does not exists anymore), or 
-                        // there was no cache. In this case we need to make sure the project
-                        // is resolved again after the SDK is loaded.
-                        plugin.setProjectToResolve(javaProject);
-                        
-                        markerMessage = String.format(
-                                "Unable to resolve target '%s' until the SDK is loaded.",
-                                hashString);
-
-                        // let's not log this one to the console as it will happen at every boot,
-                        // and it's expected. (we do keep the error marker though).
-                        outputToConsole = false;
-
-                    } else {
-                        // we created a container from the cache, so we register the project
-                        // to be checked for cache validity once the SDK is loaded
-                        plugin.setProjectToCheck(javaProject);
-                        
-                        // and return the container
-                        return container;
-                    }
-                    
-                }
-                
-                // return a dummy container to replace the one we may have had before.
-                // It'll be replaced by the real when if/when the target is resolved if/when the
-                // SDK finishes loading.
-                return new IClasspathContainer() {
-                    public IClasspathEntry[] getClasspathEntries() {
-                        return new IClasspathEntry[0];
-                    }
-
-                    public String getDescription() {
-                        return "Unable to get system library for the project";
-                    }
-
-                    public int getKind() {
-                        return IClasspathContainer.K_DEFAULT_SYSTEM;
-                    }
-
-                    public IPath getPath() {
-                        return null;
-                    }
-                };
-            }
-        } finally {
-            if (markerMessage != null) {
-                // log the error and put the marker on the project if we can.
-                if (outputToConsole) {
-                    AdtPlugin.printErrorToConsole(iProject, markerMessage);
-                }
-                
-                try {
-                    BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET, markerMessage,
-                            -1, IMarker.SEVERITY_ERROR, IMarker.PRIORITY_HIGH);
-                } catch (CoreException e) {
-                    // In some cases, the workspace may be locked for modification when we
-                    // pass here.
-                    // We schedule a new job to put the marker after.
-                    final String fmessage = markerMessage;
-                    Job markerJob = new Job("Android SDK: Resolving error markers") {
-                        @Override
-                        protected IStatus run(IProgressMonitor monitor) {
-                            try {
-                                BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET,
-                                        fmessage, -1, IMarker.SEVERITY_ERROR,
-                                        IMarker.PRIORITY_HIGH);
-                            } catch (CoreException e2) {
-                                return e2.getStatus();
-                            }
-
-                            return Status.OK_STATUS;
-                        }
-                    };
-
-                    // build jobs are run after other interactive jobs
-                    markerJob.setPriority(Job.BUILD);
-                    markerJob.schedule();
-                }
-            } else {
-                // no error, remove potential MARKER_TARGETs.
-                try {
-                    if (iProject.exists()) {
-                        iProject.deleteMarkers(AdtConstants.MARKER_TARGET, true,
-                                IResource.DEPTH_INFINITE);
-                    }
-                } catch (CoreException ce) {
-                    // In some cases, the workspace may be locked for modification when we pass
-                    // here, so we schedule a new job to put the marker after.
-                    Job markerJob = new Job("Android SDK: Resolving error markers") {
-                        @Override
-                        protected IStatus run(IProgressMonitor monitor) {
-                            try {
-                                iProject.deleteMarkers(AdtConstants.MARKER_TARGET, true,
-                                        IResource.DEPTH_INFINITE);
-                            } catch (CoreException e2) {
-                                return e2.getStatus();
-                            }
-
-                            return Status.OK_STATUS;
-                        }
-                    };
-
-                    // build jobs are run after other interactive jobs
-                    markerJob.setPriority(Job.BUILD);
-                    markerJob.schedule();
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates and returns an array of {@link IClasspathEntry} objects for the android
-     * framework and optional libraries.
-     * <p/>This references the OS path to the android.jar and the
-     * java doc directory. This is dynamically created when a project is opened,
-     * and never saved in the project itself, so there's no risk of storing an
-     * obsolete path.
-     * The method also stores the paths used to create the entries in the project persistent
-     * properties. A new {@link AndroidClasspathContainer} can be created from the stored path
-     * using the {@link #getContainerFromCache(IProject)} method.
-     * @param project 
-     * @param target The target that contains the libraries.
-     * @param targetName 
-     */
-    private static IClasspathEntry[] createClasspathEntries(IProject project,
-            IAndroidTarget target, String targetName) {
-        
-        // get the path from the target
-        String[] paths = getTargetPaths(target);
-        
-        // create the classpath entry from the paths
-        IClasspathEntry[] entries = createClasspathEntriesFromPaths(paths);
-        
-        // paths now contains all the path required to recreate the IClasspathEntry with no
-        // target info. We encode them in a single string, with each path separated by
-        // OS path separator.
-        StringBuilder sb = new StringBuilder(CACHE_VERSION);
-        for (String p : paths) {
-            sb.append(PATH_SEPARATOR);
-            sb.append(p);
-        }
-        
-        // store this in a project persistent property
-        ProjectHelper.saveStringProperty(project, PROPERTY_CONTAINER_CACHE, sb.toString());
-        ProjectHelper.saveStringProperty(project, PROPERTY_TARGET_NAME, targetName);
-
-        return entries;
-    }
-    
-    /**
-     * Generates an {@link AndroidClasspathContainer} from the project cache, if possible.
-     */
-    private static AndroidClasspathContainer getContainerFromCache(IProject project) {
-        // get the cached info from the project persistent properties.
-        String cache = ProjectHelper.loadStringProperty(project, PROPERTY_CONTAINER_CACHE);
-        String targetNameCache = ProjectHelper.loadStringProperty(project, PROPERTY_TARGET_NAME);
-        if (cache == null || targetNameCache == null) {
-            return null;
-        }
-        
-        // the first 2 chars must match CACHE_VERSION. The 3rd char is the normal separator.
-        if (cache.startsWith(CACHE_VERSION_SEP) == false) {
-            return null;
-        }
-        
-        cache = cache.substring(CACHE_VERSION_SEP.length());
-        
-        // the cache contains multiple paths, separated by a character guaranteed to not be in
-        // the path (\u001C).
-        // The first 3 are for android.jar (jar, source, doc), the rest are for the optional
-        // libraries and should contain at least one doc and a jar (if there are any libraries).
-        // Therefore, the path count should be 3 or 5+
-        String[] paths = cache.split(Pattern.quote(PATH_SEPARATOR));
-        if (paths.length < 3 || paths.length == 4) {
-            return null;
-        }
-        
-        // now we check the paths actually exist.
-        // There's an exception: If the source folder for android.jar does not exist, this is
-        // not a problem, so we skip it.
-        // Also paths[CACHE_INDEX_DOCS_URI] is a URI to the javadoc, so we test it a
-        // bit differently.
-        try {
-            if (new File(paths[CACHE_INDEX_JAR]).exists() == false ||
-                    new File(new URI(paths[CACHE_INDEX_DOCS_URI])).exists() == false) {
-                return null;
-            }
-        
-            // check the path for the add-ons, if they exist.
-            if (paths.length > CACHE_INDEX_ADD_ON_START) {
-                
-                // check the docs path separately from the rest of the paths as it's a URI.
-                if (new File(new URI(paths[CACHE_INDEX_OPT_DOCS_URI])).exists() == false) {
-                    return null;
-                }
-
-                // now just check the remaining paths.
-                for (int i = CACHE_INDEX_ADD_ON_START + 1; i < paths.length; i++) {
-                    String path = paths[i];
-                    if (path.length() > 0) {
-                        File f = new File(path);
-                        if (f.exists() == false) {
-                            return null;
-                        }
-                    }
-                }
-            }
-        } catch (URISyntaxException e) {
-            return null;
-        }
-
-        IClasspathEntry[] entries = createClasspathEntriesFromPaths(paths);
-
-        return new AndroidClasspathContainer(entries,
-                new Path(CONTAINER_ID), targetNameCache);
-    }
-    
-    /**
-     * Generates an array of {@link IClasspathEntry} from a set of paths.
-     * @see #getTargetPaths(IAndroidTarget)
-     */
-    private static IClasspathEntry[] createClasspathEntriesFromPaths(String[] paths) {
-        ArrayList<IClasspathEntry> list = new ArrayList<IClasspathEntry>();
-        
-        // First, we create the IClasspathEntry for the framework.
-        // now add the android framework to the class path.
-        // create the path object.
-        IPath android_lib = new Path(paths[CACHE_INDEX_JAR]);
-        IPath android_src = new Path(paths[CACHE_INDEX_SRC]);
-
-        // create the java doc link.
-        IClasspathAttribute cpAttribute = JavaCore.newClasspathAttribute(
-                IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME,
-                paths[CACHE_INDEX_DOCS_URI]);
-        
-        // create the access rule to restrict access to classes in com.android.internal
-        IAccessRule accessRule = JavaCore.newAccessRule(
-                new Path("com/android/internal/**"), //$NON-NLS-1$
-                IAccessRule.K_NON_ACCESSIBLE);
-
-        IClasspathEntry frameworkClasspathEntry = JavaCore.newLibraryEntry(android_lib,
-                android_src, // source attachment path
-                null,        // default source attachment root path.
-                new IAccessRule[] { accessRule },
-                new IClasspathAttribute[] { cpAttribute },
-                false // not exported.
-                );
-
-        list.add(frameworkClasspathEntry);
-        
-        // now deal with optional libraries
-        if (paths.length >= 5) {
-            String docPath = paths[CACHE_INDEX_OPT_DOCS_URI];
-            int i = 4;
-            while (i < paths.length) {
-                Path jarPath = new Path(paths[i++]);
-
-                IClasspathAttribute[] attributes = null;
-                if (docPath.length() > 0) {
-                    attributes = new IClasspathAttribute[] {
-                            JavaCore.newClasspathAttribute(
-                                    IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME,
-                                    docPath)
-                    };
-                }
-    
-                IClasspathEntry entry = JavaCore.newLibraryEntry(
-                        jarPath,
-                        null, // source attachment path
-                        null, // default source attachment root path.
-                        null,
-                        attributes,
-                        false // not exported.
-                        );
-                list.add(entry);
-            }
-        }
-        
-        return list.toArray(new IClasspathEntry[list.size()]);
-    }
-
-    /**
-     * Checks the projects' caches. If the cache was valid, the project is removed from the list.
-     * @param projects the list of projects to check.
-     */
-    public static void checkProjectsCache(ArrayList<IJavaProject> projects) {
-        int i = 0;
-        projectLoop: while (i < projects.size()) {
-            IJavaProject javaProject = projects.get(i);
-            IProject iProject = javaProject.getProject();
-            
-            // check if the project is opened
-            if (iProject.isOpen() == false) {
-                // remove from the list
-                // we do not increment i in this case.
-                projects.remove(i);
-
-                continue;
-            }
-
-            // get the target from the project and its paths
-            IAndroidTarget target = Sdk.getCurrent().getTarget(javaProject.getProject());
-            if (target == null) {
-                // this is really not supposed to happen. This would mean there are cached paths,
-                // but default.properties was deleted. Keep the project in the list to force
-                // a resolve which will display the error.
-                i++;
-                continue;
-            }
-            
-            String[] targetPaths = getTargetPaths(target);
-            
-            // now get the cached paths
-            String cache = ProjectHelper.loadStringProperty(iProject, PROPERTY_CONTAINER_CACHE);
-            if (cache == null) {
-                // this should not happen. We'll force resolve again anyway.
-                i++;
-                continue;
-            }
-            
-            String[] cachedPaths = cache.split(Pattern.quote(PATH_SEPARATOR));
-            if (cachedPaths.length < 3 || cachedPaths.length == 4) {
-                // paths length is wrong. simply resolve the project again
-                i++;
-                continue;
-            }
-            
-            // Now we compare the paths. The first 4 can be compared directly.
-            // because of case sensitiveness we need to use File objects
-            
-            if (targetPaths.length != cachedPaths.length) {
-                // different paths, force resolve again.
-                i++;
-                continue;
-            }
-            
-            // compare the main paths (android.jar, main sources, main javadoc)
-            if (new File(targetPaths[CACHE_INDEX_JAR]).equals(
-                            new File(cachedPaths[CACHE_INDEX_JAR])) == false ||
-                    new File(targetPaths[CACHE_INDEX_SRC]).equals(
-                            new File(cachedPaths[CACHE_INDEX_SRC])) == false ||
-                    new File(targetPaths[CACHE_INDEX_DOCS_URI]).equals(
-                            new File(cachedPaths[CACHE_INDEX_DOCS_URI])) == false) {
-                // different paths, force resolve again.
-                i++;
-                continue;
-            }
-            
-            if (cachedPaths.length > CACHE_INDEX_OPT_DOCS_URI) {
-                // compare optional libraries javadoc
-                if (new File(targetPaths[CACHE_INDEX_OPT_DOCS_URI]).equals(
-                        new File(cachedPaths[CACHE_INDEX_OPT_DOCS_URI])) == false) {
-                    // different paths, force resolve again.
-                    i++;
-                    continue;
-                }
-                
-                // testing the optional jar files is a little bit trickier.
-                // The order is not guaranteed to be identical.
-                // From a previous test, we do know however that there is the same number.
-                // The number of libraries should be low enough that we can simply go through the
-                // lists manually.
-                targetLoop: for (int tpi = 4 ; tpi < targetPaths.length; tpi++) {
-                    String targetPath = targetPaths[tpi];
-                    
-                    // look for a match in the other array
-                    for (int cpi = 4 ; cpi < cachedPaths.length; cpi++) {
-                        if (new File(targetPath).equals(new File(cachedPaths[cpi]))) {
-                            // found a match. Try the next targetPath
-                            continue targetLoop;
-                        }
-                    }
-                    
-                    // if we stop here, we haven't found a match, which means there's a
-                    // discrepancy in the libraries. We force a resolve.
-                    i++;
-                    continue projectLoop;
-                }
-            }
-
-            // at the point the check passes, and we can remove the project from the list.
-            // we do not increment i in this case.
-            projects.remove(i);
-        }
-    }
-    
-    /**
-     * Returns the paths necessary to create the {@link IClasspathEntry} for this targets.
-     * <p/>The paths are always in the same order.
-     * <ul>
-     * <li>Path to android.jar</li>
-     * <li>Path to the source code for android.jar</li>
-     * <li>Path to the javadoc for the android platform</li>
-     * </ul>
-     * Additionally, if there are optional libraries, the array will contain:
-     * <ul>
-     * <li>Path to the librairies javadoc</li>
-     * <li>Path to the first .jar file</li>
-     * <li>(more .jar as needed)</li>
-     * </ul>
-     */
-    private static String[] getTargetPaths(IAndroidTarget target) {
-        ArrayList<String> paths = new ArrayList<String>();
-        
-        // first, we get the path for android.jar
-        // The order is: android.jar, source folder, docs folder
-        paths.add(target.getPath(IAndroidTarget.ANDROID_JAR));
-        paths.add(target.getPath(IAndroidTarget.SOURCES));
-        paths.add(AdtPlugin.getUrlDoc());
-        
-        // now deal with optional libraries.
-        IOptionalLibrary[] libraries = target.getOptionalLibraries();
-        if (libraries != null) {
-            // all the optional libraries use the same javadoc, so we start with this
-            String targetDocPath = target.getPath(IAndroidTarget.DOCS);
-            if (targetDocPath != null) {
-                paths.add(ProjectHelper.getJavaDocPath(targetDocPath));
-            } else {
-                // we add an empty string, to always have the same count.
-                paths.add("");
-            }
-            
-            // because different libraries could use the same jar file, we make sure we add
-            // each jar file only once.
-            HashSet<String> visitedJars = new HashSet<String>();
-            for (IOptionalLibrary library : libraries) {
-                String jarPath = library.getJarPath();
-                if (visitedJars.contains(jarPath) == false) {
-                    visitedJars.add(jarPath);
-                    paths.add(jarPath);
-                }
-            }
-        }
-
-        return paths.toArray(new String[paths.size()]);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestParser.java
deleted file mode 100644
index f03749c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestParser.java
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.xml.AndroidManifest;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IJavaProject;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-public class AndroidManifestParser {
-
-    private final static int LEVEL_MANIFEST = 0;
-    private final static int LEVEL_APPLICATION = 1;
-    private final static int LEVEL_ACTIVITY = 2;
-    private final static int LEVEL_INTENT_FILTER = 3;
-    private final static int LEVEL_CATEGORY = 4;
-
-    private final static String ACTION_MAIN = "android.intent.action.MAIN"; //$NON-NLS-1$
-    private final static String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; //$NON-NLS-1$
-
-    /**
-     * Instrumentation info obtained from manifest
-     */
-    public static class Instrumentation {
-        private final String mName;
-        private final String mTargetPackage;
-
-        Instrumentation(String name, String targetPackage) {
-            mName = name;
-            mTargetPackage = targetPackage;
-        }
-
-        /**
-         * Returns the fully qualified instrumentation class name
-         */
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Returns the Android app package that is the target of this instrumentation
-         */
-        public String getTargetPackage() {
-            return mTargetPackage;
-        }
-    }
-
-    /**
-     * Activity info obtained from the manifest.
-     */
-    public static class Activity {
-        private final String mName;
-        private final boolean mIsExported;
-        private boolean mHasAction = false;
-        private boolean mHasMainAction = false;
-        private boolean mHasLauncherCategory = false;
-
-        public Activity(String name, boolean exported) {
-            mName = name;
-            mIsExported = exported;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public boolean isExported() {
-            return mIsExported;
-        }
-
-        public boolean hasAction() {
-            return mHasAction;
-        }
-
-        public boolean isHomeActivity() {
-            return mHasMainAction && mHasLauncherCategory;
-        }
-
-        void setHasAction(boolean hasAction) {
-            mHasAction = hasAction;
-        }
-
-        /** If the activity doesn't yet have a filter set for the launcher, this resets both
-         * flags. This is to handle multiple intent-filters where one could have the valid
-         * action, and another one of the valid category.
-         */
-        void resetIntentFilter() {
-            if (isHomeActivity() == false) {
-                mHasMainAction = mHasLauncherCategory = false;
-            }
-        }
-
-        void setHasMainAction(boolean hasMainAction) {
-            mHasMainAction = hasMainAction;
-        }
-
-        void setHasLauncherCategory(boolean hasLauncherCategory) {
-            mHasLauncherCategory = hasLauncherCategory;
-        }
-    }
-
-    /**
-     * XML error & data handler used when parsing the AndroidManifest.xml file.
-     * <p/>
-     * This serves both as an {@link XmlErrorHandler} to report errors and as a data repository
-     * to collect data from the manifest.
-     */
-    private static class ManifestHandler extends XmlErrorHandler {
-
-        //--- data read from the parsing
-
-        /** Application package */
-        private String mPackage;
-        /** List of all activities */
-        private final ArrayList<Activity> mActivities = new ArrayList<Activity>();
-        /** Launcher activity */
-        private Activity mLauncherActivity = null;
-        /** list of process names declared by the manifest */
-        private Set<String> mProcesses = null;
-        /** debuggable attribute value. If null, the attribute is not present. */
-        private Boolean mDebuggable = null;
-        /** API level requirement. if null the attribute was not present. */
-        private String mApiLevelRequirement = null;
-        /** List of all instrumentations declared by the manifest */
-        private final ArrayList<Instrumentation> mInstrumentations =
-            new ArrayList<Instrumentation>();
-        /** List of all libraries in use declared by the manifest */
-        private final ArrayList<String> mLibraries = new ArrayList<String>();
-
-        //--- temporary data/flags used during parsing
-        private IJavaProject mJavaProject;
-        private boolean mGatherData = false;
-        private boolean mMarkErrors = false;
-        private int mCurrentLevel = 0;
-        private int mValidLevel = 0;
-        private Activity mCurrentActivity = null;
-        private Locator mLocator;
-
-        /**
-         * Creates a new {@link ManifestHandler}, which is also an {@link XmlErrorHandler}.
-         *
-         * @param manifestFile The manifest file being parsed. Can be null.
-         * @param errorListener An optional error listener.
-         * @param gatherData True if data should be gathered.
-         * @param javaProject The java project holding the manifest file. Can be null.
-         * @param markErrors True if errors should be marked as Eclipse Markers on the resource.
-         */
-        ManifestHandler(IFile manifestFile, XmlErrorListener errorListener,
-                boolean gatherData, IJavaProject javaProject, boolean markErrors) {
-            super(manifestFile, errorListener);
-            mGatherData = gatherData;
-            mJavaProject = javaProject;
-            mMarkErrors = markErrors;
-        }
-
-        /**
-         * Returns the package defined in the manifest, if found.
-         * @return The package name or null if not found.
-         */
-        String getPackage() {
-            return mPackage;
-        }
-
-        /**
-         * Returns the list of activities found in the manifest.
-         * @return An array of fully qualified class names, or empty if no activity were found.
-         */
-        Activity[] getActivities() {
-            return mActivities.toArray(new Activity[mActivities.size()]);
-        }
-
-        /**
-         * Returns the name of one activity found in the manifest, that is configured to show
-         * up in the HOME screen.
-         * @return the fully qualified name of a HOME activity or null if none were found.
-         */
-        Activity getLauncherActivity() {
-            return mLauncherActivity;
-        }
-
-        /**
-         * Returns the list of process names declared by the manifest.
-         */
-        String[] getProcesses() {
-            if (mProcesses != null) {
-                return mProcesses.toArray(new String[mProcesses.size()]);
-            }
-
-            return new String[0];
-        }
-
-        /**
-         * Returns the <code>debuggable</code> attribute value or null if it is not set.
-         */
-        Boolean getDebuggable() {
-            return mDebuggable;
-        }
-
-        /**
-         * Returns the <code>minSdkVersion</code> attribute, or null if it's not set.
-         */
-        String getApiLevelRequirement() {
-            return mApiLevelRequirement;
-        }
-
-        /**
-         * Returns the list of instrumentations found in the manifest.
-         * @return An array of {@link Instrumentation}, or empty if no instrumentations were
-         * found.
-         */
-        Instrumentation[] getInstrumentations() {
-            return mInstrumentations.toArray(new Instrumentation[mInstrumentations.size()]);
-        }
-
-        /**
-         * Returns the list of libraries in use found in the manifest.
-         * @return An array of library names, or empty if no libraries were found.
-         */
-        String[] getUsesLibraries() {
-            return mLibraries.toArray(new String[mLibraries.size()]);
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
-         */
-        @Override
-        public void setDocumentLocator(Locator locator) {
-            mLocator = locator;
-            super.setDocumentLocator(locator);
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String,
-         * java.lang.String, org.xml.sax.Attributes)
-         */
-        @Override
-        public void startElement(String uri, String localName, String name, Attributes attributes)
-                throws SAXException {
-            try {
-                if (mGatherData == false) {
-                    return;
-                }
-
-                // if we're at a valid level
-                if (mValidLevel == mCurrentLevel) {
-                    String value;
-                    switch (mValidLevel) {
-                        case LEVEL_MANIFEST:
-                            if (AndroidManifest.NODE_MANIFEST.equals(localName)) {
-                                // lets get the package name.
-                                mPackage = getAttributeValue(attributes,
-                                        AndroidManifest.ATTRIBUTE_PACKAGE,
-                                        false /* hasNamespace */);
-                                mValidLevel++;
-                            }
-                            break;
-                        case LEVEL_APPLICATION:
-                            if (AndroidManifest.NODE_APPLICATION.equals(localName)) {
-                                value = getAttributeValue(attributes,
-                                        AndroidManifest.ATTRIBUTE_PROCESS,
-                                        true /* hasNamespace */);
-                                if (value != null) {
-                                    addProcessName(value);
-                                }
-
-                                value = getAttributeValue(attributes,
-                                        AndroidManifest.ATTRIBUTE_DEBUGGABLE,
-                                        true /* hasNamespace*/);
-                                if (value != null) {
-                                    mDebuggable = Boolean.parseBoolean(value);
-                                }
-
-                                mValidLevel++;
-                            } else if (AndroidManifest.NODE_USES_SDK.equals(localName)) {
-                                mApiLevelRequirement = getAttributeValue(attributes,
-                                        AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
-                                        true /* hasNamespace */);
-                            } else if (AndroidManifest.NODE_INSTRUMENTATION.equals(localName)) {
-                                processInstrumentationNode(attributes);
-                            }
-                            break;
-                        case LEVEL_ACTIVITY:
-                            if (AndroidManifest.NODE_ACTIVITY.equals(localName)) {
-                                processActivityNode(attributes);
-                                mValidLevel++;
-                            } else if (AndroidManifest.NODE_SERVICE.equals(localName)) {
-                                processNode(attributes, AndroidConstants.CLASS_SERVICE);
-                                mValidLevel++;
-                            } else if (AndroidManifest.NODE_RECEIVER.equals(localName)) {
-                                processNode(attributes, AndroidConstants.CLASS_BROADCASTRECEIVER);
-                                mValidLevel++;
-                            } else if (AndroidManifest.NODE_PROVIDER.equals(localName)) {
-                                processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
-                                mValidLevel++;
-                            } else if (AndroidManifest.NODE_USES_LIBRARY.equals(localName)) {
-                                value = getAttributeValue(attributes,
-                                        AndroidManifest.ATTRIBUTE_NAME,
-                                        true /* hasNamespace */);
-                                if (value != null) {
-                                    mLibraries.add(value);
-                                }
-                            }
-                            break;
-                        case LEVEL_INTENT_FILTER:
-                            // only process this level if we are in an activity
-                            if (mCurrentActivity != null &&
-                                    AndroidManifest.NODE_INTENT.equals(localName)) {
-                                mCurrentActivity.resetIntentFilter();
-                                mValidLevel++;
-                            }
-                            break;
-                        case LEVEL_CATEGORY:
-                            if (mCurrentActivity != null) {
-                                if (AndroidManifest.NODE_ACTION.equals(localName)) {
-                                    // get the name attribute
-                                    String action = getAttributeValue(attributes,
-                                            AndroidManifest.ATTRIBUTE_NAME,
-                                            true /* hasNamespace */);
-                                    if (action != null) {
-                                        mCurrentActivity.setHasAction(true);
-                                        mCurrentActivity.setHasMainAction(
-                                                ACTION_MAIN.equals(action));
-                                    }
-                                } else if (AndroidManifest.NODE_CATEGORY.equals(localName)) {
-                                    String category = getAttributeValue(attributes,
-                                            AndroidManifest.ATTRIBUTE_NAME,
-                                            true /* hasNamespace */);
-                                    if (CATEGORY_LAUNCHER.equals(category)) {
-                                        mCurrentActivity.setHasLauncherCategory(true);
-                                    }
-                                }
-
-                                // no need to increase mValidLevel as we don't process anything
-                                // below this level.
-                            }
-                            break;
-                    }
-                }
-
-                mCurrentLevel++;
-            } finally {
-                super.startElement(uri, localName, name, attributes);
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String,
-         * java.lang.String)
-         */
-        @Override
-        public void endElement(String uri, String localName, String name) throws SAXException {
-            try {
-                if (mGatherData == false) {
-                    return;
-                }
-
-                // decrement the levels.
-                if (mValidLevel == mCurrentLevel) {
-                    mValidLevel--;
-                }
-                mCurrentLevel--;
-
-                // if we're at a valid level
-                // process the end of the element
-                if (mValidLevel == mCurrentLevel) {
-                    switch (mValidLevel) {
-                        case LEVEL_ACTIVITY:
-                            mCurrentActivity = null;
-                            break;
-                        case LEVEL_INTENT_FILTER:
-                            // if we found both a main action and a launcher category, this is our
-                            // launcher activity!
-                            if (mLauncherActivity == null &&
-                                    mCurrentActivity != null &&
-                                    mCurrentActivity.isHomeActivity() &&
-                                    mCurrentActivity.isExported()) {
-                                mLauncherActivity = mCurrentActivity;
-                            }
-                            break;
-                        default:
-                            break;
-                    }
-
-                }
-            } finally {
-                super.endElement(uri, localName, name);
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
-         */
-        @Override
-        public void error(SAXParseException e) {
-            if (mMarkErrors) {
-                handleError(e, e.getLineNumber());
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
-         */
-        @Override
-        public void fatalError(SAXParseException e) {
-            if (mMarkErrors) {
-                handleError(e, e.getLineNumber());
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
-         */
-        @Override
-        public void warning(SAXParseException e) throws SAXException {
-            if (mMarkErrors) {
-                super.warning(e);
-            }
-        }
-
-        /**
-         * Processes the activity node.
-         * @param attributes the attributes for the activity node.
-         */
-        private void processActivityNode(Attributes attributes) {
-            // lets get the activity name, and add it to the list
-            String activityName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_NAME,
-                    true /* hasNamespace */);
-            if (activityName != null) {
-                activityName = AndroidManifest.combinePackageAndClassName(mPackage, activityName);
-
-                // get the exported flag.
-                String exportedStr = getAttributeValue(attributes,
-                        AndroidManifest.ATTRIBUTE_EXPORTED, true);
-                boolean exported = exportedStr == null ||
-                        exportedStr.toLowerCase().equals("true"); // $NON-NLS-1$
-                mCurrentActivity = new Activity(activityName, exported);
-                mActivities.add(mCurrentActivity);
-
-                if (mMarkErrors) {
-                    checkClass(activityName, AndroidConstants.CLASS_ACTIVITY,
-                            true /* testVisibility */);
-                }
-            } else {
-                // no activity found! Aapt will output an error,
-                // so we don't have to do anything
-                mCurrentActivity = null;
-            }
-
-            String processName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_PROCESS,
-                    true /* hasNamespace */);
-            if (processName != null) {
-                addProcessName(processName);
-            }
-        }
-
-        /**
-         * Processes the service/receiver/provider nodes.
-         * @param attributes the attributes for the activity node.
-         * @param superClassName the fully qualified name of the super class that this
-         * node is representing
-         */
-        private void processNode(Attributes attributes, String superClassName) {
-            // lets get the class name, and check it if required.
-            String serviceName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_NAME,
-                    true /* hasNamespace */);
-            if (serviceName != null) {
-                serviceName = AndroidManifest.combinePackageAndClassName(mPackage, serviceName);
-
-                if (mMarkErrors) {
-                    checkClass(serviceName, superClassName, false /* testVisibility */);
-                }
-            }
-
-            String processName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_PROCESS,
-                    true /* hasNamespace */);
-            if (processName != null) {
-                addProcessName(processName);
-            }
-        }
-
-        /**
-         * Processes the instrumentation nodes.
-         * @param attributes the attributes for the activity node.
-         * node is representing
-         */
-        private void processInstrumentationNode(Attributes attributes) {
-            // lets get the class name, and check it if required.
-            String instrumentationName = getAttributeValue(attributes,
-                    AndroidManifest.ATTRIBUTE_NAME,
-                    true /* hasNamespace */);
-            if (instrumentationName != null) {
-                String instrClassName = AndroidManifest.combinePackageAndClassName(mPackage,
-                        instrumentationName);
-                String targetPackage = getAttributeValue(attributes,
-                        AndroidManifest.ATTRIBUTE_TARGET_PACKAGE,
-                        true /* hasNamespace */);
-                mInstrumentations.add(new Instrumentation(instrClassName, targetPackage));
-                if (mMarkErrors) {
-                    checkClass(instrClassName, AndroidConstants.CLASS_INSTRUMENTATION,
-                            true /* testVisibility */);
-                }
-            }
-        }
-
-        /**
-         * Checks that a class is valid and can be used in the Android Manifest.
-         * <p/>
-         * Errors are put as {@link IMarker} on the manifest file.
-         * @param className the fully qualified name of the class to test.
-         * @param superClassName the fully qualified name of the class it is supposed to extend.
-         * @param testVisibility if <code>true</code>, the method will check the visibility of
-         * the class or of its constructors.
-         */
-        private void checkClass(String className, String superClassName, boolean testVisibility) {
-            if (mJavaProject == null) {
-                return;
-            }
-            // we need to check the validity of the activity.
-            String result = BaseProjectHelper.testClassForManifest(mJavaProject,
-                    className, superClassName, testVisibility);
-            if (result != BaseProjectHelper.TEST_CLASS_OK) {
-                // get the line number
-                int line = mLocator.getLineNumber();
-
-                // mark the file
-                IMarker marker = BaseProjectHelper.addMarker(getFile(),
-                        AndroidConstants.MARKER_ANDROID,
-                        result, line, IMarker.SEVERITY_ERROR);
-
-                // add custom attributes to be used by the manifest editor.
-                if (marker != null) {
-                    try {
-                        marker.setAttribute(AndroidConstants.MARKER_ATTR_TYPE,
-                                AndroidConstants.MARKER_ATTR_TYPE_ACTIVITY);
-                        marker.setAttribute(AndroidConstants.MARKER_ATTR_CLASS, className);
-                    } catch (CoreException e) {
-                    }
-                }
-            }
-        }
-
-        /**
-         * Searches through the attributes list for a particular one and returns its value.
-         * @param attributes the attribute list to search through
-         * @param attributeName the name of the attribute to look for.
-         * @param hasNamespace Indicates whether the attribute has an android namespace.
-         * @return a String with the value or null if the attribute was not found.
-         * @see SdkConstants#NS_RESOURCES
-         */
-        private String getAttributeValue(Attributes attributes, String attributeName,
-                boolean hasNamespace) {
-            int count = attributes.getLength();
-            for (int i = 0 ; i < count ; i++) {
-                if (attributeName.equals(attributes.getLocalName(i)) &&
-                        ((hasNamespace &&
-                                SdkConstants.NS_RESOURCES.equals(attributes.getURI(i))) ||
-                                (hasNamespace == false && attributes.getURI(i).length() == 0))) {
-                    return attributes.getValue(i);
-                }
-            }
-
-            return null;
-        }
-
-        private void addProcessName(String processName) {
-            if (mProcesses == null) {
-                mProcesses = new TreeSet<String>();
-            }
-
-            mProcesses.add(processName);
-        }
-    }
-
-    private static SAXParserFactory sParserFactory;
-
-    private final String mJavaPackage;
-    private final Activity[] mActivities;
-    private final Activity mLauncherActivity;
-    private final String[] mProcesses;
-    private final Boolean mDebuggable;
-    private final String mApiLevelRequirement;
-    private final Instrumentation[] mInstrumentations;
-    private final String[] mLibraries;
-
-    static {
-        sParserFactory = SAXParserFactory.newInstance();
-        sParserFactory.setNamespaceAware(true);
-    }
-
-    /**
-     * Parses the Android Manifest, and returns an object containing the result of the parsing.
-     * <p/>
-     * This method is useful to parse a specific {@link IFile} in a Java project.
-     * <p/>
-     * If you only want to gather data, consider {@link #parseForData(IFile)} instead.
-     *
-     * @param javaProject The java project.
-     * @param manifestFile the {@link IFile} representing the manifest file.
-     * @param errorListener
-     * @param gatherData indicates whether the parsing will extract data from the manifest.
-     * @param markErrors indicates whether the error found during parsing should put a
-     * marker on the file. For class validation errors to put a marker, <code>gatherData</code>
-     * must be set to <code>true</code>
-     * @return an {@link AndroidManifestParser} or null if the parsing failed.
-     * @throws CoreException
-     */
-    public static AndroidManifestParser parse(
-                IJavaProject javaProject,
-                IFile manifestFile,
-                XmlErrorListener errorListener,
-                boolean gatherData,
-                boolean markErrors)
-            throws CoreException {
-        try {
-            if (manifestFile != null) {
-                SAXParser parser = sParserFactory.newSAXParser();
-
-                ManifestHandler manifestHandler = new ManifestHandler(manifestFile,
-                        errorListener, gatherData, javaProject, markErrors);
-                parser.parse(new InputSource(manifestFile.getContents()), manifestHandler);
-
-                // get the result from the handler
-                return new AndroidManifestParser(manifestHandler.getPackage(),
-                        manifestHandler.getActivities(),
-                        manifestHandler.getLauncherActivity(),
-                        manifestHandler.getProcesses(),
-                        manifestHandler.getDebuggable(),
-                        manifestHandler.getApiLevelRequirement(),
-                        manifestHandler.getInstrumentations(),
-                        manifestHandler.getUsesLibraries());
-            }
-        } catch (ParserConfigurationException e) {
-            AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                    "Bad parser configuration for %s: %s",
-                    manifestFile.getFullPath(),
-                    e.getMessage());
-        } catch (SAXException e) {
-            AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                    "Parser exception for %s: %s",
-                    manifestFile.getFullPath(),
-                    e.getMessage());
-        } catch (IOException e) {
-            // Don't log a console error when failing to read a non-existing file
-            if (!(e instanceof FileNotFoundException)) {
-                AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                        "I/O error for %s: %s",
-                        manifestFile.getFullPath(),
-                        e.getMessage());
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Parses the Android Manifest, and returns an object containing the result of the parsing.
-     * <p/>
-     * This version parses a real {@link File} file given by an actual path, which is useful for
-     * parsing a file that is not part of an Eclipse Java project.
-     * <p/>
-     * It assumes errors cannot be marked on the file and that data gathering is enabled.
-     *
-     * @param manifestFile the manifest file to parse.
-     * @return an {@link AndroidManifestParser} or null if the parsing failed.
-     * @throws CoreException
-     */
-    private static AndroidManifestParser parse(File manifestFile)
-            throws CoreException {
-        try {
-            SAXParser parser = sParserFactory.newSAXParser();
-
-            ManifestHandler manifestHandler = new ManifestHandler(
-                    null, //manifestFile
-                    null, //errorListener
-                    true, //gatherData
-                    null, //javaProject
-                    false //markErrors
-                    );
-
-            parser.parse(new InputSource(new FileReader(manifestFile)), manifestHandler);
-
-            // get the result from the handler
-
-            return new AndroidManifestParser(manifestHandler.getPackage(),
-                    manifestHandler.getActivities(),
-                    manifestHandler.getLauncherActivity(),
-                    manifestHandler.getProcesses(),
-                    manifestHandler.getDebuggable(),
-                    manifestHandler.getApiLevelRequirement(),
-                    manifestHandler.getInstrumentations(),
-                    manifestHandler.getUsesLibraries());
-        } catch (ParserConfigurationException e) {
-            AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                    "Bad parser configuration for %s: %s",
-                    manifestFile.getAbsolutePath(),
-                    e.getMessage());
-        } catch (SAXException e) {
-            AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                    "Parser exception for %s: %s",
-                    manifestFile.getAbsolutePath(),
-                    e.getMessage());
-        } catch (IOException e) {
-            // Don't log a console error when failing to read a non-existing file
-            if (!(e instanceof FileNotFoundException)) {
-                AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                        "I/O error for %s: %s",
-                        manifestFile.getAbsolutePath(),
-                        e.getMessage());
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Parses the Android Manifest for the specified project, and returns an object containing
-     * the result of the parsing.
-     * @param javaProject The java project. Required if <var>markErrors</var> is <code>true</code>
-     * @param errorListener the {@link XmlErrorListener} object being notified of the presence
-     * of errors. Optional.
-     * @param gatherData indicates whether the parsing will extract data from the manifest.
-     * @param markErrors indicates whether the error found during parsing should put a
-     * marker on the file. For class validation errors to put a marker, <code>gatherData</code>
-     * must be set to <code>true</code>
-     * @return an {@link AndroidManifestParser} or null if the parsing failed.
-     * @throws CoreException
-     */
-    public static AndroidManifestParser parse(
-                IJavaProject javaProject,
-                XmlErrorListener errorListener,
-                boolean gatherData,
-                boolean markErrors)
-            throws CoreException {
-
-        IFile manifestFile = getManifest(javaProject.getProject());
-
-        try {
-            SAXParser parser = sParserFactory.newSAXParser();
-
-            if (manifestFile != null) {
-                ManifestHandler manifestHandler = new ManifestHandler(manifestFile,
-                        errorListener, gatherData, javaProject, markErrors);
-
-                parser.parse(new InputSource(manifestFile.getContents()), manifestHandler);
-
-                // get the result from the handler
-                return new AndroidManifestParser(manifestHandler.getPackage(),
-                        manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
-                        manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
-                        manifestHandler.getApiLevelRequirement(),
-                        manifestHandler.getInstrumentations(), manifestHandler.getUsesLibraries());
-            }
-        } catch (ParserConfigurationException e) {
-            AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                    "Bad parser configuration for %s", manifestFile.getFullPath());
-        } catch (SAXException e) {
-            AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                    "Parser exception for %s", manifestFile.getFullPath());
-        } catch (IOException e) {
-            AdtPlugin.logAndPrintError(e, AndroidManifestParser.class.getCanonicalName(),
-                    "I/O error for %s", manifestFile.getFullPath());
-        }
-
-        return null;
-    }
-
-    /**
-     * Parses the manifest file, collects data, and checks for errors.
-     * @param javaProject The java project. Required.
-     * @param manifestFile The manifest file to parse.
-     * @param errorListener the {@link XmlErrorListener} object being notified of the presence
-     * of errors. Optional.
-     * @return an {@link AndroidManifestParser} or null if the parsing failed.
-     * @throws CoreException
-     */
-    public static AndroidManifestParser parseForError(IJavaProject javaProject, IFile manifestFile,
-            XmlErrorListener errorListener) throws CoreException {
-        return parse(javaProject, manifestFile, errorListener, true, true);
-    }
-
-    /**
-     * Parses the manifest file, and collects data.
-     * @param manifestFile The manifest file to parse.
-     * @return an {@link AndroidManifestParser} or null if the parsing failed.
-     * @throws CoreException for example the file does not exist in the workspace or
-     *         the workspace needs to be refreshed.
-     */
-    public static AndroidManifestParser parseForData(IFile manifestFile) throws CoreException {
-        return parse(null /* javaProject */, manifestFile, null /* errorListener */,
-                true /* gatherData */, false /* markErrors */);
-    }
-
-    /**
-     * Parses the manifest file, and collects data.
-     *
-     * @param osManifestFilePath The OS path of the manifest file to parse.
-     * @return an {@link AndroidManifestParser} or null if the parsing failed.
-     */
-    public static AndroidManifestParser parseForData(String osManifestFilePath) {
-        try {
-            return parse(new File(osManifestFilePath));
-        } catch (CoreException e) {
-            // Ignore workspace errors (unlikely to happen since this parses an actual file,
-            // not a workspace resource).
-            return null;
-        }
-    }
-
-    /**
-     * Returns the package defined in the manifest, if found.
-     * @return The package name or null if not found.
-     */
-    public String getPackage() {
-        return mJavaPackage;
-    }
-
-    /**
-     * Returns the list of activities found in the manifest.
-     * @return An array of {@link Activity}, or empty if no activity were found.
-     */
-    public Activity[] getActivities() {
-        return mActivities;
-    }
-
-    /**
-     * Returns the name of one activity found in the manifest, that is configured to show
-     * up in the HOME screen.
-     * @return The {@link Activity} representing a HOME activity or null if none were found.
-     */
-    public Activity getLauncherActivity() {
-        return mLauncherActivity;
-    }
-
-    /**
-     * Returns the list of process names declared by the manifest.
-     */
-    public String[] getProcesses() {
-        return mProcesses;
-    }
-
-    /**
-     * Returns the debuggable attribute value or <code>null</code> if it is not set.
-     */
-    public Boolean getDebuggable() {
-        return mDebuggable;
-    }
-
-    /**
-     * Returns the <code>minSdkVersion</code> attribute, or null if it's not set.
-     */
-    public String getApiLevelRequirement() {
-        return mApiLevelRequirement;
-    }
-
-    /**
-     * Returns the list of instrumentations found in the manifest.
-     * @return An array of {@link Instrumentation}, or empty if no instrumentations were found.
-     */
-    public Instrumentation[] getInstrumentations() {
-        return mInstrumentations;
-    }
-
-    /**
-     * Returns the list of libraries in use found in the manifest.
-     * @return An array of library names, or empty if no uses-library declarations were found.
-     */
-    public String[] getUsesLibraries() {
-        return mLibraries;
-    }
-
-
-    /**
-     * Private constructor to enforce using
-     * {@link #parse(IJavaProject, XmlErrorListener, boolean, boolean)},
-     * {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)},
-     * or {@link #parseForError(IJavaProject, IFile, XmlErrorListener)} to get an
-     * {@link AndroidManifestParser} object.
-     * @param javaPackage the package parsed from the manifest.
-     * @param activities the list of activities parsed from the manifest.
-     * @param launcherActivity the launcher activity parser from the manifest.
-     * @param processes the list of custom processes declared in the manifest.
-     * @param debuggable the debuggable attribute, or null if not set.
-     * @param apiLevelRequirement the minSdkVersion attribute value or null if not set.
-     * @param instrumentations the list of instrumentations parsed from the manifest.
-     * @param libraries the list of libraries in use parsed from the manifest.
-     */
-    private AndroidManifestParser(String javaPackage, Activity[] activities,
-            Activity launcherActivity, String[] processes, Boolean debuggable,
-            String apiLevelRequirement, Instrumentation[] instrumentations, String[] libraries) {
-        mJavaPackage = javaPackage;
-        mActivities = activities;
-        mLauncherActivity = launcherActivity;
-        mProcesses = processes;
-        mDebuggable = debuggable;
-        mApiLevelRequirement = apiLevelRequirement;
-        mInstrumentations = instrumentations;
-        mLibraries = libraries;
-    }
-
-    /**
-     * Returns an IFile object representing the manifest for the specified
-     * project.
-     *
-     * @param project The project containing the manifest file.
-     * @return An IFile object pointing to the manifest or null if the manifest
-     *         is missing.
-     */
-    public static IFile getManifest(IProject project) {
-        IResource r = project.findMember(AndroidConstants.WS_SEP
-                + AndroidConstants.FN_ANDROID_MANIFEST);
-
-        if (r == null || r.exists() == false || (r instanceof IFile) == false) {
-            return null;
-        }
-        return (IFile) r;
-    }
-
-    /**
-     * Given a fully qualified activity name (e.g. com.foo.test.MyClass) and given a project
-     * package base name (e.g. com.foo), returns the relative activity name that would be used
-     * the "name" attribute of an "activity" element.
-     *
-     * @param fullActivityName a fully qualified activity class name, e.g. "com.foo.test.MyClass"
-     * @param packageName The project base package name, e.g. "com.foo"
-     * @return The relative activity name if it can be computed or the original fullActivityName.
-     */
-    public static String extractActivityName(String fullActivityName, String packageName) {
-        if (packageName != null && fullActivityName != null) {
-            if (packageName.length() > 0 && fullActivityName.startsWith(packageName)) {
-                String name = fullActivityName.substring(packageName.length());
-                if (name.length() > 0 && name.charAt(0) == '.') {
-                    return name;
-                }
-            }
-        }
-
-        return fullActivityName;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidNature.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidNature.java
deleted file mode 100644
index 70097ae..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidNature.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.build.ApkBuilder;
-import com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder;
-import com.android.ide.eclipse.adt.internal.build.ResourceManagerBuilder;
-
-import org.eclipse.core.resources.ICommand;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IProjectNature;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.JavaCore;
-
-/**
- * Project nature for the Android Projects.
- */
-public class AndroidNature implements IProjectNature {
-
-    /** the project this nature object is associated with */
-    private IProject mProject;
-
-    /**
-     * Configures this nature for its project. This is called by the workspace
-     * when natures are added to the project using
-     * <code>IProject.setDescription</code> and should not be called directly
-     * by clients. The nature extension id is added to the list of natures
-     * before this method is called, and need not be added here.
-     *
-     * Exceptions thrown by this method will be propagated back to the caller of
-     * <code>IProject.setDescription</code>, but the nature will remain in
-     * the project description.
-     *
-     * The Android nature adds the pre-builder and the APK builder if necessary.
-     *
-     * @see org.eclipse.core.resources.IProjectNature#configure()
-     * @throws CoreException if configuration fails.
-     */
-    public void configure() throws CoreException {
-        configureResourceManagerBuilder(mProject);
-        configurePreBuilder(mProject);
-        configureApkBuilder(mProject);
-    }
-
-    /**
-     * De-configures this nature for its project. This is called by the
-     * workspace when natures are removed from the project using
-     * <code>IProject.setDescription</code> and should not be called directly
-     * by clients. The nature extension id is removed from the list of natures
-     * before this method is called, and need not be removed here.
-     *
-     * Exceptions thrown by this method will be propagated back to the caller of
-     * <code>IProject.setDescription</code>, but the nature will still be
-     * removed from the project description.
-     *
-     * The Android nature removes the custom pre builder and APK builder.
-     *
-     * @see org.eclipse.core.resources.IProjectNature#deconfigure()
-     * @throws CoreException if configuration fails.
-     */
-    public void deconfigure() throws CoreException {
-        // remove the android builders
-        removeBuilder(mProject, ResourceManagerBuilder.ID);
-        removeBuilder(mProject, PreCompilerBuilder.ID);
-        removeBuilder(mProject, ApkBuilder.ID);
-    }
-
-    /**
-     * Returns the project to which this project nature applies.
-     *
-     * @return the project handle
-     * @see org.eclipse.core.resources.IProjectNature#getProject()
-     */
-    public IProject getProject() {
-        return mProject;
-    }
-
-    /**
-     * Sets the project to which this nature applies. Used when instantiating
-     * this project nature runtime. This is called by
-     * <code>IProject.create()</code> or
-     * <code>IProject.setDescription()</code> and should not be called
-     * directly by clients.
-     *
-     * @param project the project to which this nature applies
-     * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
-     */
-    public void setProject(IProject project) {
-        mProject = project;
-    }
-
-    /**
-     * Adds the Android Nature and the Java Nature to the project if it doesn't
-     * already have them.
-     *
-     * @param project An existing or new project to update
-     * @param monitor An optional progress monitor. Can be null.
-     * @throws CoreException if fails to change the nature.
-     */
-    public static synchronized void setupProjectNatures(IProject project,
-            IProgressMonitor monitor) throws CoreException {
-        if (project == null || !project.isOpen()) return;
-        if (monitor == null) monitor = new NullProgressMonitor();
-
-        // Add the natures. We need to add the Java nature first, so it adds its builder to the
-        // project first. This way, when the android nature is added, we can control where to put
-        // the android builders in relation to the java builder.
-        // Adding the java nature after the android one, would place the java builder before the
-        // android builders.
-        addNatureToProjectDescription(project, JavaCore.NATURE_ID, monitor);
-        addNatureToProjectDescription(project, AndroidConstants.NATURE, monitor);
-    }
-
-    /**
-     * Add the specified nature to the specified project. The nature is only
-     * added if not already present.
-     * <p/>
-     * Android Natures are always inserted at the beginning of the list of natures in order to
-     * have the jdt views/dialogs display the proper icon.
-     *
-     * @param project The project to modify.
-     * @param natureId The Id of the nature to add.
-     * @param monitor An existing progress monitor.
-     * @throws CoreException if fails to change the nature.
-     */
-    private static void addNatureToProjectDescription(IProject project,
-            String natureId, IProgressMonitor monitor) throws CoreException {
-        if (!project.hasNature(natureId)) {
-
-            IProjectDescription description = project.getDescription();
-            String[] natures = description.getNatureIds();
-            String[] newNatures = new String[natures.length + 1];
-            
-            // Android natures always come first.
-            if (natureId.equals(AndroidConstants.NATURE)) {
-                System.arraycopy(natures, 0, newNatures, 1, natures.length);
-                newNatures[0] = natureId;
-            } else {
-                System.arraycopy(natures, 0, newNatures, 0, natures.length);
-                newNatures[natures.length] = natureId;
-            }
-            
-            description.setNatureIds(newNatures);
-            project.setDescription(description, new SubProgressMonitor(monitor, 10));
-        }
-    }
-
-    /**
-     * Adds the ResourceManagerBuilder, if its not already there. It'll insert
-     * itself as the first builder.
-     * @throws CoreException
-     *
-     */
-    public static void configureResourceManagerBuilder(IProject project)
-            throws CoreException {
-        // get the builder list
-        IProjectDescription desc = project.getDescription();
-        ICommand[] commands = desc.getBuildSpec();
-
-        // look for the builder in case it's already there.
-        for (int i = 0; i < commands.length; ++i) {
-            if (ResourceManagerBuilder.ID.equals(commands[i].getBuilderName())) {
-                return;
-            }
-        }
-
-        // it's not there, lets add it at the beginning of the builders
-        ICommand[] newCommands = new ICommand[commands.length + 1];
-        System.arraycopy(commands, 0, newCommands, 1, commands.length);
-        ICommand command = desc.newCommand();
-        command.setBuilderName(ResourceManagerBuilder.ID);
-        newCommands[0] = command;
-        desc.setBuildSpec(newCommands);
-        project.setDescription(desc, null);
-    }
-
-    /**
-     * Adds the PreCompilerBuilder if its not already there. It'll check for
-     * presence of the ResourceManager and insert itself right after.
-     * @param project
-     * @throws CoreException
-     */
-    public static void configurePreBuilder(IProject project)
-            throws CoreException {
-        // get the builder list
-        IProjectDescription desc = project.getDescription();
-        ICommand[] commands = desc.getBuildSpec();
-
-        // look for the builder in case it's already there.
-        for (int i = 0; i < commands.length; ++i) {
-            if (PreCompilerBuilder.ID.equals(commands[i].getBuilderName())) {
-                return;
-            }
-        }
-
-        // we need to add it after the resource manager builder.
-        // Let's look for it
-        int index = -1;
-        for (int i = 0; i < commands.length; ++i) {
-            if (ResourceManagerBuilder.ID.equals(commands[i].getBuilderName())) {
-                index = i;
-                break;
-            }
-        }
-
-        // we're inserting after
-        index++;
-
-        // do the insertion
-
-        // copy the builders before.
-        ICommand[] newCommands = new ICommand[commands.length + 1];
-        System.arraycopy(commands, 0, newCommands, 0, index);
-
-        // insert the new builder
-        ICommand command = desc.newCommand();
-        command.setBuilderName(PreCompilerBuilder.ID);
-        newCommands[index] = command;
-
-        // copy the builder after
-        System.arraycopy(commands, index, newCommands, index + 1, commands.length-index);
-
-        // set the new builders in the project
-        desc.setBuildSpec(newCommands);
-        project.setDescription(desc, null);
-    }
-
-    public static void configureApkBuilder(IProject project)
-            throws CoreException {
-        // Add the .apk builder at the end if it's not already there
-        IProjectDescription desc = project.getDescription();
-        ICommand[] commands = desc.getBuildSpec();
-
-        for (int i = 0; i < commands.length; ++i) {
-            if (ApkBuilder.ID.equals(commands[i].getBuilderName())) {
-                return;
-            }
-        }
-
-        ICommand[] newCommands = new ICommand[commands.length + 1];
-        System.arraycopy(commands, 0, newCommands, 0, commands.length);
-        ICommand command = desc.newCommand();
-        command.setBuilderName(ApkBuilder.ID);
-        newCommands[commands.length] = command;
-        desc.setBuildSpec(newCommands);
-        project.setDescription(desc, null);
-    }
-
-    /**
-     * Removes a builder from the project.
-     * @param project The project to remove the builder from.
-     * @param id The String ID of the builder to remove.
-     * @return true if the builder was found and removed.
-     * @throws CoreException
-     */
-    public static boolean removeBuilder(IProject project, String id) throws CoreException {
-        IProjectDescription description = project.getDescription();
-        ICommand[] commands = description.getBuildSpec();
-        for (int i = 0; i < commands.length; ++i) {
-            if (id.equals(commands[i].getBuilderName())) {
-                ICommand[] newCommands = new ICommand[commands.length - 1];
-                System.arraycopy(commands, 0, newCommands, 0, i);
-                System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
-                description.setBuildSpec(newCommands);
-                project.setDescription(description, null);
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java
deleted file mode 100644
index f7556c0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IProjectListener;
-
-import org.eclipse.core.resources.IProject;
-
-import java.util.ArrayList;
-
-/**
- * Registers which apk was installed on which device.
- * <p/>
- * The goal of this class is to remember the installation of APKs on devices, and provide
- * information about whether a new APK should be installed on a device prior to running the
- * application from a launch configuration.
- * <p/>
- * The manager uses {@link IProject} and {@link IDevice} to identify the target device and the
- * (project generating the) APK. This ensures that disconnected and reconnected devices will
- * always receive new APKs (since the APK could be uninstalled manually).
- * <p/>
- * Manually uninstalling an APK from a connected device will still be a problem, but this should
- * be a limited use case.
- * <p/>
- * This is a singleton. To get the instance, use {@link #getInstance()}
- */
-public class ApkInstallManager implements IDeviceChangeListener, IDebugBridgeChangeListener,
-        IProjectListener {
-
-    private final static ApkInstallManager sThis = new ApkInstallManager();
-
-    /**
-     * Internal struct to associate a project and a device.
-     */
-    private static class ApkInstall {
-        public ApkInstall(IProject project, IDevice device) {
-            this.project = project;
-            this.device = device;
-        }
-        IProject project;
-        IDevice device;
-    }
-
-    private final ArrayList<ApkInstall> mInstallList = new ArrayList<ApkInstall>();
-
-    public static ApkInstallManager getInstance() {
-        return sThis;
-    }
-
-    /**
-     * Registers an installation of <var>project</var> onto <var>device</var>
-     * @param project The project that was installed.
-     * @param device The device that received the installation.
-     */
-    public void registerInstallation(IProject project, IDevice device) {
-        synchronized (mInstallList) {
-            mInstallList.add(new ApkInstall(project, device));
-        }
-    }
-
-    /**
-     * Returns whether a <var>project</var> was installed on the <var>device</var>.
-     * @param project the project that may have been installed.
-     * @param device the device that may have received the installation.
-     * @return
-     */
-    public boolean isApplicationInstalled(IProject project, IDevice device) {
-        synchronized (mInstallList) {
-            for (ApkInstall install : mInstallList) {
-                if (project == install.project && device == install.device) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Resets registered installations for a specific {@link IProject}.
-     * <p/>This ensures that {@link #isApplicationInstalled(IProject, IDevice)} will always return
-     * <code>null</code> for this specified project, for any device.
-     * @param project the project for which to reset all installations.
-     */
-    public void resetInstallationFor(IProject project) {
-        synchronized (mInstallList) {
-            for (int i = 0 ; i < mInstallList.size() ;) {
-                ApkInstall install = mInstallList.get(i);
-                if (install.project == project) {
-                    mInstallList.remove(i);
-                } else {
-                    i++;
-                }
-            }
-        }
-    }
-
-    private ApkInstallManager() {
-        AndroidDebugBridge.addDeviceChangeListener(this);
-        AndroidDebugBridge.addDebugBridgeChangeListener(this);
-        ResourceMonitor.getMonitor().addProjectListener(this);
-    }
-
-    /*
-     * Responds to a bridge change by clearing the full installation list.
-     * (non-Javadoc)
-     * @see com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener#bridgeChanged(com.android.ddmlib.AndroidDebugBridge)
-     */
-    public void bridgeChanged(AndroidDebugBridge bridge) {
-        // the bridge changed, there is no way to know which IDevice will be which.
-        // We reset everything
-        synchronized (mInstallList) {
-            mInstallList.clear();
-        }
-    }
-
-    /*
-     * Responds to a device being disconnected by removing all installations related to this device.
-     * (non-Javadoc)
-     * @see com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener#deviceDisconnected(com.android.ddmlib.Device)
-     */
-    public void deviceDisconnected(IDevice device) {
-        synchronized (mInstallList) {
-            for (int i = 0 ; i < mInstallList.size() ;) {
-                ApkInstall install = mInstallList.get(i);
-                if (install.device == device) {
-                    mInstallList.remove(i);
-                } else {
-                    i++;
-                }
-            }
-        }
-    }
-
-    /*
-     * Responds to a close project by resetting all its installation.
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectClosed(org.eclipse.core.resources.IProject)
-     */
-    public void projectClosed(IProject project) {
-        resetInstallationFor(project);
-    }
-
-    /*
-     * Responds to a close project by resetting all its installation.
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectDeleted(org.eclipse.core.resources.IProject)
-     */
-    public void projectDeleted(IProject project) {
-        resetInstallationFor(project);
-    }
-
-    /*
-     * Does nothing
-     * (non-Javadoc)
-     * @see com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener#deviceChanged(com.android.ddmlib.Device, int)
-     */
-    public void deviceChanged(IDevice device, int changeMask) {
-        // nothing to do.
-    }
-
-    /*
-     * Does nothing
-     * (non-Javadoc)
-     * @see com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener#deviceConnected(com.android.ddmlib.Device)
-     */
-    public void deviceConnected(IDevice device) {
-        // nothing to do.
-    }
-
-    /*
-     * Does nothing
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectOpened(org.eclipse.core.resources.IProject)
-     */
-    public void projectOpened(IProject project) {
-        // nothing to do.
-    }
-
-    /*
-     * Does nothing
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener#projectOpenedWithWorkspace(org.eclipse.core.resources.IProject)
-     */
-    public void projectOpenedWithWorkspace(IProject project) {
-        // nothing to do.
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
deleted file mode 100644
index ff6cd04..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.Flags;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.ui.JavaUI;
-import org.eclipse.jdt.ui.actions.OpenJavaPerspectiveAction;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-import org.eclipse.ui.texteditor.ITextEditor;
-
-import java.util.ArrayList;
-
-/**
- * Utility methods to manipulate projects.
- */
-public final class BaseProjectHelper {
-
-    public static final String TEST_CLASS_OK = null;
-
-    /**
-     * returns a list of source classpath for a specified project
-     * @param javaProject
-     * @return a list of path relative to the workspace root.
-     */
-    public static ArrayList<IPath> getSourceClasspaths(IJavaProject javaProject) {
-        ArrayList<IPath> sourceList = new ArrayList<IPath>();
-        IClasspathEntry[] classpaths = javaProject.readRawClasspath();
-        if (classpaths != null) {
-            for (IClasspathEntry e : classpaths) {
-                if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
-                    sourceList.add(e.getPath());
-                }
-            }
-        }
-        return sourceList;
-    }
-
-    /**
-     * Adds a marker to a file on a specific line. This methods catches thrown
-     * {@link CoreException}, and returns null instead.
-     * @param file the file to be marked
-     * @param markerId The id of the marker to add.
-     * @param message the message associated with the mark
-     * @param lineNumber the line number where to put the mark. If line is < 1, it puts the marker
-     * on line 1.
-     * @param severity the severity of the marker.
-     * @return the IMarker that was added or null if it failed to add one.
-     */
-    public final static IMarker addMarker(IResource file, String markerId,
-            String message, int lineNumber, int severity) {
-        try {
-            IMarker marker = file.createMarker(markerId);
-            marker.setAttribute(IMarker.MESSAGE, message);
-            marker.setAttribute(IMarker.SEVERITY, severity);
-            if (lineNumber < 1) {
-                lineNumber = 1;
-            }
-            marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
-
-            // on Windows, when adding a marker to a project, it takes a refresh for the marker
-            // to show. In order to fix this we're forcing a refresh of elements receiving
-            // markers (and only the element, not its children), to force the marker display.
-            file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
-
-            return marker;
-        } catch (CoreException e) {
-            AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", //$NON-NLS-1$
-                    markerId, file.getFullPath());
-        }
-        
-        return null;
-    }
-
-    /**
-     * Adds a marker to a resource. This methods catches thrown {@link CoreException},
-     * and returns null instead.
-     * @param resource the file to be marked
-     * @param markerId The id of the marker to add.
-     * @param message the message associated with the mark
-     * @param severity the severity of the marker.
-     * @return the IMarker that was added or null if it failed to add one.
-     */
-    public final static IMarker addMarker(IResource resource, String markerId,
-            String message, int severity) {
-        try {
-            IMarker marker = resource.createMarker(markerId);
-            marker.setAttribute(IMarker.MESSAGE, message);
-            marker.setAttribute(IMarker.SEVERITY, severity);
-
-            // on Windows, when adding a marker to a project, it takes a refresh for the marker
-            // to show. In order to fix this we're forcing a refresh of elements receiving
-            // markers (and only the element, not its children), to force the marker display.
-            resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
-
-            return marker;
-        } catch (CoreException e) {
-            AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", //$NON-NLS-1$
-                    markerId, resource.getFullPath());
-        }
-        
-        return null;
-    }
-
-    /**
-     * Adds a marker to a resource. This method does not catch {@link CoreException} and instead
-     * throw them.
-     * @param resource the file to be marked
-     * @param markerId The id of the marker to add.
-     * @param message the message associated with the mark
-     * @param lineNumber the line number where to put the mark if != -1.
-     * @param severity the severity of the marker.
-     * @param priority the priority of the marker
-     * @return the IMarker that was added.
-     * @throws CoreException 
-     */
-    public final static IMarker addMarker(IResource resource, String markerId,
-            String message, int lineNumber, int severity, int priority) throws CoreException {
-        IMarker marker = resource.createMarker(markerId);
-        marker.setAttribute(IMarker.MESSAGE, message);
-        marker.setAttribute(IMarker.SEVERITY, severity);
-        if (lineNumber != -1) {
-            marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
-        }
-        marker.setAttribute(IMarker.PRIORITY, priority);
-
-        // on Windows, when adding a marker to a project, it takes a refresh for the marker
-        // to show. In order to fix this we're forcing a refresh of elements receiving
-        // markers (and only the element, not its children), to force the marker display.
-        resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
-
-        return marker;
-    }
-
-    /**
-     * Tests that a class name is valid for usage in the manifest.
-     * <p/>
-     * This tests the class existence, that it can be instantiated (ie it must not be abstract,
-     * nor non static if enclosed), and that it extends the proper super class (not necessarily
-     * directly)
-     * @param javaProject the {@link IJavaProject} containing the class.
-     * @param className the fully qualified name of the class to test.
-     * @param superClassName the fully qualified name of the expected super class.
-     * @param testVisibility if <code>true</code>, the method will check the visibility of the class
-     * or of its constructors.
-     * @return {@link #TEST_CLASS_OK} or an error message.
-     */
-    public final static String testClassForManifest(IJavaProject javaProject, String className,
-            String superClassName, boolean testVisibility) {
-        try {
-            // replace $ by .
-            String javaClassName = className.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
-
-            // look for the IType object for this class
-            IType type = javaProject.findType(javaClassName);
-            if (type != null && type.exists()) {
-                // test that the class is not abstract
-                int flags = type.getFlags();
-                if (Flags.isAbstract(flags)) {
-                    return String.format("%1$s is abstract", className);
-                }
-                
-                // test whether the class is public or not.
-                if (testVisibility && Flags.isPublic(flags) == false) {
-                    // if its not public, it may have a public default constructor,
-                    // which would then be fine.
-                    IMethod basicConstructor = type.getMethod(type.getElementName(), new String[0]);
-                    if (basicConstructor != null && basicConstructor.exists()) {
-                        int constructFlags = basicConstructor.getFlags();
-                        if (Flags.isPublic(constructFlags) == false) {
-                            return String.format(
-                                    "%1$s or its default constructor must be public for the system to be able to instantiate it",
-                                    className);
-                        }
-                    } else {
-                        return String.format(
-                                "%1$s must be public, or the system will not be able to instantiate it.",
-                                className);
-                    }
-                }
-
-                // If it's enclosed, test that it's static. If its declaring class is enclosed
-                // as well, test that it is also static, and public.
-                IType declaringType = type;
-                do {
-                    IType tmpType = declaringType.getDeclaringType();
-                    if (tmpType != null) {
-                        if (tmpType.exists()) {
-                            flags = declaringType.getFlags();
-                            if (Flags.isStatic(flags) == false) {
-                                return String.format("%1$s is enclosed, but not static",
-                                        declaringType.getFullyQualifiedName());
-                            }
-                            
-                            flags = tmpType.getFlags();
-                            if (testVisibility && Flags.isPublic(flags) == false) {
-                                return String.format("%1$s is not public",
-                                        tmpType.getFullyQualifiedName());
-                            }
-                        } else {
-                            // if it doesn't exist, we need to exit so we may as well mark it null.
-                            tmpType = null;
-                        }
-                    }
-                    declaringType = tmpType;
-                } while (declaringType != null);
-
-                // test the class inherit from the specified super class.
-                // get the type hierarchy
-                ITypeHierarchy hierarchy = type.newSupertypeHierarchy(new NullProgressMonitor());
-                
-                // if the super class is not the reference class, it may inherit from
-                // it so we get its supertype. At some point it will be null and we
-                // will stop
-                IType superType = type;
-                boolean foundProperSuperClass = false;
-                while ((superType = hierarchy.getSuperclass(superType)) != null &&
-                        superType.exists()) {
-                    if (superClassName.equals(superType.getFullyQualifiedName())) {
-                        foundProperSuperClass = true;
-                    }
-                }
-                
-                // didn't find the proper superclass? return false.
-                if (foundProperSuperClass == false) {
-                    return String.format("%1$s does not extend %2$s", className, superClassName);
-                }
-                
-                return TEST_CLASS_OK;
-            } else {
-                return String.format("Class %1$s does not exist", className);
-            }
-        } catch (JavaModelException e) {
-            return String.format("%1$s: %2$s", className, e.getMessage());
-        }
-    }
-    
-    /**
-     * Parses the manifest file for errors.
-     * <p/>
-     * This starts by removing the current XML marker, and then parses the xml for errors, both
-     * of XML type and of Android type (checking validity of class files).
-     * @param manifestFile
-     * @param errorListener
-     * @throws CoreException
-     */
-    public static AndroidManifestParser parseManifestForError(IFile manifestFile,
-            XmlErrorListener errorListener) throws CoreException {
-        // remove previous markers
-        if (manifestFile.exists()) {
-            manifestFile.deleteMarkers(AndroidConstants.MARKER_XML, true, IResource.DEPTH_ZERO);
-            manifestFile.deleteMarkers(AndroidConstants.MARKER_ANDROID, true, IResource.DEPTH_ZERO);
-        }
-        
-        // and parse
-        return AndroidManifestParser.parseForError(
-                BaseProjectHelper.getJavaProject(manifestFile.getProject()),
-                manifestFile, errorListener);
-    }
-
-    /**
-     * Returns the {@link IJavaProject} for a {@link IProject} object.
-     * <p/>
-     * This checks if the project has the Java Nature first.
-     * @param project
-     * @return the IJavaProject or null if the project couldn't be created or if the project
-     * does not have the Java Nature.
-     * @throws CoreException
-     */
-    public static IJavaProject getJavaProject(IProject project) throws CoreException {
-        if (project != null && project.hasNature(JavaCore.NATURE_ID)) {
-            return JavaCore.create(project);
-        }
-        return null;
-    }
-    
-    /**
-     * Reveals a specific line in the source file defining a specified class,
-     * for a specific project.
-     * @param project
-     * @param className
-     * @param line
-     */
-    public static void revealSource(IProject project, String className, int line) {
-        // in case the type is enclosed, we need to replace the $ with .
-        className = className.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS2$
-
-        // get the java project
-        IJavaProject javaProject = JavaCore.create(project);
-        
-        try {
-            // look for the IType matching the class name.
-            IType result = javaProject.findType(className);
-            if (result != null && result.exists()) {
-                // before we show the type in an editor window, we make sure the current
-                // workbench page has an editor area (typically the ddms perspective doesn't).
-                IWorkbench workbench = PlatformUI.getWorkbench();
-                IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
-                IWorkbenchPage page = window.getActivePage();
-                if (page.isEditorAreaVisible() == false) {
-                    // no editor area? we open the java perspective.
-                    new OpenJavaPerspectiveAction().run();
-                }
-                
-                IEditorPart editor = JavaUI.openInEditor(result);
-                if (editor instanceof ITextEditor) {
-                    // get the text editor that was just opened.
-                    ITextEditor textEditor = (ITextEditor)editor;
-                    
-                    IEditorInput input = textEditor.getEditorInput();
-                    
-                    // get the location of the line to show.
-                    IDocumentProvider documentProvider = textEditor.getDocumentProvider();
-                    IDocument document = documentProvider.getDocument(input);
-                    IRegion lineInfo = document.getLineInformation(line - 1);
-                    
-                    // select and reveal the line.
-                    textEditor.selectAndReveal(lineInfo.getOffset(), lineInfo.getLength());
-                }
-            }
-        } catch (JavaModelException e) {
-        } catch (PartInitException e) {
-        } catch (BadLocationException e) {
-        }
-    }
-    
-    /**
-     * Returns the list of android-flagged projects. This list contains projects that are opened
-     * in the workspace and that are flagged as android project (through the android nature)
-     * @return an array of IJavaProject, which can be empty if no projects match.
-     */
-    public static IJavaProject[] getAndroidProjects() {
-        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
-        IJavaModel javaModel = JavaCore.create(workspaceRoot);
-
-        return getAndroidProjects(javaModel);
-    }
-
-    /**
-     * Returns the list of android-flagged projects for the specified java Model.
-     * This list contains projects that are opened in the workspace and that are flagged as android
-     * project (through the android nature)
-     * @param javaModel the Java Model object corresponding for the current workspace root.
-     * @return an array of IJavaProject, which can be empty if no projects match.
-     */
-    public static IJavaProject[] getAndroidProjects(IJavaModel javaModel) {
-        // get the java projects
-        IJavaProject[] javaProjectList = null;
-        try {
-            javaProjectList  = javaModel.getJavaProjects();
-        }
-        catch (JavaModelException jme) {
-            return new IJavaProject[0];
-        }
-
-        // temp list to build the android project array
-        ArrayList<IJavaProject> androidProjectList = new ArrayList<IJavaProject>();
-
-        // loop through the projects and add the android flagged projects to the temp list.
-        for (IJavaProject javaProject : javaProjectList) {
-            // get the workspace project object
-            IProject project = javaProject.getProject();
-
-            // check if it's an android project based on its nature
-            try {
-                if (project.hasNature(AndroidConstants.NATURE)) {
-                    androidProjectList.add(javaProject);
-                }
-            } catch (CoreException e) {
-                // this exception, thrown by IProject.hasNature(), means the project either doesn't
-                // exist or isn't opened. So, in any case we just skip it (the exception will
-                // bypass the ArrayList.add()
-            }
-        }
-
-        // return the android projects list.
-        return androidProjectList.toArray(new IJavaProject[androidProjectList.size()]);
-    }
-    
-    /**
-     * Returns the {@link IFolder} representing the output for the project.
-     * <p>
-     * The project must be a java project and be opened, or the method will return null.
-     * @param project the {@link IProject}
-     * @return an IFolder item or null.
-     */
-    public final static IFolder getOutputFolder(IProject project) {
-        try {
-            if (project.isOpen() && project.hasNature(JavaCore.NATURE_ID)) {
-                // get a java project from the normal project object
-                IJavaProject javaProject = JavaCore.create(project);
-    
-                IPath path = javaProject.getOutputLocation();
-                IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
-                IResource outputResource = wsRoot.findMember(path);
-                if (outputResource != null && outputResource.getType() == IResource.FOLDER) {
-                    return (IFolder)outputResource;
-                }
-            }
-        } catch (JavaModelException e) {
-            // Let's do nothing and return null
-        } catch (CoreException e) {
-            // Let's do nothing and return null
-        }
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java
deleted file mode 100644
index 235ba7c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.jar.JarEntry;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-
-/**
- * Export helper for project.
- */
-public final class ExportHelper {
-
-    private static IExportCallback sCallback;
-
-    public interface IExportCallback {
-        void startExportWizard(IProject project);
-    }
-
-    public static void setCallback(IExportCallback callback) {
-        sCallback = callback;
-    }
-
-    public static void startExportWizard(IProject project) {
-        if (sCallback != null) {
-            sCallback.startExportWizard(project);
-        }
-    }
-
-    /**
-     * Exports an <b>unsigned</b> version of the application created by the given project.
-     * @param project the project to export
-     */
-    public static void exportProject(IProject project) {
-        Shell shell = Display.getCurrent().getActiveShell();
-
-        // get the java project to get the output directory
-        IFolder outputFolder = BaseProjectHelper.getOutputFolder(project);
-        if (outputFolder != null) {
-            IPath binLocation = outputFolder.getLocation();
-
-            // make the full path to the package
-            String fileName = project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
-
-            File file = new File(binLocation.toOSString() + File.separator + fileName);
-
-            if (file.exists() == false || file.isFile() == false) {
-                MessageDialog.openError(Display.getCurrent().getActiveShell(),
-                        "Android IDE Plug-in",
-                        String.format("Failed to export %1$s: %2$s doesn't exist!",
-                                project.getName(), file.getPath()));
-                return;
-            }
-
-            // ok now pop up the file save window
-            FileDialog fileDialog = new FileDialog(shell, SWT.SAVE);
-
-            fileDialog.setText("Export Project");
-            fileDialog.setFileName(fileName);
-
-            String saveLocation = fileDialog.open();
-            if (saveLocation != null) {
-                // get the stream from the original file
-
-                ZipInputStream zis = null;
-                ZipOutputStream zos = null;
-                FileInputStream input = null;
-                FileOutputStream output = null;
-
-                try {
-                    input = new FileInputStream(file);
-                    zis = new ZipInputStream(input);
-
-                    // get an output stream into the new file
-                    File saveFile = new File(saveLocation);
-                    output = new FileOutputStream(saveFile);
-                    zos = new ZipOutputStream(output);
-                } catch (FileNotFoundException e) {
-                    // only the input/output stream are throwing this exception.
-                    // so we only have to close zis if output is the one that threw.
-                    if (zis != null) {
-                        try {
-                            zis.close();
-                        } catch (IOException e1) {
-                            // pass
-                        }
-                    }
-
-                    MessageDialog.openError(shell, "Android IDE Plug-in",
-                            String.format("Failed to export %1$s: %2$s doesn't exist!",
-                                    project.getName(), file.getPath()));
-                    return;
-                }
-
-                try {
-                    ZipEntry entry;
-
-                    byte[] buffer = new byte[4096];
-
-                    while ((entry = zis.getNextEntry()) != null) {
-                        String name = entry.getName();
-
-                        // do not take directories or anything inside the META-INF folder since
-                        // we want to strip the signature.
-                        if (entry.isDirectory() || name.startsWith("META-INF/")) { //$NON-NL1$
-                            continue;
-                        }
-
-                        ZipEntry newEntry;
-
-                        // Preserve the STORED method of the input entry.
-                        if (entry.getMethod() == JarEntry.STORED) {
-                            newEntry = new JarEntry(entry);
-                        } else {
-                            // Create a new entry so that the compressed len is recomputed.
-                            newEntry = new JarEntry(name);
-                        }
-
-                        // add the entry to the jar archive
-                        zos.putNextEntry(newEntry);
-
-                        // read the content of the entry from the input stream, and write it into the archive.
-                        int count;
-                        while ((count = zis.read(buffer)) != -1) {
-                            zos.write(buffer, 0, count);
-                        }
-
-                        // close the entry for this file
-                        zos.closeEntry();
-                        zis.closeEntry();
-                    }
-
-                } catch (IOException e) {
-                    MessageDialog.openError(shell, "Android IDE Plug-in",
-                            String.format("Failed to export %1$s: %2$s",
-                                    project.getName(), e.getMessage()));
-                } finally {
-                    try {
-                        zos.close();
-                    } catch (IOException e) {
-                        // pass
-                    }
-                    try {
-                        zis.close();
-                    } catch (IOException e) {
-                        // pass
-                    }
-                }
-
-                // this is unsigned export. Let's tell the developers to run zip align
-                MessageDialog.openWarning(shell, "Android IDE Plug-in", String.format(
-                        "An unsigned package of the application was saved at\n%1$s\n\n" +
-                        "Before publishing the application you will need to:\n" +
-                        "- Sign the application with your release key,\n" +
-                        "- run zipalign on the signed package. ZipAlign is located in <SDK>/tools/\n\n" +
-                        "Aligning applications allows Android to use application resources\n" +
-                        "more efficiently.", saveLocation));
-
-            }
-        } else {
-            MessageDialog.openError(shell, "Android IDE Plug-in",
-                    String.format("Failed to export %1$s: Could not get project output location",
-                            project.getName()));
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FixLaunchConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FixLaunchConfig.java
deleted file mode 100644
index e311bfb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FixLaunchConfig.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchConfigurationType;
-import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
-
-import java.util.ArrayList;
-
-/**
- * Class to fix the launch configuration of a project if the java package
- * defined in the manifest has been changed.<br>
- * This fix can be done synchronously, or asynchronously.<br>
- * <code>start()</code> will start a thread that will do the fix.<br>
- * <code>run()</code> will do the fix in the current thread.<br><br>
- * By default, the fix first display a dialog to the user asking if he/she wants to
- * do the fix. This can be overriden by calling <code>setDisplayPrompt(false)</code>.
- *
- */
-public class FixLaunchConfig extends Thread {
-
-    private IProject mProject;
-    private String mOldPackage;
-    private String mNewPackage;
-
-    private boolean mDisplayPrompt = true;
-
-    public FixLaunchConfig(IProject project, String oldPackage, String newPackage) {
-        super();
-
-        mProject = project;
-        mOldPackage = oldPackage;
-        mNewPackage = newPackage;
-    }
-
-    /**
-     * Set the display prompt. If true run()/start() first ask the user if he/she wants
-     * to fix the Launch Config
-     * @param displayPrompt
-     */
-    public void setDisplayPrompt(boolean displayPrompt) {
-        mDisplayPrompt = displayPrompt;
-    }
-
-    /**
-     * Fix the Launch configurations.
-     */
-    @Override
-    public void run() {
-
-        if (mDisplayPrompt) {
-            // ask the user if he really wants to fix the launch config
-            boolean res = AdtPlugin.displayPrompt(
-                    "Launch Configuration Update",
-                    "The package definition in the manifest changed.\nDo you want to update your Launch Configuration(s)?");
-
-            if (res == false) {
-                return;
-            }
-        }
-
-        // get the list of config for the project
-        String projectName = mProject.getName();
-        ILaunchConfiguration[] configs = findConfigs(mProject.getName());
-
-        // loop through all the config and update the package
-        for (ILaunchConfiguration config : configs) {
-            try {
-                // get the working copy so that we can make changes.
-                ILaunchConfigurationWorkingCopy copy = config.getWorkingCopy();
-
-                // get the attributes for the activity
-                String activity = config.getAttribute(LaunchConfigDelegate.ATTR_ACTIVITY,
-                        ""); //$NON-NLS-1$
-
-                // manifests can define activities that are not in the defined package,
-                // so we need to make sure the activity is inside the old package.
-                if (activity.startsWith(mOldPackage)) {
-                    // create the new activity
-                    activity = mNewPackage + activity.substring(mOldPackage.length());
-
-                    // put it in the copy
-                    copy.setAttribute(LaunchConfigDelegate.ATTR_ACTIVITY, activity);
-
-                    // save the config
-                    copy.doSave();
-                }
-            } catch (CoreException e) {
-                // couldn't get the working copy. we output the error in the console
-                String msg = String.format("Failed to modify %1$s: %2$s", projectName,
-                        e.getMessage());
-                AdtPlugin.printErrorToConsole(mProject, msg);
-            }
-        }
-
-    }
-
-    /**
-     * Looks for and returns all existing Launch Configuration object for a
-     * specified project.
-     * @param projectName The name of the project
-     * @return all the ILaunchConfiguration object. If none are present, an empty array is
-     * returned.
-     */
-    private static ILaunchConfiguration[] findConfigs(String projectName) {
-        // get the launch manager
-        ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
-
-        // now get the config type for our particular android type.
-        ILaunchConfigurationType configType = manager.
-                getLaunchConfigurationType(LaunchConfigDelegate.ANDROID_LAUNCH_TYPE_ID);
-
-        // create a temp list to hold all the valid configs
-        ArrayList<ILaunchConfiguration> list = new ArrayList<ILaunchConfiguration>();
-
-        try {
-            ILaunchConfiguration[] configs = manager.getLaunchConfigurations(configType);
-
-            for (ILaunchConfiguration config : configs) {
-                if (config.getAttribute(
-                        IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
-                        "").equals(projectName)) {  //$NON-NLS-1$
-                    list.add(config);
-                }
-            }
-        } catch (CoreException e) {
-        }
-
-        return list.toArray(new ILaunchConfiguration[list.size()]);
-
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java
deleted file mode 100644
index 5f4e22e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.IDecoration;
-import org.eclipse.jface.viewers.ILabelDecorator;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ILightweightLabelDecorator;
-
-/**
- * A {@link ILabelDecorator} associated with an org.eclipse.ui.decorators extension.
- * This is used to add android icons in some special folders in the package explorer.
- */
-public class FolderDecorator implements ILightweightLabelDecorator {
-    
-    private ImageDescriptor mDescriptor;
-
-    public FolderDecorator() {
-        mDescriptor = AdtPlugin.getImageDescriptor("/icons/android_project.png"); //$NON-NLS-1$
-    }
-
-    public void decorate(Object element, IDecoration decoration) {
-        if (element instanceof IFolder) {
-            IFolder folder = (IFolder)element;
-            
-            // get the project and make sure this is an android project
-            IProject project = folder.getProject();
-
-            try {
-                if (project.hasNature(AndroidConstants.NATURE)) {
-                    // check the folder is directly under the project.
-                    if (folder.getParent().getType() == IResource.PROJECT) {
-                        String name = folder.getName();
-                        if (name.equals(SdkConstants.FD_ASSETS)) {
-                            doDecoration(decoration, null);
-                        } else if (name.equals(SdkConstants.FD_RESOURCES)) {
-                            doDecoration(decoration, null);
-                        } else if (name.equals(SdkConstants.FD_GEN_SOURCES)) {
-                            doDecoration(decoration, " [Generated Java Files]");
-                      } else if (name.equals(SdkConstants.FD_NATIVE_LIBS)) {
-                          doDecoration(decoration, null);
-                        }
-                    }
-                }
-            } catch (CoreException e) {
-                // log the error
-                AdtPlugin.log(e, "Unable to get nature of project '%s'.", project.getName());
-            }
-        }
-    }
-    
-    public void doDecoration(IDecoration decoration, String suffix) {
-        decoration.addOverlay(mDescriptor, IDecoration.TOP_LEFT);
-
-        if (suffix != null) {
-            decoration.addSuffix(suffix);
-
-            // this is broken as it changes the color of the whole text, not only of the decoration.
-            // TODO: figure out how to change the color of the decoration only.
-//            ITheme theme = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme();
-//            ColorRegistry registry = theme.getColorRegistry();
-//            decoration.setForegroundColor(
-//                    registry.get("org.eclipse.jdt.ui.ColoredLabels.decorations")); //$NON-NLS-1$
-        }
-
-    }
-
-    public boolean isLabelProperty(Object element, String property) {
-        // Property change do not affect the label
-        return false;
-    }
-
-    public void addListener(ILabelProviderListener listener) {
-        // No state change will affect the rendering.
-    }
-
-    public void removeListener(ILabelProviderListener listener) {
-        // No state change will affect the rendering.
-    }
-
-    public void dispose() {
-        // nothing to dispose
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectChooserHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectChooserHelper.java
deleted file mode 100644
index e6cac8a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectChooserHelper.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.ui.JavaElementLabelProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.dialogs.ElementListSelectionDialog;
-
-/**
- * Helper class to deal with displaying a project choosing dialog that lists only the
- * projects with the Android nature.
- */
-public class ProjectChooserHelper {
-
-    private final Shell mParentShell;
-
-    /**
-     * List of current android projects. Since the dialog is modal, we'll just get
-     * the list once on-demand.
-     */
-    private IJavaProject[] mAndroidProjects;
-
-    public ProjectChooserHelper(Shell parentShell) {
-        mParentShell = parentShell;
-    }
-    /**
-     * Displays a project chooser dialog which lists all available projects with the Android nature.
-     * <p/>
-     * The list of project is built from Android flagged projects currently opened in the workspace.
-     *
-     * @param projectName If non null and not empty, represents the name of an Android project
-     *                    that will be selected by default.
-     * @return the project chosen by the user in the dialog, or null if the dialog was canceled.
-     */
-    public IJavaProject chooseJavaProject(String projectName) {
-        ILabelProvider labelProvider = new JavaElementLabelProvider(
-                JavaElementLabelProvider.SHOW_DEFAULT);
-        ElementListSelectionDialog dialog = new ElementListSelectionDialog(
-                mParentShell, labelProvider);
-        dialog.setTitle("Project Selection");
-        dialog.setMessage("Select a project to constrain your search.");
-
-        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
-        IJavaModel javaModel = JavaCore.create(workspaceRoot);
-
-        // set the elements in the dialog. These are opened android projects.
-        dialog.setElements(getAndroidProjects(javaModel));
-
-        // look for the project matching the given project name
-        IJavaProject javaProject = null;
-        if (projectName != null && projectName.length() > 0) {
-            javaProject = javaModel.getJavaProject(projectName);
-        }
-
-        // if we found it, we set the initial selection in the dialog to this one.
-        if (javaProject != null) {
-            dialog.setInitialSelections(new Object[] { javaProject });
-        }
-
-        // open the dialog and return the object selected if OK was clicked, or null otherwise
-        if (dialog.open() == Window.OK) {
-            return (IJavaProject) dialog.getFirstResult();
-        }
-        return null;
-    }
-    
-    /**
-     * Returns the list of Android projects.
-     * <p/>
-     * Because this list can be time consuming, this class caches the list of project.
-     * It is recommended to call this method instead of
-     * {@link BaseProjectHelper#getAndroidProjects()}.
-     * 
-     * @param javaModel the java model. Can be null.
-     */
-    public IJavaProject[] getAndroidProjects(IJavaModel javaModel) {
-        if (mAndroidProjects == null) {
-            if (javaModel == null) {
-                mAndroidProjects = BaseProjectHelper.getAndroidProjects();
-            } else {
-                mAndroidProjects = BaseProjectHelper.getAndroidProjects(javaModel);
-            }
-        }
-        
-        return mAndroidProjects;
-    }
-    
-    /**
-     * Helper method to get the Android project with the given name
-     * 
-     * @param projectName the name of the project to find
-     * @return the {@link IProject} for the Android project. <code>null</code> if not found.
-     */
-    public IProject getAndroidProject(String projectName) {
-        IProject iproject = null;
-        IJavaProject[] javaProjects = getAndroidProjects(null);
-        if (javaProjects != null) {
-            for (IJavaProject javaProject : javaProjects) {
-                if (javaProject.getElementName().equals(projectName)) {
-                    iproject = javaProject.getProject();
-                    break;
-                }
-            }
-        }    
-        return iproject;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java
deleted file mode 100644
index 49a75dc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.launching.JavaRuntime;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility class to manipulate Project parameters/properties.
- */
-public final class ProjectHelper {
-    public final static int COMPILER_COMPLIANCE_OK = 0;
-    public final static int COMPILER_COMPLIANCE_LEVEL = 1;
-    public final static int COMPILER_COMPLIANCE_SOURCE = 2;
-    public final static int COMPILER_COMPLIANCE_CODEGEN_TARGET = 3;
-
-    /**
-     * Adds the corresponding source folder to the class path entries.
-     *
-     * @param entries The class path entries to read. A copy will be returned.
-     * @param new_entry The parent source folder to remove.
-     * @return A new class path entries array.
-     */
-    public static IClasspathEntry[] addEntryToClasspath(
-            IClasspathEntry[] entries, IClasspathEntry new_entry) {
-        int n = entries.length;
-        IClasspathEntry[] newEntries = new IClasspathEntry[n + 1];
-        System.arraycopy(entries, 0, newEntries, 0, n);
-        newEntries[n] = new_entry;
-        return newEntries;
-    }
-
-    /**
-     * Adds the corresponding source folder to the project's class path entries.
-     *
-     * @param javaProject The java project of which path entries to update.
-     * @param new_entry The parent source folder to remove.
-     * @throws JavaModelException 
-     */
-    public static void addEntryToClasspath(
-            IJavaProject javaProject, IClasspathEntry new_entry)
-            throws JavaModelException {
-
-        IClasspathEntry[] entries = javaProject.getRawClasspath();
-        entries = addEntryToClasspath(entries, new_entry);
-        javaProject.setRawClasspath(entries, new NullProgressMonitor());
-    }
-
-    /**
-     * Remove a classpath entry from the array.
-     * @param entries The class path entries to read. A copy will be returned
-     * @param index The index to remove.
-     * @return A new class path entries array.
-     */
-    public static IClasspathEntry[] removeEntryFromClasspath(
-            IClasspathEntry[] entries, int index) {
-        int n = entries.length;
-        IClasspathEntry[] newEntries = new IClasspathEntry[n-1];
-
-        // copy the entries before index
-        System.arraycopy(entries, 0, newEntries, 0, index);
-
-        // copy the entries after index
-        System.arraycopy(entries, index + 1, newEntries, index,
-                entries.length - index - 1);
-
-        return newEntries;
-    }
-
-    /**
-     * Converts a OS specific path into a path valid for the java doc location
-     * attributes of a project.
-     * @param javaDocOSLocation The OS specific path.
-     * @return a valid path for the java doc location.
-     */
-    public static String getJavaDocPath(String javaDocOSLocation) {
-        // first thing we do is convert the \ into /
-        String javaDoc = javaDocOSLocation.replaceAll("\\\\", //$NON-NLS-1$
-                AndroidConstants.WS_SEP);
-
-        // then we add file: at the beginning for unix path, and file:/ for non
-        // unix path
-        if (javaDoc.startsWith(AndroidConstants.WS_SEP)) {
-            return "file:" + javaDoc; //$NON-NLS-1$
-        }
-
-        return "file:/" + javaDoc; //$NON-NLS-1$
-    }
-
-    /**
-     * Look for a specific classpath entry by full path and return its index.
-     * @param entries The entry array to search in.
-     * @param entryPath The OS specific path of the entry.
-     * @param entryKind The kind of the entry. Accepted values are 0
-     * (no filter), IClasspathEntry.CPE_LIBRARY, IClasspathEntry.CPE_PROJECT,
-     * IClasspathEntry.CPE_SOURCE, IClasspathEntry.CPE_VARIABLE,
-     * and IClasspathEntry.CPE_CONTAINER
-     * @return the index of the found classpath entry or -1.
-     */
-    public static int findClasspathEntryByPath(IClasspathEntry[] entries,
-            String entryPath, int entryKind) {
-        for (int i = 0 ; i < entries.length ; i++) {
-            IClasspathEntry entry = entries[i];
-
-            int kind = entry.getEntryKind();
-
-            if (kind == entryKind || entryKind == 0) {
-                // get the path
-                IPath path = entry.getPath();
-
-                String osPathString = path.toOSString();
-                if (osPathString.equals(entryPath)) {
-                    return i;
-                }
-            }
-        }
-
-        // not found, return bad index.
-        return -1;
-    }
-
-    /**
-     * Look for a specific classpath entry for file name only and return its
-     *  index.
-     * @param entries The entry array to search in.
-     * @param entryName The filename of the entry.
-     * @param entryKind The kind of the entry. Accepted values are 0
-     * (no filter), IClasspathEntry.CPE_LIBRARY, IClasspathEntry.CPE_PROJECT,
-     * IClasspathEntry.CPE_SOURCE, IClasspathEntry.CPE_VARIABLE,
-     * and IClasspathEntry.CPE_CONTAINER
-     * @param startIndex Index where to start the search
-     * @return the index of the found classpath entry or -1.
-     */
-    public static int findClasspathEntryByName(IClasspathEntry[] entries,
-            String entryName, int entryKind, int startIndex) {
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex ; i < entries.length ; i++) {
-            IClasspathEntry entry = entries[i];
-
-            int kind = entry.getEntryKind();
-
-            if (kind == entryKind || entryKind == 0) {
-                // get the path
-                IPath path = entry.getPath();
-                String name = path.segment(path.segmentCount()-1);
-
-                if (name.equals(entryName)) {
-                    return i;
-                }
-            }
-        }
-
-        // not found, return bad index.
-        return -1;
-    }
-
-    /**
-     * Fix the project. This checks the SDK location.
-     * @param project The project to fix.
-     * @throws JavaModelException
-     */
-    public static void fixProject(IProject project) throws JavaModelException {
-        if (AdtPlugin.getOsSdkFolder().length() == 0) {
-            AdtPlugin.printToConsole(project, "Unknown SDK Location, project not fixed.");
-            return;
-        }
-        
-        // get a java project
-        IJavaProject javaProject = JavaCore.create(project);
-        fixProjectClasspathEntries(javaProject);
-    }
-
-    /**
-     * Fix the project classpath entries. The method ensures that:
-     * <ul>
-     * <li>The project does not reference any old android.zip/android.jar archive.</li>
-     * <li>The project does not use its output folder as a sourc folder.</li>
-     * <li>The project does not reference a desktop JRE</li>
-     * <li>The project references the AndroidClasspathContainer.
-     * </ul>
-     * @param javaProject The project to fix.
-     * @throws JavaModelException
-     */
-    public static void fixProjectClasspathEntries(IJavaProject javaProject)
-            throws JavaModelException {
-
-        // get the project classpath
-        IClasspathEntry[] entries = javaProject.getRawClasspath();
-        IClasspathEntry[] oldEntries = entries;
-
-        // check if the JRE is set as library
-        int jreIndex = ProjectHelper.findClasspathEntryByPath(entries, JavaRuntime.JRE_CONTAINER,
-                IClasspathEntry.CPE_CONTAINER);
-        if (jreIndex != -1) {
-            // the project has a JRE included, we remove it
-            entries = ProjectHelper.removeEntryFromClasspath(entries, jreIndex);
-        }
-
-        // get the output folder
-        IPath outputFolder = javaProject.getOutputLocation();
-        
-        boolean foundContainer = false;
-
-        for (int i = 0 ; i < entries.length ;) {
-            // get the entry and kind
-            IClasspathEntry entry = entries[i];
-            int kind = entry.getEntryKind();
-
-            if (kind == IClasspathEntry.CPE_SOURCE) {
-                IPath path = entry.getPath();
-                
-                if (path.equals(outputFolder)) {
-                    entries = ProjectHelper.removeEntryFromClasspath(entries, i);
-                    
-                    // continue, to skip the i++;
-                    continue;
-                }
-            } else if (kind == IClasspathEntry.CPE_CONTAINER) {
-                if (AndroidClasspathContainerInitializer.checkPath(entry.getPath())) {
-                    foundContainer = true;
-                }
-            }
-            
-            i++;
-        }
-
-        // if the framework container is not there, we add it
-        if (foundContainer == false) {
-            // add the android container to the array
-            entries = ProjectHelper.addEntryToClasspath(entries,
-                    AndroidClasspathContainerInitializer.getContainerEntry());
-        }
-
-        // set the new list of entries to the project
-        if (entries != oldEntries) {
-            javaProject.setRawClasspath(entries, new NullProgressMonitor());
-        }
-
-        // If needed, check and fix compiler compliance and source compatibility
-        ProjectHelper.checkAndFixCompilerCompliance(javaProject);
-    }
-    
-    
-    /**
-     * Checks the project compiler compliance level is supported.
-     * @param javaProject The project to check
-     * @return <ul>
-     * <li><code>COMPILER_COMPLIANCE_OK</code> if the project is properly configured</li>
-     * <li><code>COMPILER_COMPLIANCE_LEVEL</code> for unsupported compiler level</li>
-     * <li><code>COMPILER_COMPLIANCE_SOURCE</code> for unsupported source compatibility</li>
-     * <li><code>COMPILER_COMPLIANCE_CODEGEN_TARGET</code> for unsupported .class format</li>
-     * </ul>
-     */
-    public static final int checkCompilerCompliance(IJavaProject javaProject) {
-        // get the project compliance level option
-        String compliance = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
-
-        // check it against a list of valid compliance level strings.
-        if (checkCompliance(compliance) == false) {
-            // if we didn't find the proper compliance level, we return an error
-            return COMPILER_COMPLIANCE_LEVEL;
-        }
-
-        // otherwise we check source compatibility
-        String source = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
-
-        // check it against a list of valid compliance level strings.
-        if (checkCompliance(source) == false) {
-            // if we didn't find the proper compliance level, we return an error
-            return COMPILER_COMPLIANCE_SOURCE;
-        }
-
-        // otherwise check codegen level
-        String codeGen = javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true);
-
-        // check it against a list of valid compliance level strings.
-        if (checkCompliance(codeGen) == false) {
-            // if we didn't find the proper compliance level, we return an error
-            return COMPILER_COMPLIANCE_CODEGEN_TARGET;
-        }
-
-        return COMPILER_COMPLIANCE_OK;
-    }
-
-    /**
-     * Checks the project compiler compliance level is supported.
-     * @param project The project to check
-     * @return <ul>
-     * <li><code>COMPILER_COMPLIANCE_OK</code> if the project is properly configured</li>
-     * <li><code>COMPILER_COMPLIANCE_LEVEL</code> for unsupported compiler level</li>
-     * <li><code>COMPILER_COMPLIANCE_SOURCE</code> for unsupported source compatibility</li>
-     * <li><code>COMPILER_COMPLIANCE_CODEGEN_TARGET</code> for unsupported .class format</li>
-     * </ul>
-     */
-    public static final int checkCompilerCompliance(IProject project) {
-        // get the java project from the IProject resource object
-        IJavaProject javaProject = JavaCore.create(project);
-
-        // check and return the result.
-        return checkCompilerCompliance(javaProject);
-    }
-
-
-    /**
-     * Checks, and fixes if needed, the compiler compliance level, and the source compatibility
-     * level
-     * @param project The project to check and fix.
-     */
-    public static final void checkAndFixCompilerCompliance(IProject project) {
-        // get the java project from the IProject resource object
-        IJavaProject javaProject = JavaCore.create(project);
-
-        // Now we check the compiler compliance level and make sure it is valid
-        checkAndFixCompilerCompliance(javaProject);
-    }
-
-    /**
-     * Checks, and fixes if needed, the compiler compliance level, and the source compatibility
-     * level
-     * @param javaProject The Java project to check and fix.
-     */
-    public static final void checkAndFixCompilerCompliance(IJavaProject javaProject) {
-        if (checkCompilerCompliance(javaProject) != COMPILER_COMPLIANCE_OK) {
-            // setup the preferred compiler compliance level.
-            javaProject.setOption(JavaCore.COMPILER_COMPLIANCE,
-                    AndroidConstants.COMPILER_COMPLIANCE_PREFERRED);
-            javaProject.setOption(JavaCore.COMPILER_SOURCE,
-                    AndroidConstants.COMPILER_COMPLIANCE_PREFERRED);
-            javaProject.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
-                    AndroidConstants.COMPILER_COMPLIANCE_PREFERRED);
-
-            // clean the project to make sure we recompile
-            try {
-                javaProject.getProject().build(IncrementalProjectBuilder.CLEAN_BUILD,
-                        new NullProgressMonitor());
-            } catch (CoreException e) {
-                AdtPlugin.printErrorToConsole(javaProject.getProject(),
-                        "Project compiler settings changed. Clean your project.");
-            }
-        }
-    }
-
-    /**
-     * Returns a {@link IProject} by its running application name, as it returned by the AVD.
-     * <p/>
-     * <var>applicationName</var> will in most case be the package declared in the manifest, but
-     * can, in some cases, be a custom process name declared in the manifest, in the
-     * <code>application</code>, <code>activity</code>, <code>receiver</code>, or
-     * <code>service</code> nodes.
-     * @param applicationName The application name.
-     * @return a project or <code>null</code> if no matching project were found.
-     */
-    public static IProject findAndroidProjectByAppName(String applicationName) {
-        // Get the list of project for the current workspace
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-        IProject[] projects = workspace.getRoot().getProjects();
-        
-        // look for a project that matches the packageName of the app
-        // we're trying to debug
-        for (IProject p : projects) {
-            if (p.isOpen()) {
-                try {
-                    if (p.hasNature(AndroidConstants.NATURE) == false) {
-                        // ignore non android projects
-                        continue;
-                    }
-                } catch (CoreException e) {
-                    // failed to get the nature? skip project.
-                    continue;
-                }
-
-                // check that there is indeed a manifest file.
-                IFile manifestFile = AndroidManifestParser.getManifest(p);
-                if (manifestFile == null) {
-                    // no file? skip this project.
-                    continue;
-                }
-
-                AndroidManifestParser parser = null;
-                try {
-                    parser = AndroidManifestParser.parseForData(manifestFile);
-                } catch (CoreException e) {
-                    // ignore, handled below.
-                }
-                if (parser == null) {
-                    // skip this project.
-                    continue;
-                }
-
-                String manifestPackage = parser.getPackage();
-
-                if (manifestPackage != null && manifestPackage.equals(applicationName)) {
-                    // this is the project we were looking for!
-                    return p;
-                } else {
-                    // if the package and application name don't match,
-                    // we look for other possible process names declared in the manifest.
-                    String[] processes = parser.getProcesses();
-                    for (String process : processes) {
-                        if (process.equals(applicationName)) {
-                            return p;
-                        }
-                    }
-                }
-            }
-        }
-
-        return null;
-
-    }
-
-    public static void fixProjectNatureOrder(IProject project) throws CoreException {
-        IProjectDescription description = project.getDescription();
-        String[] natures = description.getNatureIds();
-        
-        // if the android nature is not the first one, we reorder them
-        if (AndroidConstants.NATURE.equals(natures[0]) == false) {
-            // look for the index
-            for (int i = 0 ; i < natures.length ; i++) {
-                if (AndroidConstants.NATURE.equals(natures[i])) {
-                    // if we try to just reorder the array in one pass, this doesn't do 
-                    // anything. I guess JDT check that we are actually adding/removing nature.
-                    // So, first we'll remove the android nature, and then add it back.
-
-                    // remove the android nature
-                    removeNature(project, AndroidConstants.NATURE);
-                    
-                    // now add it back at the first index.
-                    description = project.getDescription();
-                    natures = description.getNatureIds();
-                    
-                    String[] newNatures = new String[natures.length + 1];
-
-                    // first one is android
-                    newNatures[0] = AndroidConstants.NATURE;
-                    
-                    // next the rest that was before the android nature
-                    System.arraycopy(natures, 0, newNatures, 1, natures.length);
-                    
-                    // set the new natures
-                    description.setNatureIds(newNatures);
-                    project.setDescription(description, null);
-
-                    // and stop
-                    break;
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Removes a specific nature from a project.
-     * @param project The project to remove the nature from.
-     * @param nature The nature id to remove.
-     * @throws CoreException
-     */
-    public static void removeNature(IProject project, String nature) throws CoreException {
-        IProjectDescription description = project.getDescription();
-        String[] natures = description.getNatureIds();
-
-        // check if the project already has the android nature.
-        for (int i = 0; i < natures.length; ++i) {
-            if (nature.equals(natures[i])) {
-                String[] newNatures = new String[natures.length - 1];
-                if (i > 0) {
-                    System.arraycopy(natures, 0, newNatures, 0, i);
-                }
-                System.arraycopy(natures, i + 1, newNatures, i, natures.length - i - 1);
-                description.setNatureIds(newNatures);
-                project.setDescription(description, null);
-
-                return;
-            }
-        }
-
-    }
-
-    /**
-     * Returns if the project has error level markers.
-     * @param includeReferencedProjects flag to also test the referenced projects.
-     * @throws CoreException
-     */
-    public static boolean hasError(IProject project, boolean includeReferencedProjects)
-    throws CoreException {
-        IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
-        if (markers != null && markers.length > 0) {
-            // the project has marker(s). even though they are "problem" we
-            // don't know their severity. so we loop on them and figure if they
-            // are warnings or errors
-            for (IMarker m : markers) {
-                int s = m.getAttribute(IMarker.SEVERITY, -1);
-                if (s == IMarker.SEVERITY_ERROR) {
-                    return true;
-                }
-            }
-        }
-        
-        // test the referenced projects if needed.
-        if (includeReferencedProjects) {
-            IProject[] projects = getReferencedProjects(project);
-            
-            for (IProject p : projects) {
-                if (hasError(p, false)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Saves a String property into the persistent storage of a resource.
-     * @param resource The resource into which the string value is saved.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param value the value to save
-     * @return true if the save succeeded.
-     */
-    public static boolean saveStringProperty(IResource resource, String propertyName,
-            String value) {
-        QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID, propertyName);
-
-        try {
-            resource.setPersistentProperty(qname, value);
-        } catch (CoreException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Loads a String property from the persistent storage of a resource.
-     * @param resource The resource from which the string value is loaded.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @return the property value or null if it was not found.
-     */
-    public static String loadStringProperty(IResource resource, String propertyName) {
-        QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID, propertyName);
-
-        try {
-            String value = resource.getPersistentProperty(qname);
-            return value;
-        } catch (CoreException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Saves a property into the persistent storage of a resource.
-     * @param resource The resource into which the boolean value is saved.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param value the value to save
-     * @return true if the save succeeded.
-     */
-    public static boolean saveBooleanProperty(IResource resource, String propertyName,
-            boolean value) {
-        return saveStringProperty(resource, propertyName, Boolean.toString(value));
-    }
-
-    /**
-     * Loads a boolean property from the persistent storage of the project.
-     * @param resource The resource from which the boolean value is loaded.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param defaultValue The default value to return if the property was not found.
-     * @return the property value or the default value if the property was not found.
-     */
-    public static boolean loadBooleanProperty(IResource resource, String propertyName,
-            boolean defaultValue) {
-        String value = loadStringProperty(resource, propertyName);
-        if (value != null) {
-            return Boolean.parseBoolean(value);
-        }
-
-        return defaultValue;
-    }
-
-    /**
-     * Saves the path of a resource into the persistent storate of the project.
-     * @param resource The resource into which the resource path is saved.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @param value The resource to save. It's its path that is actually stored. If null, an
-     *      empty string is stored.
-     * @return true if the save succeeded
-     */
-    public static boolean saveResourceProperty(IResource resource, String propertyName,
-            IResource value) {
-        if (value != null) {
-            IPath iPath = value.getProjectRelativePath();
-            return saveStringProperty(resource, propertyName, iPath.toString());
-        }
-
-        return saveStringProperty(resource, propertyName, ""); //$NON-NLS-1$
-    }
-
-    /**
-     * Loads the path of a resource from the persistent storage of the project, and returns the
-     * corresponding IResource object, if it exists in the same project as <code>resource</code>.
-     * @param resource The resource from which the resource path is loaded.
-     * @param propertyName the name of the property. The id of the plugin is added to this string.
-     * @return The corresponding IResource object (or children interface) or null
-     */
-    public static IResource loadResourceProperty(IResource resource, String propertyName) {
-        String value = loadStringProperty(resource, propertyName);
-
-        if (value != null && value.length() > 0) {
-            return resource.getProject().findMember(value);
-        }
-
-        return null;
-    }
-    
-    /**
-     * Returns the list of referenced project that are opened and Java projects.
-     * @param project
-     * @return list of opened referenced java project.
-     * @throws CoreException
-     */
-    public static IProject[] getReferencedProjects(IProject project) throws CoreException {
-        IProject[] projects = project.getReferencedProjects();
-        
-        ArrayList<IProject> list = new ArrayList<IProject>();
-        
-        for (IProject p : projects) {
-            if (p.isOpen() && p.hasNature(JavaCore.NATURE_ID)) {
-                list.add(p);
-            }
-        }
-
-        return list.toArray(new IProject[list.size()]);
-    }
-
-
-    /**
-     * Checks a Java project compiler level option against a list of supported versions.
-     * @param optionValue the Compiler level option.
-     * @return true if the option value is supproted.
-     */
-    private static boolean checkCompliance(String optionValue) {
-        for (String s : AndroidConstants.COMPILER_COMPLIANCE) {
-            if (s != null && s.equals(optionValue)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-    
-    /**
-     * Returns the apk filename for the given project
-     * @param project The project.
-     * @param config An optional config name. Can be null.
-     */
-    public static String getApkFilename(IProject project, String config) {
-        if (config != null) {
-            return project.getName() + "-" + config + AndroidConstants.DOT_ANDROID_PACKAGE; //$NON-NLS-1$ 
-        }
-        
-        return project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
-    }
-
-    /**
-     * Find the list of projects on which this JavaProject is dependent on at the compilation level.
-     * 
-     * @param javaProject Java project that we are looking for the dependencies.
-     * @return A list of Java projects for which javaProject depend on.
-     * @throws JavaModelException
-     */
-    public static List<IJavaProject> getAndroidProjectDependencies(IJavaProject javaProject) 
-        throws JavaModelException {
-        String[] requiredProjectNames = javaProject.getRequiredProjectNames();
-    
-        // Go from java project name to JavaProject name
-        IJavaModel javaModel = javaProject.getJavaModel();
-    
-        // loop through all dependent projects and keep only those that are Android projects
-        List<IJavaProject> projectList = new ArrayList<IJavaProject>(requiredProjectNames.length);
-        for (String javaProjectName : requiredProjectNames) {
-            IJavaProject androidJavaProject = javaModel.getJavaProject(javaProjectName);
-            
-            //Verify that the project has also the Android Nature
-            try {
-                if (!androidJavaProject.getProject().hasNature(AndroidConstants.NATURE)) {
-                    continue;
-                }
-            } catch (CoreException e) {
-                continue;
-            }
-            
-            projectList.add(androidJavaProject);
-        }
-        
-        return projectList;
-    }
-
-    /**
-     * Returns the android package file as an IFile object for the specified
-     * project.
-     * @param project The project
-     * @return The android package as an IFile object or null if not found.
-     */
-    public static IFile getApplicationPackage(IProject project) {
-        // get the output folder
-        IFolder outputLocation = BaseProjectHelper.getOutputFolder(project);
-    
-        if (outputLocation == null) {
-            AdtPlugin.printErrorToConsole(project,
-                    "Failed to get the output location of the project. Check build path properties"
-                    );
-            return null;
-        }
-        
-    
-        // get the package path
-        String packageName = project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
-        IResource r = outputLocation.findMember(packageName);
-    
-        // check the package is present
-        if (r instanceof IFile && r.exists()) {
-            return (IFile)r;
-        }
-    
-        String msg = String.format("Could not find %1$s!", packageName);
-        AdtPlugin.printErrorToConsole(project, msg);
-    
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java
deleted file mode 100644
index fe73d49..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarker;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * XML error handler used by the parser to report errors/warnings.
- */
-public class XmlErrorHandler extends DefaultHandler {
-
-    /** file being parsed */
-    private IFile mFile;
-
-    /** link to the delta visitor, to set the xml error flag */
-    private XmlErrorListener mErrorListener;
-    
-    /**
-     * Classes which implement this interface provide a method that deals
-     * with XML errors.
-     */
-    public interface XmlErrorListener {
-        /**
-         * Sent when an XML error is detected.
-         */
-        public void errorFound();
-    }
-    
-    public static class BasicXmlErrorListener implements XmlErrorListener {
-        public boolean mHasXmlError = false;
-        
-        public void errorFound() {
-            mHasXmlError = true;
-        }
-    }
-
-    public XmlErrorHandler(IFile file, XmlErrorListener errorListener) {
-        mFile = file;
-        mErrorListener = errorListener;
-    }
-
-    /**
-     * Xml Error call back
-     * @param exception the parsing exception
-     * @throws SAXException 
-     */
-    @Override
-    public void error(SAXParseException exception) throws SAXException {
-        handleError(exception, exception.getLineNumber());
-    }
-
-    /**
-     * Xml Fatal Error call back
-     * @param exception the parsing exception
-     * @throws SAXException 
-     */
-    @Override
-    public void fatalError(SAXParseException exception) throws SAXException {
-        handleError(exception, exception.getLineNumber());
-    }
-
-    /**
-     * Xml Warning call back
-     * @param exception the parsing exception
-     * @throws SAXException 
-     */
-    @Override
-    public void warning(SAXParseException exception) throws SAXException {
-        if (mFile != null) {
-            BaseProjectHelper.addMarker(mFile,
-                    AndroidConstants.MARKER_XML,
-                    exception.getMessage(),
-                    exception.getLineNumber(),
-                    IMarker.SEVERITY_WARNING);
-        }
-    }
-    
-    protected final IFile getFile() {
-        return mFile;
-    }
-    
-    /**
-     * Handles a parsing error and an optional line number.
-     * @param exception
-     * @param lineNumber
-     */
-    protected void handleError(Exception exception, int lineNumber) {
-        if (mErrorListener != null) {
-            mErrorListener.errorFound();
-        }
-        
-        String message = exception.getMessage();
-        if (message == null) {
-            message = "Unknown error " + exception.getClass().getCanonicalName();
-        }
-        
-        if (mFile != null) {
-            if (lineNumber != -1) {
-                BaseProjectHelper.addMarker(mFile,
-                        AndroidConstants.MARKER_XML,
-                        message,
-                        lineNumber,
-                        IMarker.SEVERITY_ERROR);
-            } else {
-                BaseProjectHelper.addMarker(mFile,
-                        AndroidConstants.MARKER_XML,
-                        message,
-                        IMarker.SEVERITY_ERROR);
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java
deleted file mode 100644
index d9d66e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.properties;
-
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.internal.project.ApkSettings;
-import com.android.sdkuilib.internal.widgets.SdkTargetSelector;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.ui.IWorkbenchPropertyPage;
-import org.eclipse.ui.dialogs.PropertyPage;
-
-/**
- * Property page for "Android" project.
- * This is accessible from the Package Explorer when right clicking a project and choosing
- * "Properties".
- *
- */
-public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPropertyPage {
-
-    private IProject mProject;
-    private SdkTargetSelector mSelector;
-    // APK-SPLIT: This is not yet supported, so we hide the UI
-//    private Button mSplitByDensity;
-
-    public AndroidPropertyPage() {
-        // pass
-    }
-
-    @Override
-    protected Control createContents(Composite parent) {
-        // get the element (this is not yet valid in the constructor).
-        mProject = (IProject)getElement();
-
-        // get the targets from the sdk
-        IAndroidTarget[] targets = null;
-        if (Sdk.getCurrent() != null) {
-            targets = Sdk.getCurrent().getTargets();
-        }
-
-        // build the UI.
-        Composite top = new Composite(parent, SWT.NONE);
-        top.setLayoutData(new GridData(GridData.FILL_BOTH));
-        top.setLayout(new GridLayout(1, false));
-
-        Label l = new Label(top, SWT.NONE);
-        l.setText("Project Build Target");
-
-        mSelector = new SdkTargetSelector(top, targets);
-
-        /*
-         * APK-SPLIT: This is not yet supported, so we hide the UI
-        Group g = new Group(top, SWT.NONE);
-        g.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        g.setLayout(new GridLayout(1, false));
-        g.setText("APK Generation");
-
-        mSplitByDensity = new Button(g, SWT.CHECK);
-        mSplitByDensity.setText("One APK per density");
-
-*/
-        // fill the ui
-        Sdk currentSdk = Sdk.getCurrent();
-        if (currentSdk != null && mProject.isOpen()) {
-            // get the target
-            IAndroidTarget target = currentSdk.getTarget(mProject);
-            if (target != null) {
-                mSelector.setSelection(target);
-            }
-
-            /*
-             * APK-SPLIT: This is not yet supported, so we hide the UI
-            // get the project settings
-            ApkSettings settings = currentSdk.getApkSettings(mProject);
-            mSplitByDensity.setSelection(settings.isSplitByDpi());
-            */
-        }
-
-        mSelector.setSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // look for the selection and validate the page if there is a selection
-                IAndroidTarget target = mSelector.getSelected();
-                setValid(target != null);
-            }
-        });
-
-        if (mProject.isOpen() == false) {
-            // disable the ui.
-        }
-
-        return top;
-    }
-
-    @Override
-    public boolean performOk() {
-        Sdk currentSdk = Sdk.getCurrent();
-        if (currentSdk != null) {
-            ApkSettings apkSettings = new ApkSettings();
-            /*
-             * APK-SPLIT: This is not yet supported, so we hide the UI
-            apkSettings.setSplitByDensity(mSplitByDensity.getSelection());
-             */
-
-            currentSdk.setProject(mProject, mSelector.getSelected(), apkSettings);
-        }
-
-        return true;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java
deleted file mode 100644
index 6caf966..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.text.ITextSelection;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.FileEditorInput;
-
-/*
- * Quick Reference Link:
- * http://www.eclipse.org/articles/article.php?file=Article-Unleashing-the-Power-of-Refactoring/index.html
- * and
- * http://www.ibm.com/developerworks/opensource/library/os-ecjdt/
- */
-
-/**
- * Action executed when the "Extract String" menu item is invoked.
- * <p/>
- * The intent of the action is to start a refactoring that extracts a source string and
- * replaces it by an Android string resource ID.
- * <p/>
- * Workflow:
- * <ul>
- * <li> The action is currently located in the Refactoring menu in the main menu.
- * <li> TODO: extend the popup refactoring menu in a Java or Android XML file.
- * <li> The action is only enabled if the selection is 1 character or more. That is at least part
- *     of the string must be selected, it's not enough to just move the insertion point. This is
- *     a limitation due to {@link #selectionChanged(IAction, ISelection)} not being called when
- *     the insertion point is merely moved. TODO: address this limitation.
- * <ul> The action gets the current {@link ISelection}. It also knows the current
- *     {@link IWorkbenchWindow}. However for the refactoring we are also interested in having the
- *     actual resource file. By looking at the Active Window > Active Page > Active Editor we
- *     can get the {@link IEditorInput} and find the {@link ICompilationUnit} (aka Java file)
- *     that is being edited.
- * <ul> TODO: change this to find the {@link IFile} being manipulated. The {@link ICompilationUnit}
- *     can be inferred using {@link JavaCore#createCompilationUnitFrom(IFile)}. This will allow
- *     us to be able to work with a selection from an Android XML file later.
- * <li> The action creates a new {@link ExtractStringRefactoring} and make it run on in a new
- *     {@link ExtractStringWizard}.
- * <ul>
- */
-public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
-
-    /** Keep track of the current workbench window. */
-    private IWorkbenchWindow mWindow;
-    private ITextSelection mSelection;
-    private IEditorPart mEditor;
-    private IFile mFile;
-
-    /**
-     * Keep track of the current workbench window.
-     */
-    public void init(IWorkbenchWindow window) {
-        mWindow = window;
-    }
-
-    public void dispose() {
-        // Nothing to do
-    }
-
-    /**
-     * Examine the selection to determine if the action should be enabled or not.
-     * <p/>
-     * Keep a link to the relevant selection structure (i.e. a part of the Java AST).
-     */
-    public void selectionChanged(IAction action, ISelection selection) {
-
-        // Note, two kinds of selections are returned here:
-        // ITextSelection on a Java source window
-        // IStructuredSelection in the outline or navigator
-        // This simply deals with the refactoring based on a non-empty selection.
-        // At that point, just enable the action and later decide if it's valid when it actually
-        // runs since we don't have access to the AST yet.
-
-        mSelection = null;
-        mFile = null;
-
-        if (selection instanceof ITextSelection) {
-            mSelection = (ITextSelection) selection;
-            if (mSelection.getLength() > 0) {
-                mEditor = getActiveEditor();
-                mFile = getSelectedFile(mEditor);
-            }
-        }
-
-        action.setEnabled(mSelection != null && mFile != null);
-    }
-
-    /**
-     * Create a new instance of our refactoring and a wizard to configure it.
-     */
-    public void run(IAction action) {
-        if (mSelection != null && mFile != null) {
-            ExtractStringRefactoring ref = new ExtractStringRefactoring(mFile, mEditor, mSelection);
-            RefactoringWizard wizard = new ExtractStringWizard(ref, mFile.getProject());
-            RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
-            try {
-                op.run(mWindow.getShell(), wizard.getDefaultPageTitle());
-            } catch (InterruptedException e) {
-                // Interrupted. Pass.
-            }
-        }
-    }
-
-    /**
-     * Returns the active editor (hopefully matching our selection) or null.
-     */
-    private IEditorPart getActiveEditor() {
-        IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-        if (wwin != null) {
-            IWorkbenchPage page = wwin.getActivePage();
-            if (page != null) {
-                return page.getActiveEditor();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the active {@link IFile} (hopefully matching our selection) or null.
-     * The file is only returned if it's a file from a project with an Android nature.
-     * <p/>
-     * At that point we do not try to analyze if the selection nor the file is suitable
-     * for the refactoring. This check is performed when the refactoring is invoked since
-     * it can then produce meaningful error messages as needed.
-     */
-    private IFile getSelectedFile(IEditorPart editor) {
-        if (editor != null) {
-            IEditorInput input = editor.getEditorInput();
-
-            if (input instanceof FileEditorInput) {
-                FileEditorInput fi = (FileEditorInput) input;
-                IFile file = fi.getFile();
-                if (file.exists()) {
-                    IProject proj = file.getProject();
-                    try {
-                        if (proj != null && proj.hasNature(AndroidConstants.NATURE)) {
-                            return file;
-                        }
-                    } catch (CoreException e) {
-                        // ignore
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringContribution.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringContribution.java
deleted file mode 100644
index 14fd506..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringContribution.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-import org.eclipse.ltk.core.refactoring.RefactoringContribution;
-import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
-
-import java.util.Map;
-
-/**
- * @see ExtractStringDescriptor
- */
-public class ExtractStringContribution extends RefactoringContribution {
-    
-    /* (non-Javadoc)
-     * @see org.eclipse.ltk.core.refactoring.RefactoringContribution#createDescriptor(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.Map, int)
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public RefactoringDescriptor createDescriptor(
-            String id,
-            String project,
-            String description,
-            String comment,
-            Map arguments,
-            int flags)
-                throws IllegalArgumentException {
-        return new ExtractStringDescriptor(project, description, comment, arguments);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Map retrieveArgumentMap(RefactoringDescriptor descriptor) {
-        if (descriptor instanceof ExtractStringDescriptor) {
-            return ((ExtractStringDescriptor) descriptor).getArguments();
-        }
-        return super.retrieveArgumentMap(descriptor);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringDescriptor.java
deleted file mode 100644
index 190736a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringDescriptor.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.ltk.core.refactoring.Refactoring;
-import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-
-import java.util.Map;
-
-/**
- * A descriptor that allows an {@link ExtractStringRefactoring} to be created from
- * a previous instance of itself.
- */
-public class ExtractStringDescriptor extends RefactoringDescriptor {
-
-    public static final String ID =
-        "com.android.ide.eclipse.adt.refactoring.extract.string";  //$NON-NLS-1$
-    
-    private final Map<String, String> mArguments;
-
-    public ExtractStringDescriptor(String project, String description, String comment,
-            Map<String, String> arguments) {
-        super(ID, project, description, comment,
-                RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE //flags
-        );
-        mArguments = arguments;
-    }
-    
-    public Map<String, String> getArguments() {
-        return mArguments;
-    }
-
-    /**
-     * Creates a new refactoring instance for this refactoring descriptor based on
-     * an argument map. The argument map is created by the refactoring itself in
-     * {@link ExtractStringRefactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)}
-     * <p/>
-     * This is apparently used to replay a refactoring.
-     * 
-     * {@inheritDoc}
-     * 
-     * @throws CoreException
-     */
-    @Override
-    public Refactoring createRefactoring(RefactoringStatus status) throws CoreException {
-        try {
-            ExtractStringRefactoring ref = new ExtractStringRefactoring(mArguments);
-            return ref;
-        } catch (NullPointerException e) {
-            status.addFatalError("Failed to recreate ExtractStringRefactoring from descriptor");
-            return null;
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java
deleted file mode 100644
index a54f8b6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @see ExtractStringRefactoring
- */
-class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage {
-
-    /** Last res file path used, shared across the session instances but specific to the
-     *  current project. The default for unknown projects is {@link #DEFAULT_RES_FILE_PATH}. */
-    private static HashMap<String, String> sLastResFilePath = new HashMap<String, String>();
-
-    /** The project where the user selection happened. */
-    private final IProject mProject;
-
-    /** Text field where the user enters the new ID to be generated or replaced with. */
-    private Combo mStringIdCombo;
-    /** Text field where the user enters the new string value. */
-    private Text mStringValueField;
-    /** The configuration selector, to select the resource path of the XML file. */
-    private ConfigurationSelector mConfigSelector;
-    /** The combo to display the existing XML files or enter a new one. */
-    private Combo mResFileCombo;
-
-    /** Regex pattern to read a valid res XML file path. It checks that the are 2 folders and
-     *  a leaf file name ending with .xml */
-    private static final Pattern RES_XML_FILE_REGEX = Pattern.compile(
-                                     "/res/[a-z][a-zA-Z0-9_-]+/[^.]+\\.xml");  //$NON-NLS-1$
-    /** Absolute destination folder root, e.g. "/res/" */
-    private static final String RES_FOLDER_ABS =
-        AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP;
-    /** Relative destination folder root, e.g. "res/" */
-    private static final String RES_FOLDER_REL =
-        SdkConstants.FD_RESOURCES + AndroidConstants.WS_SEP;
-
-    private static final String DEFAULT_RES_FILE_PATH = "/res/values/strings.xml";  //$NON-NLS-1$
-
-    private XmlStringFileHelper mXmlHelper = new XmlStringFileHelper();
-
-
-    public ExtractStringInputPage(IProject project) {
-        super("ExtractStringInputPage");  //$NON-NLS-1$
-        mProject = project;
-    }
-
-    /**
-     * Create the UI for the refactoring wizard.
-     * <p/>
-     * Note that at that point the initial conditions have been checked in
-     * {@link ExtractStringRefactoring}.
-     */
-    public void createControl(Composite parent) {
-        Composite content = new Composite(parent, SWT.NONE);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 1;
-        content.setLayout(layout);
-
-        createStringGroup(content);
-        createResFileGroup(content);
-
-        validatePage();
-        setControl(content);
-    }
-
-    /**
-     * Creates the top group with the field to replace which string and by what
-     * and by which options.
-     *
-     * @param content A composite with a 1-column grid layout
-     */
-    public void createStringGroup(Composite content) {
-
-        final ExtractStringRefactoring ref = getOurRefactoring();
-
-        Group group = new Group(content, SWT.NONE);
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        if (ref.getMode() == ExtractStringRefactoring.Mode.EDIT_SOURCE) {
-            group.setText("String Replacement");
-        } else {
-            group.setText("New String");
-        }
-
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-
-        // line: Textfield for string value (based on selection, if any)
-
-        Label label = new Label(group, SWT.NONE);
-        label.setText("&String");
-
-        String selectedString = ref.getTokenString();
-
-        mStringValueField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-        mStringValueField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mStringValueField.setText(selectedString != null ? selectedString : "");  //$NON-NLS-1$
-
-        ref.setNewStringValue(mStringValueField.getText());
-
-        mStringValueField.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                validatePage();
-            }
-        });
-
-
-        // TODO provide an option to replace all occurences of this string instead of
-        // just the one.
-
-        // line : Textfield for new ID
-
-        label = new Label(group, SWT.NONE);
-        if (ref.getMode() == ExtractStringRefactoring.Mode.EDIT_SOURCE) {
-            label.setText("&Replace by R.string.");
-        } else if (ref.getMode() == ExtractStringRefactoring.Mode.SELECT_NEW_ID) {
-            label.setText("New &R.string.");
-        } else {
-            label.setText("ID &R.string.");
-        }
-
-        mStringIdCombo = new Combo(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.DROP_DOWN);
-        mStringIdCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mStringIdCombo.setText(guessId(selectedString));
-        mStringIdCombo.forceFocus();
-
-        ref.setNewStringId(mStringIdCombo.getText().trim());
-
-        mStringIdCombo.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                validatePage();
-            }
-        });
-        mStringIdCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                validatePage();
-            }
-        });
-    }
-
-    /**
-     * Creates the lower group with the fields to choose the resource confirmation and
-     * the target XML file.
-     *
-     * @param content A composite with a 1-column grid layout
-     */
-    private void createResFileGroup(Composite content) {
-
-        Group group = new Group(content, SWT.NONE);
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        group.setText("XML resource to edit");
-
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-
-        // line: selection of the res config
-
-        Label label;
-        label = new Label(group, SWT.NONE);
-        label.setText("&Configuration:");
-
-        mConfigSelector = new ConfigurationSelector(group, false /*deviceMode*/);
-        GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
-        gd.horizontalSpan = 2;
-        gd.widthHint = ConfigurationSelector.WIDTH_HINT;
-        gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
-        mConfigSelector.setLayoutData(gd);
-        OnConfigSelectorUpdated onConfigSelectorUpdated = new OnConfigSelectorUpdated();
-        mConfigSelector.setOnChangeListener(onConfigSelectorUpdated);
-
-        // line: selection of the output file
-
-        label = new Label(group, SWT.NONE);
-        label.setText("Resource &file:");
-
-        mResFileCombo = new Combo(group, SWT.DROP_DOWN);
-        mResFileCombo.select(0);
-        mResFileCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mResFileCombo.addModifyListener(onConfigSelectorUpdated);
-
-        // set output file name to the last one used
-
-        String projPath = mProject.getFullPath().toPortableString();
-        String filePath = sLastResFilePath.get(projPath);
-
-        mResFileCombo.setText(filePath != null ? filePath : DEFAULT_RES_FILE_PATH);
-        onConfigSelectorUpdated.run();
-    }
-
-    /**
-     * Utility method to guess a suitable new XML ID based on the selected string.
-     */
-    private String guessId(String text) {
-        if (text == null) {
-            return "";  //$NON-NLS-1$
-        }
-
-        // make lower case
-        text = text.toLowerCase();
-
-        // everything not alphanumeric becomes an underscore
-        text = text.replaceAll("[^a-zA-Z0-9]+", "_");  //$NON-NLS-1$ //$NON-NLS-2$
-
-        // the id must be a proper Java identifier, so it can't start with a number
-        if (text.length() > 0 && !Character.isJavaIdentifierStart(text.charAt(0))) {
-            text = "_" + text;  //$NON-NLS-1$
-        }
-        return text;
-    }
-
-    /**
-     * Returns the {@link ExtractStringRefactoring} instance used by this wizard page.
-     */
-    private ExtractStringRefactoring getOurRefactoring() {
-        return (ExtractStringRefactoring) getRefactoring();
-    }
-
-    /**
-     * Validates fields of the wizard input page. Displays errors as appropriate and
-     * enable the "Next" button (or not) by calling {@link #setPageComplete(boolean)}.
-     *
-     * If validation succeeds, this udpates the text id & value in the refactoring object.
-     *
-     * @return True if the page has been positively validated. It may still have warnings.
-     */
-    private boolean validatePage() {
-        boolean success = true;
-
-        ExtractStringRefactoring ref = getOurRefactoring();
-
-        // Analyze fatal errors.
-
-        String text = mStringIdCombo.getText().trim();
-        if (text == null || text.length() < 1) {
-            setErrorMessage("Please provide a resource ID.");
-            success = false;
-        } else {
-            for (int i = 0; i < text.length(); i++) {
-                char c = text.charAt(i);
-                boolean ok = i == 0 ?
-                        Character.isJavaIdentifierStart(c) :
-                        Character.isJavaIdentifierPart(c);
-                if (!ok) {
-                    setErrorMessage(String.format(
-                            "The resource ID must be a valid Java identifier. The character %1$c at position %2$d is not acceptable.",
-                            c, i+1));
-                    success = false;
-                    break;
-                }
-            }
-
-            // update the field in the refactoring object in case of success
-            if (success) {
-                ref.setNewStringId(text);
-            }
-        }
-
-        String resFile = mResFileCombo.getText();
-        if (success) {
-            if (resFile == null || resFile.length() == 0) {
-                setErrorMessage("A resource file name is required.");
-                success = false;
-            } else if (!RES_XML_FILE_REGEX.matcher(resFile).matches()) {
-                setErrorMessage("The XML file name is not valid.");
-                success = false;
-            }
-        }
-
-        // Analyze info & warnings.
-
-        if (success) {
-            setErrorMessage(null);
-
-            ref.setTargetFile(resFile);
-            sLastResFilePath.put(mProject.getFullPath().toPortableString(), resFile);
-
-            String idValue = mXmlHelper.valueOfStringId(mProject, resFile, text);
-            if (idValue != null) {
-                String msg = String.format("%1$s already contains a string ID '%2$s' with value '%3$s'.",
-                        resFile,
-                        text,
-                        idValue);
-                if (ref.getMode() == ExtractStringRefactoring.Mode.SELECT_NEW_ID) {
-                    setErrorMessage(msg);
-                    success = false;
-                } else {
-                    setMessage(msg, WizardPage.WARNING);
-                }
-            } else if (mProject.findMember(resFile) == null) {
-                setMessage(
-                        String.format("File %2$s does not exist and will be created.",
-                                text, resFile),
-                        WizardPage.INFORMATION);
-            } else {
-                setMessage(null);
-            }
-        }
-
-        if (success) {
-            // Also update the text value in case of success.
-            ref.setNewStringValue(mStringValueField.getText());
-        }
-
-        setPageComplete(success);
-        return success;
-    }
-
-    private void updateStringValueCombo() {
-        String resFile = mResFileCombo.getText();
-        Map<String, String> ids = mXmlHelper.getResIdsForFile(mProject, resFile);
-
-        // get the current text from the combo, to make sure we don't change it
-        String currText = mStringIdCombo.getText();
-
-        // erase the choices and fill with the given ids
-        mStringIdCombo.removeAll();
-        mStringIdCombo.setItems(ids.keySet().toArray(new String[ids.size()]));
-
-        // set the current text to preserve it in case it changed
-        if (!currText.equals(mStringIdCombo.getText())) {
-            mStringIdCombo.setText(currText);
-        }
-    }
-
-    public class OnConfigSelectorUpdated implements Runnable, ModifyListener {
-
-        /** Regex pattern to parse a valid res path: it reads (/res/folder-name/)+(filename). */
-        private final Pattern mPathRegex = Pattern.compile(
-            "(/res/[a-z][a-zA-Z0-9_-]+/)(.+)");  //$NON-NLS-1$
-
-        /** Temporary config object used to retrieve the Config Selector value. */
-        private FolderConfiguration mTempConfig = new FolderConfiguration();
-
-        private HashMap<String, TreeSet<String>> mFolderCache =
-            new HashMap<String, TreeSet<String>>();
-        private String mLastFolderUsedInCombo = null;
-        private boolean mInternalConfigChange;
-        private boolean mInternalFileComboChange;
-
-        /**
-         * Callback invoked when the {@link ConfigurationSelector} has been changed.
-         * <p/>
-         * The callback does the following:
-         * <ul>
-         * <li> Examine the current file name to retrieve the XML filename, if any.
-         * <li> Recompute the path based on the configuration selector (e.g. /res/values-fr/).
-         * <li> Examine the path to retrieve all the files in it. Keep those in a local cache.
-         * <li> If the XML filename from step 1 is not in the file list, it's a custom file name.
-         *      Insert it and sort it.
-         * <li> Re-populate the file combo with all the choices.
-         * <li> Select the original XML file.
-         */
-        public void run() {
-            if (mInternalConfigChange) {
-                return;
-            }
-
-            // get current leafname, if any
-            String leafName = "";  //$NON-NLS-1$
-            String currPath = mResFileCombo.getText();
-            Matcher m = mPathRegex.matcher(currPath);
-            if (m.matches()) {
-                // Note: groups 1 and 2 cannot be null.
-                leafName = m.group(2);
-                currPath = m.group(1);
-            } else {
-                // There was a path but it was invalid. Ignore it.
-                currPath = "";  //$NON-NLS-1$
-            }
-
-            // recreate the res path from the current configuration
-            mConfigSelector.getConfiguration(mTempConfig);
-            StringBuffer sb = new StringBuffer(RES_FOLDER_ABS);
-            sb.append(mTempConfig.getFolderName(ResourceFolderType.VALUES, mProject));
-            sb.append('/');
-
-            String newPath = sb.toString();
-            if (newPath.equals(currPath) && newPath.equals(mLastFolderUsedInCombo)) {
-                // Path has not changed. No need to reload.
-                return;
-            }
-
-            // Get all the files at the new path
-
-            TreeSet<String> filePaths = mFolderCache.get(newPath);
-
-            if (filePaths == null) {
-                filePaths = new TreeSet<String>();
-
-                IFolder folder = mProject.getFolder(newPath);
-                if (folder != null && folder.exists()) {
-                    try {
-                        for (IResource res : folder.members()) {
-                            String name = res.getName();
-                            if (res.getType() == IResource.FILE && name.endsWith(".xml")) {
-                                filePaths.add(newPath + name);
-                            }
-                        }
-                    } catch (CoreException e) {
-                        // Ignore.
-                    }
-                }
-
-                mFolderCache.put(newPath, filePaths);
-            }
-
-            currPath = newPath + leafName;
-            if (leafName.length() > 0 && !filePaths.contains(currPath)) {
-                filePaths.add(currPath);
-            }
-
-            // Fill the combo
-            try {
-                mInternalFileComboChange = true;
-
-                mResFileCombo.removeAll();
-
-                for (String filePath : filePaths) {
-                    mResFileCombo.add(filePath);
-                }
-
-                int index = -1;
-                if (leafName.length() > 0) {
-                    index = mResFileCombo.indexOf(currPath);
-                    if (index >= 0) {
-                        mResFileCombo.select(index);
-                    }
-                }
-
-                if (index == -1) {
-                    mResFileCombo.setText(currPath);
-                }
-
-                mLastFolderUsedInCombo = newPath;
-
-            } finally {
-                mInternalFileComboChange = false;
-            }
-
-            // finally validate the whole page
-            updateStringValueCombo();
-            validatePage();
-        }
-
-        /**
-         * Callback invoked when {@link ExtractStringInputPage#mResFileCombo} has been
-         * modified.
-         */
-        public void modifyText(ModifyEvent e) {
-            if (mInternalFileComboChange) {
-                return;
-            }
-
-            String wsFolderPath = mResFileCombo.getText();
-
-            // This is a custom path, we need to sanitize it.
-            // First it should start with "/res/". Then we need to make sure there are no
-            // relative paths, things like "../" or "./" or even "//".
-            wsFolderPath = wsFolderPath.replaceAll("/+\\.\\./+|/+\\./+|//+|\\\\+|^/+", "/");  //$NON-NLS-1$ //$NON-NLS-2$
-            wsFolderPath = wsFolderPath.replaceAll("^\\.\\./+|^\\./+", "");                   //$NON-NLS-1$ //$NON-NLS-2$
-            wsFolderPath = wsFolderPath.replaceAll("/+\\.\\.$|/+\\.$|/+$", "");               //$NON-NLS-1$ //$NON-NLS-2$
-
-            // We get "res/foo" from selections relative to the project when we want a "/res/foo" path.
-            if (wsFolderPath.startsWith(RES_FOLDER_REL)) {
-                wsFolderPath = RES_FOLDER_ABS + wsFolderPath.substring(RES_FOLDER_REL.length());
-
-                mInternalFileComboChange = true;
-                mResFileCombo.setText(wsFolderPath);
-                mInternalFileComboChange = false;
-            }
-
-            if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
-                wsFolderPath = wsFolderPath.substring(RES_FOLDER_ABS.length());
-
-                int pos = wsFolderPath.indexOf(AndroidConstants.WS_SEP_CHAR);
-                if (pos >= 0) {
-                    wsFolderPath = wsFolderPath.substring(0, pos);
-                }
-
-                String[] folderSegments = wsFolderPath.split(FolderConfiguration.QUALIFIER_SEP);
-
-                if (folderSegments.length > 0) {
-                    String folderName = folderSegments[0];
-
-                    if (folderName != null && !folderName.equals(wsFolderPath)) {
-                        // update config selector
-                        mInternalConfigChange = true;
-                        mConfigSelector.setConfiguration(folderSegments);
-                        mInternalConfigChange = false;
-                    }
-                }
-            }
-
-            updateStringValueCombo();
-            validatePage();
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java
deleted file mode 100644
index 20ef355..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java
+++ /dev/null
@@ -1,1466 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.AndroidEditor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ReferenceAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourceAttributes;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.jdt.core.IBuffer;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.ToolFactory;
-import org.eclipse.jdt.core.compiler.IScanner;
-import org.eclipse.jdt.core.compiler.ITerminalSymbols;
-import org.eclipse.jdt.core.compiler.InvalidInputException;
-import org.eclipse.jdt.core.dom.AST;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.ASTParser;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
-import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
-import org.eclipse.jface.text.ITextSelection;
-import org.eclipse.ltk.core.refactoring.Change;
-import org.eclipse.ltk.core.refactoring.ChangeDescriptor;
-import org.eclipse.ltk.core.refactoring.CompositeChange;
-import org.eclipse.ltk.core.refactoring.Refactoring;
-import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
-import org.eclipse.ltk.core.refactoring.TextFileChange;
-import org.eclipse.text.edits.InsertEdit;
-import org.eclipse.text.edits.MultiTextEdit;
-import org.eclipse.text.edits.ReplaceEdit;
-import org.eclipse.text.edits.TextEdit;
-import org.eclipse.text.edits.TextEditGroup;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
-import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
-import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
-import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
-import org.w3c.dom.Node;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This refactoring extracts a string from a file and replaces it by an Android resource ID
- * such as R.string.foo.
- * <p/>
- * There are a number of scenarios, which are not all supported yet. The workflow works as
- * such:
- * <ul>
- * <li> User selects a string in a Java (TODO: or XML file) and invokes
- *      the {@link ExtractStringAction}.
- * <li> The action finds the {@link ICompilationUnit} being edited as well as the current
- *      {@link ITextSelection}. The action creates a new instance of this refactoring as
- *      well as an {@link ExtractStringWizard} and runs the operation.
- * <li> Step 1 of the refactoring is to check the preliminary conditions. Right now we check
- *      that the java source is not read-only and is in sync. We also try to find a string under
- *      the selection. If this fails, the refactoring is aborted.
- * <li> TODO: Find the string in an XML file based on selection.
- * <li> On success, the wizard is shown, which let the user input the new ID to use.
- * <li> The wizard sets the user input values into this refactoring instance, e.g. the new string
- *      ID, the XML file to update, etc. The wizard does use the utility method
- *      {@link XmlStringFileHelper#valueOfStringId(IProject, String, String)} to check whether
- *      the new ID is already defined in the target XML file.
- * <li> Once Preview or Finish is selected in the wizard, the
- *      {@link #checkFinalConditions(IProgressMonitor)} is called to double-check the user input
- *      and compute the actual changes.
- * <li> When all changes are computed, {@link #createChange(IProgressMonitor)} is invoked.
- * </ul>
- *
- * The list of changes are:
- * <ul>
- * <li> If the target XML does not exist, create it with the new string ID.
- * <li> If the target XML exists, find the <resources> node and add the new string ID right after.
- *      If the node is <resources/>, it needs to be opened.
- * <li> Create an AST rewriter to edit the source Java file and replace all occurences by the
- *      new computed R.string.foo. Also need to rewrite imports to import R as needed.
- *      If there's already a conflicting R included, we need to insert the FQCN instead.
- * <li> TODO: Have a pref in the wizard: [x] Change other XML Files
- * <li> TODO: Have a pref in the wizard: [x] Change other Java Files
- * </ul>
- */
-public class ExtractStringRefactoring extends Refactoring {
-
-    public enum Mode {
-        /**
-         * the Extract String refactoring is called on an <em>existing</em> source file.
-         * Its purpose is then to get the selected string of the source and propose to
-         * change it by an XML id. The XML id may be a new one or an existing one.
-         */
-        EDIT_SOURCE,
-        /**
-         * The Extract String refactoring is called without any source file.
-         * Its purpose is then to create a new XML string ID or select/modify an existing one.
-         */
-        SELECT_ID,
-        /**
-         * The Extract String refactoring is called without any source file.
-         * Its purpose is then to create a new XML string ID. The ID must not already exist.
-         */
-        SELECT_NEW_ID
-    }
-
-    /** The {@link Mode} of operation of the refactoring. */
-    private final Mode mMode;
-    /** Non-null when editing an Android Resource XML file: identifies the attribute name
-     * of the value being edited. When null, the source is an Android Java file. */
-    private String mXmlAttributeName;
-    /** The file model being manipulated.
-     * Value is null when not on {@link Mode#EDIT_SOURCE} mode. */
-    private final IFile mFile;
-    /** The editor. Non-null when invoked from {@link ExtractStringAction}. Null otherwise. */
-    private final IEditorPart mEditor;
-    /** The project that contains {@link #mFile} and that contains the target XML file to modify. */
-    private final IProject mProject;
-    /** The start of the selection in {@link #mFile}.
-     * Value is -1 when not on {@link Mode#EDIT_SOURCE} mode. */
-    private final int mSelectionStart;
-    /** The end of the selection in {@link #mFile}.
-     * Value is -1 when not on {@link Mode#EDIT_SOURCE} mode. */
-    private final int mSelectionEnd;
-
-    /** The compilation unit, only defined if {@link #mFile} points to a usable Java source file. */
-    private ICompilationUnit mUnit;
-    /** The actual string selected, after UTF characters have been escaped, good for display.
-     * Value is null when not on {@link Mode#EDIT_SOURCE} mode. */
-    private String mTokenString;
-
-    /** The XML string ID selected by the user in the wizard. */
-    private String mXmlStringId;
-    /** The XML string value. Might be different than the initial selected string. */
-    private String mXmlStringValue;
-    /** The path of the XML file that will define {@link #mXmlStringId}, selected by the user
-     *  in the wizard. */
-    private String mTargetXmlFileWsPath;
-
-    /** The list of changes computed by {@link #checkFinalConditions(IProgressMonitor)} and
-     *  used by {@link #createChange(IProgressMonitor)}. */
-    private ArrayList<Change> mChanges;
-
-    private XmlStringFileHelper mXmlHelper = new XmlStringFileHelper();
-
-    private static final String KEY_MODE = "mode";              //$NON-NLS-1$
-    private static final String KEY_FILE = "file";              //$NON-NLS-1$
-    private static final String KEY_PROJECT = "proj";           //$NON-NLS-1$
-    private static final String KEY_SEL_START = "sel-start";    //$NON-NLS-1$
-    private static final String KEY_SEL_END = "sel-end";        //$NON-NLS-1$
-    private static final String KEY_TOK_ESC = "tok-esc";        //$NON-NLS-1$
-    private static final String KEY_XML_ATTR_NAME = "xml-attr-name";      //$NON-NLS-1$
-
-    public ExtractStringRefactoring(Map<String, String> arguments) throws NullPointerException {
-        mMode = Mode.valueOf(arguments.get(KEY_MODE));
-
-        IPath path = Path.fromPortableString(arguments.get(KEY_PROJECT));
-        mProject = (IProject) ResourcesPlugin.getWorkspace().getRoot().findMember(path);
-
-        if (mMode == Mode.EDIT_SOURCE) {
-            path = Path.fromPortableString(arguments.get(KEY_FILE));
-            mFile = (IFile) ResourcesPlugin.getWorkspace().getRoot().findMember(path);
-
-            mSelectionStart = Integer.parseInt(arguments.get(KEY_SEL_START));
-            mSelectionEnd   = Integer.parseInt(arguments.get(KEY_SEL_END));
-            mTokenString    = arguments.get(KEY_TOK_ESC);
-            mXmlAttributeName = arguments.get(KEY_XML_ATTR_NAME);
-        } else {
-            mFile = null;
-            mSelectionStart = mSelectionEnd = -1;
-            mTokenString = null;
-            mXmlAttributeName = null;
-        }
-
-        mEditor = null;
-    }
-
-    private Map<String, String> createArgumentMap() {
-        HashMap<String, String> args = new HashMap<String, String>();
-        args.put(KEY_MODE,      mMode.name());
-        args.put(KEY_PROJECT,   mProject.getFullPath().toPortableString());
-        if (mMode == Mode.EDIT_SOURCE) {
-            args.put(KEY_FILE,      mFile.getFullPath().toPortableString());
-            args.put(KEY_SEL_START, Integer.toString(mSelectionStart));
-            args.put(KEY_SEL_END,   Integer.toString(mSelectionEnd));
-            args.put(KEY_TOK_ESC,   mTokenString);
-            args.put(KEY_XML_ATTR_NAME, mXmlAttributeName);
-        }
-        return args;
-    }
-
-    /**
-     * Constructor to use when the Extract String refactoring is called on an
-     * *existing* source file. Its purpose is then to get the selected string of
-     * the source and propose to change it by an XML id. The XML id may be a new one
-     * or an existing one.
-     *
-     * @param file The source file to process. Cannot be null. File must exist in workspace.
-     * @param editor
-     * @param selection The selection in the source file. Cannot be null or empty.
-     */
-    public ExtractStringRefactoring(IFile file, IEditorPart editor, ITextSelection selection) {
-        mMode = Mode.EDIT_SOURCE;
-        mFile = file;
-        mEditor = editor;
-        mProject = file.getProject();
-        mSelectionStart = selection.getOffset();
-        mSelectionEnd = mSelectionStart + Math.max(0, selection.getLength() - 1);
-    }
-
-    /**
-     * Constructor to use when the Extract String refactoring is called without
-     * any source file. Its purpose is then to create a new XML string ID.
-     *
-     * @param project The project where the target XML file to modify is located. Cannot be null.
-     * @param enforceNew If true the XML ID must be a new one. If false, an existing ID can be
-     *  used.
-     */
-    public ExtractStringRefactoring(IProject project, boolean enforceNew) {
-        mMode = enforceNew ? Mode.SELECT_NEW_ID : Mode.SELECT_ID;
-        mFile = null;
-        mEditor = null;
-        mProject = project;
-        mSelectionStart = mSelectionEnd = -1;
-    }
-
-    /**
-     * @see org.eclipse.ltk.core.refactoring.Refactoring#getName()
-     */
-    @Override
-    public String getName() {
-        if (mMode == Mode.SELECT_ID) {
-            return "Create or USe Android String";
-        } else if (mMode == Mode.SELECT_NEW_ID) {
-            return "Create New Android String";
-        }
-
-        return "Extract Android String";
-    }
-
-    public Mode getMode() {
-        return mMode;
-    }
-
-    /**
-     * Gets the actual string selected, after UTF characters have been escaped,
-     * good for display.
-     */
-    public String getTokenString() {
-        return mTokenString;
-    }
-
-    public String getXmlStringId() {
-        return mXmlStringId;
-    }
-
-    /**
-     * Step 1 of 3 of the refactoring:
-     * Checks that the current selection meets the initial condition before the ExtractString
-     * wizard is shown. The check is supposed to be lightweight and quick. Note that at that
-     * point the wizard has not been created yet.
-     * <p/>
-     * Here we scan the source buffer to find the token matching the selection.
-     * The check is successful is a Java string literal is selected, the source is in sync
-     * and is not read-only.
-     * <p/>
-     * This is also used to extract the string to be modified, so that we can display it in
-     * the refactoring wizard.
-     *
-     * @see org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
-     *
-     * @throws CoreException
-     */
-    @Override
-    public RefactoringStatus checkInitialConditions(IProgressMonitor monitor)
-            throws CoreException, OperationCanceledException {
-
-        mUnit = null;
-        mTokenString = null;
-
-        RefactoringStatus status = new RefactoringStatus();
-
-        try {
-            monitor.beginTask("Checking preconditions...", 6);
-
-            if (mMode != Mode.EDIT_SOURCE) {
-                monitor.worked(6);
-                return status;
-            }
-
-            if (!checkSourceFile(mFile, status, monitor)) {
-                return status;
-            }
-
-            // Try to get a compilation unit from this file. If it fails, mUnit is null.
-            try {
-                mUnit = JavaCore.createCompilationUnitFrom(mFile);
-
-                // Make sure the unit is not read-only, e.g. it's not a class file or inside a Jar
-                if (mUnit.isReadOnly()) {
-                    status.addFatalError("The file is read-only, please make it writeable first.");
-                    return status;
-                }
-
-                // This is a Java file. Check if it contains the selection we want.
-                if (!findSelectionInJavaUnit(mUnit, status, monitor)) {
-                    return status;
-                }
-
-            } catch (Exception e) {
-                // That was not a Java file. Ignore.
-            }
-
-            if (mUnit != null) {
-                monitor.worked(1);
-                return status;
-            }
-
-            // Check this a Layout XML file and get the selection and its context.
-            if (mFile != null && AndroidConstants.EXT_XML.equals(mFile.getFileExtension())) {
-
-                // Currently we only support Android resource XML files, so they must have a path
-                // similar to
-                //    project/res/<type>[-<configuration>]/*.xml
-                // There is no support for sub folders, so the segment count must be 4.
-                // We don't need to check the type folder name because a/ we only accept
-                // an AndroidEditor source and b/ aapt generates a compilation error for
-                // unknown folders.
-                IPath path = mFile.getFullPath();
-                // check if we are inside the project/res/* folder.
-                if (path.segmentCount() == 4) {
-                    if (path.segment(1).equalsIgnoreCase(SdkConstants.FD_RESOURCES)) {
-                        if (!findSelectionInXmlFile(mFile, status, monitor)) {
-                            return status;
-                        }
-                    }
-                }
-            }
-
-            if (!status.isOK()) {
-                status.addFatalError(
-                        "Selection must be inside a Java source or an Android Layout XML file.");
-            }
-
-        } finally {
-            monitor.done();
-        }
-
-        return status;
-    }
-
-    /**
-     * Try to find the selected Java element in the compilation unit.
-     *
-     * If selection matches a string literal, capture it, otherwise add a fatal error
-     * to the status.
-     *
-     * On success, advance the monitor by 3.
-     * Returns status.isOK().
-     */
-    private boolean findSelectionInJavaUnit(ICompilationUnit unit,
-            RefactoringStatus status, IProgressMonitor monitor) {
-        try {
-            IBuffer buffer = unit.getBuffer();
-
-            IScanner scanner = ToolFactory.createScanner(
-                    false, //tokenizeComments
-                    false, //tokenizeWhiteSpace
-                    false, //assertMode
-                    false  //recordLineSeparator
-                    );
-            scanner.setSource(buffer.getCharacters());
-            monitor.worked(1);
-
-            for(int token = scanner.getNextToken();
-                    token != ITerminalSymbols.TokenNameEOF;
-                    token = scanner.getNextToken()) {
-                if (scanner.getCurrentTokenStartPosition() <= mSelectionStart &&
-                        scanner.getCurrentTokenEndPosition() >= mSelectionEnd) {
-                    // found the token, but only keep if the right type
-                    if (token == ITerminalSymbols.TokenNameStringLiteral) {
-                        mTokenString = new String(scanner.getCurrentTokenSource());
-                    }
-                    break;
-                } else if (scanner.getCurrentTokenStartPosition() > mSelectionEnd) {
-                    // scanner is past the selection, abort.
-                    break;
-                }
-            }
-        } catch (JavaModelException e1) {
-            // Error in unit.getBuffer. Ignore.
-        } catch (InvalidInputException e2) {
-            // Error in scanner.getNextToken. Ignore.
-        } finally {
-            monitor.worked(1);
-        }
-
-        if (mTokenString != null) {
-            // As a literal string, the token should have surrounding quotes. Remove them.
-            int len = mTokenString.length();
-            if (len > 0 &&
-                    mTokenString.charAt(0) == '"' &&
-                    mTokenString.charAt(len - 1) == '"') {
-                mTokenString = mTokenString.substring(1, len - 1);
-            }
-            // We need a non-empty string literal
-            if (mTokenString.length() == 0) {
-                mTokenString = null;
-            }
-        }
-
-        if (mTokenString == null) {
-            status.addFatalError("Please select a Java string literal.");
-        }
-
-        monitor.worked(1);
-        return status.isOK();
-    }
-    /**
-     * Try to find the selected XML element. This implementation replies on the refactoring
-     * originating from an Android Layout Editor. We rely on some internal properties of the
-     * Structured XML editor to retrieve file content to avoid parsing it again. We also rely
-     * on our specific Android XML model to get element & attribute descriptor properties.
-     *
-     * If selection matches a string literal, capture it, otherwise add a fatal error
-     * to the status.
-     *
-     * On success, advance the monitor by 1.
-     * Returns status.isOK().
-     */
-    private boolean findSelectionInXmlFile(IFile file,
-            RefactoringStatus status,
-            IProgressMonitor monitor) {
-
-        try {
-            if (!(mEditor instanceof AndroidEditor)) {
-                status.addFatalError("Only the Android XML Editor is currently supported.");
-                return status.isOK();
-            }
-
-            AndroidEditor editor = (AndroidEditor) mEditor;
-            IStructuredModel smodel = null;
-            Node node = null;
-            String currAttrName = null;
-
-            try {
-                // See the portability note in AndroidEditor#getModelForRead() javadoc.
-                smodel = editor.getModelForRead();
-                if (smodel != null) {
-                    // The structured model gives the us the actual XML Node element where the
-                    // offset is. By using this Node, we can find the exact UiElementNode of our
-                    // model and thus we'll be able to get the properties of the attribute -- to
-                    // check if it accepts a string reference. This does not however tell us if
-                    // the selection is actually in an attribute value, nor which attribute is
-                    // being edited.
-                    for(int offset = mSelectionStart; offset >= 0 && node == null; --offset) {
-                        node = (Node) smodel.getIndexedRegion(offset);
-                    }
-
-                    if (node == null) {
-                        status.addFatalError(
-                                "The selection does not match any element in the XML document.");
-                        return status.isOK();
-                    }
-
-                    if (node.getNodeType() != Node.ELEMENT_NODE) {
-                        status.addFatalError("The selection is not inside an actual XML element.");
-                        return status.isOK();
-                    }
-
-                    IStructuredDocument sdoc = smodel.getStructuredDocument();
-                    if (sdoc != null) {
-                        // Portability note: all the structured document implementation is
-                        // under wst.sse.core.internal.provisional so we can expect it to change in
-                        // a distant future if they start cleaning their codebase, however unlikely
-                        // that is.
-
-                        int selStart = mSelectionStart;
-                        IStructuredDocumentRegion region =
-                            sdoc.getRegionAtCharacterOffset(selStart);
-                        if (region != null &&
-                                DOMRegionContext.XML_TAG_NAME.equals(region.getType())) {
-                            // Find if any sub-region representing an attribute contains the
-                            // selection. If it does, returns the name of the attribute in
-                            // currAttrName and returns the value in the field mTokenString.
-                            currAttrName = findSelectionInRegion(region, selStart);
-
-                            if (mTokenString == null) {
-                                status.addFatalError(
-                                    "The selection is not inside an actual XML attribute value.");
-                            }
-                        }
-                    }
-
-                    if (mTokenString != null && node != null && currAttrName != null) {
-
-                        // Validate that the attribute accepts a string reference.
-                        // This sets mTokenString to null by side-effect when it fails and
-                        // adds a fatal error to the status as needed.
-                        validateSelectedAttribute(editor, node, currAttrName, status);
-
-                    } else {
-                        // We shouldn't get here: we're missing one of the token string, the node
-                        // or the attribute name. All of them have been checked earlier so don't
-                        // set any specific error.
-                        mTokenString = null;
-                    }
-                }
-            } finally {
-                if (smodel != null) {
-                    smodel.releaseFromRead();
-                }
-            }
-
-        } finally {
-            monitor.worked(1);
-        }
-
-        return status.isOK();
-    }
-
-    /**
-     * The region gives us the textual representation of the XML element
-     * where the selection starts, split using sub-regions. We now just
-     * need to iterate through the sub-regions to find which one
-     * contains the actual selection. We're interested in an attribute
-     * value however when we find one we want to memorize the attribute
-     * name that was defined just before.
-     *
-     * @return When the cursor is on a valid attribute name or value, returns the string of
-     * attribute name. As a side-effect, returns the value of the attribute in {@link #mTokenString}
-     */
-    private String findSelectionInRegion(IStructuredDocumentRegion region, int selStart) {
-
-        String currAttrName = null;
-
-        int startInRegion = selStart - region.getStartOffset();
-
-        int nb = region.getNumberOfRegions();
-        ITextRegionList list = region.getRegions();
-        String currAttrValue = null;
-
-        for (int i = 0; i < nb; i++) {
-            ITextRegion subRegion = list.get(i);
-            String type = subRegion.getType();
-
-            if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) {
-                currAttrName = region.getText(subRegion);
-
-                // I like to select the attribute definition and invoke
-                // the extract string wizard. So if the selection is on
-                // the attribute name part, find the value that is just
-                // after and use it as if it were the selection.
-
-                if (subRegion.getStart() <= startInRegion &&
-                        startInRegion < subRegion.getTextEnd()) {
-                    // A well-formed attribute is composed of a name,
-                    // an equal sign and the value. There can't be any space
-                    // in between, which makes the parsing a lot easier.
-                    if (i <= nb - 3 &&
-                            DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS.equals(
-                                                   list.get(i + 1).getType())) {
-                        subRegion = list.get(i + 2);
-                        type = subRegion.getType();
-                        if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(
-                                type)) {
-                            currAttrValue = region.getText(subRegion);
-                        }
-                    }
-                }
-
-            } else if (subRegion.getStart() <= startInRegion &&
-                    startInRegion < subRegion.getTextEnd() &&
-                    DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) {
-                currAttrValue = region.getText(subRegion);
-            }
-
-            if (currAttrValue != null) {
-                // We found the value. Only accept it if not empty
-                // and if we found an attribute name before.
-                String text = currAttrValue;
-
-                // The attribute value will contain the XML quotes. Remove them.
-                int len = text.length();
-                if (len >= 2 &&
-                        text.charAt(0) == '"' &&
-                        text.charAt(len - 1) == '"') {
-                    text = text.substring(1, len - 1);
-                } else if (len >= 2 &&
-                        text.charAt(0) == '\'' &&
-                        text.charAt(len - 1) == '\'') {
-                    text = text.substring(1, len - 1);
-                }
-                if (text.length() > 0 && currAttrName != null) {
-                    // Setting mTokenString to non-null marks the fact we
-                    // accept this attribute.
-                    mTokenString = text;
-                }
-
-                break;
-            }
-        }
-
-        return currAttrName;
-    }
-
-    /**
-     * Validates that the attribute accepts a string reference.
-     * This sets mTokenString to null by side-effect when it fails and
-     * adds a fatal error to the status as needed.
-     */
-    private void validateSelectedAttribute(AndroidEditor editor, Node node,
-            String attrName, RefactoringStatus status) {
-        UiElementNode rootUiNode = editor.getUiRootNode();
-        UiElementNode currentUiNode =
-            rootUiNode == null ? null : rootUiNode.findXmlNode(node);
-        ReferenceAttributeDescriptor attrDesc = null;
-
-        if (currentUiNode != null) {
-            // remove any namespace prefix from the attribute name
-            String name = attrName;
-            int pos = name.indexOf(':');
-            if (pos > 0 && pos < name.length() - 1) {
-                name = name.substring(pos + 1);
-            }
-
-            for (UiAttributeNode attrNode : currentUiNode.getUiAttributes()) {
-                if (attrNode.getDescriptor().getXmlLocalName().equals(name)) {
-                    AttributeDescriptor desc = attrNode.getDescriptor();
-                    if (desc instanceof ReferenceAttributeDescriptor) {
-                        attrDesc = (ReferenceAttributeDescriptor) desc;
-                    }
-                    break;
-                }
-            }
-        }
-
-        // The attribute descriptor is a resource reference. It must either accept
-        // of any resource type or specifically accept string types.
-        if (attrDesc != null &&
-                (attrDesc.getResourceType() == null ||
-                 attrDesc.getResourceType() == ResourceType.STRING)) {
-            // We have one more check to do: is the current string value already
-            // an Android XML string reference? If so, we can't edit it.
-            if (mTokenString.startsWith("@")) {                             //$NON-NLS-1$
-                int pos1 = 0;
-                if (mTokenString.length() > 1 && mTokenString.charAt(1) == '+') {
-                    pos1++;
-                }
-                int pos2 = mTokenString.indexOf('/');
-                if (pos2 > pos1) {
-                    String kind = mTokenString.substring(pos1 + 1, pos2);
-                    if (ResourceType.STRING.getName().equals(kind)) {                            //$NON-NLS-1$
-                        mTokenString = null;
-                        status.addFatalError(String.format(
-                                "The attribute %1$s already contains a %2$s reference.",
-                                attrName,
-                                kind));
-                    }
-                }
-            }
-
-            if (mTokenString != null) {
-                // We're done with all our checks. mTokenString contains the
-                // current attribute value. We don't memorize the region nor the
-                // attribute, however we memorize the textual attribute name so
-                // that we can offer replacement for all its occurrences.
-                mXmlAttributeName = attrName;
-            }
-
-        } else {
-            mTokenString = null;
-            status.addFatalError(String.format(
-                    "The attribute %1$s does not accept a string reference.",
-                    attrName));
-        }
-    }
-
-    /**
-     * Tests from org.eclipse.jdt.internal.corext.refactoringChecks#validateEdit()
-     * Might not be useful.
-     *
-     * On success, advance the monitor by 2.
-     *
-     * @return False if caller should abort, true if caller should continue.
-     */
-    private boolean checkSourceFile(IFile file,
-            RefactoringStatus status,
-            IProgressMonitor monitor) {
-        // check whether the source file is in sync
-        if (!file.isSynchronized(IResource.DEPTH_ZERO)) {
-            status.addFatalError("The file is not synchronized. Please save it first.");
-            return false;
-        }
-        monitor.worked(1);
-
-        // make sure we can write to it.
-        ResourceAttributes resAttr = file.getResourceAttributes();
-        if (resAttr == null || resAttr.isReadOnly()) {
-            status.addFatalError("The file is read-only, please make it writeable first.");
-            return false;
-        }
-        monitor.worked(1);
-
-        return true;
-    }
-
-    /**
-     * Step 2 of 3 of the refactoring:
-     * Check the conditions once the user filled values in the refactoring wizard,
-     * then prepare the changes to be applied.
-     * <p/>
-     * In this case, most of the sanity checks are done by the wizard so essentially this
-     * should only be called if the wizard positively validated the user input.
-     *
-     * Here we do check that the target resource XML file either does not exists or
-     * is not read-only.
-     *
-     * @see org.eclipse.ltk.core.refactoring.Refactoring#checkFinalConditions(IProgressMonitor)
-     *
-     * @throws CoreException
-     */
-    @Override
-    public RefactoringStatus checkFinalConditions(IProgressMonitor monitor)
-            throws CoreException, OperationCanceledException {
-        RefactoringStatus status = new RefactoringStatus();
-
-        try {
-            monitor.beginTask("Checking post-conditions...", 3);
-
-            if (mXmlStringId == null || mXmlStringId.length() <= 0) {
-                // this is not supposed to happen
-                status.addFatalError("Missing replacement string ID");
-            } else if (mTargetXmlFileWsPath == null || mTargetXmlFileWsPath.length() <= 0) {
-                // this is not supposed to happen
-                status.addFatalError("Missing target xml file path");
-            }
-            monitor.worked(1);
-
-            // Either that resource must not exist or it must be a writeable file.
-            IResource targetXml = getTargetXmlResource(mTargetXmlFileWsPath);
-            if (targetXml != null) {
-                if (targetXml.getType() != IResource.FILE) {
-                    status.addFatalError(
-                            String.format("XML file '%1$s' is not a file.", mTargetXmlFileWsPath));
-                } else {
-                    ResourceAttributes attr = targetXml.getResourceAttributes();
-                    if (attr != null && attr.isReadOnly()) {
-                        status.addFatalError(
-                                String.format("XML file '%1$s' is read-only.",
-                                        mTargetXmlFileWsPath));
-                    }
-                }
-            }
-            monitor.worked(1);
-
-            if (status.hasError()) {
-                return status;
-            }
-
-            mChanges = new ArrayList<Change>();
-
-
-            // Prepare the change for the XML file.
-
-            if (mXmlHelper.valueOfStringId(mProject, mTargetXmlFileWsPath, mXmlStringId) == null) {
-                // We actually change it only if the ID doesn't exist yet
-                Change change = createXmlChange((IFile) targetXml, mXmlStringId, mXmlStringValue,
-                        status, SubMonitor.convert(monitor, 1));
-                if (change != null) {
-                    mChanges.add(change);
-                }
-            }
-
-            if (status.hasError()) {
-                return status;
-            }
-
-            if (mMode == Mode.EDIT_SOURCE) {
-                List<Change> changes = null;
-                if (mXmlAttributeName != null) {
-                    // Prepare the change to the Android resource XML file
-                    changes = computeXmlSourceChanges(mFile,
-                            mXmlStringId, mTokenString, mXmlAttributeName,
-                            status, monitor);
-
-                } else {
-                    // Prepare the change to the Java compilation unit
-                    changes = computeJavaChanges(mUnit, mXmlStringId, mTokenString,
-                            status, SubMonitor.convert(monitor, 1));
-                }
-                if (changes != null) {
-                    mChanges.addAll(changes);
-                }
-            }
-
-            monitor.worked(1);
-        } finally {
-            monitor.done();
-        }
-
-        return status;
-    }
-
-    /**
-     * Internal helper that actually prepares the {@link Change} that adds the given
-     * ID to the given XML File.
-     * <p/>
-     * This does not actually modify the file.
-     *
-     * @param targetXml The file resource to modify.
-     * @param xmlStringId The new ID to insert.
-     * @param tokenString The old string, which will be the value in the XML string.
-     * @return A new {@link TextEdit} that describes how to change the file.
-     */
-    private Change createXmlChange(IFile targetXml,
-            String xmlStringId,
-            String tokenString,
-            RefactoringStatus status,
-            SubMonitor subMonitor) {
-
-        TextFileChange xmlChange = new TextFileChange(getName(), targetXml);
-        xmlChange.setTextType("xml");   //$NON-NLS-1$
-
-        TextEdit edit = null;
-        TextEditGroup editGroup = null;
-
-        if (!targetXml.exists()) {
-            // The XML file does not exist. Simply create it.
-            StringBuilder content = new StringBuilder();
-            content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); //$NON-NLS-1$
-            content.append("<resources>\n");                                //$NON-NLS-1$
-            content.append("    <string name=\"").                          //$NON-NLS-1$
-                        append(xmlStringId).
-                        append("\">").                                      //$NON-NLS-1$
-                        append(tokenString).
-                        append("</string>\n");                              //$NON-NLS-1$
-            content.append("</resources>\n");                                //$NON-NLS-1$
-
-            edit = new InsertEdit(0, content.toString());
-            editGroup = new TextEditGroup("Create <string> in new XML file", edit);
-        } else {
-            // The file exist. Attempt to parse it as a valid XML document.
-            try {
-                int[] indices = new int[2];
-
-                // TODO case where we replace the value of an existing XML String ID
-
-                if (findXmlOpeningTagPos(targetXml.getContents(), "resources", indices)) {  //$NON-NLS-1$
-                    // Indices[1] indicates whether we found > or />. It can only be 1 or 2.
-                    // Indices[0] is the position of the first character of either > or />.
-                    //
-                    // Note: we don't even try to adapt our formatting to the existing structure (we
-                    // could by capturing whatever whitespace is after the closing bracket and
-                    // applying it here before our tag, unless we were dealing with an empty
-                    // resource tag.)
-
-                    int offset = indices[0];
-                    int len = indices[1];
-                    StringBuilder content = new StringBuilder();
-                    content.append(">\n");                                      //$NON-NLS-1$
-                    content.append("    <string name=\"").                      //$NON-NLS-1$
-                                append(xmlStringId).
-                                append("\">").                                  //$NON-NLS-1$
-                                append(tokenString).
-                                append("</string>");                            //$NON-NLS-1$
-                    if (len == 2) {
-                        content.append("\n</resources>");                       //$NON-NLS-1$
-                    }
-
-                    edit = new ReplaceEdit(offset, len, content.toString());
-                    editGroup = new TextEditGroup("Insert <string> in XML file", edit);
-                }
-            } catch (CoreException e) {
-                // Failed to read file. Ignore. Will return null below.
-            }
-        }
-
-        if (edit == null) {
-            status.addFatalError(String.format("Failed to modify file %1$s",
-                    mTargetXmlFileWsPath));
-            return null;
-        }
-
-        xmlChange.setEdit(edit);
-        // The TextEditChangeGroup let the user toggle this change on and off later.
-        xmlChange.addTextEditChangeGroup(new TextEditChangeGroup(xmlChange, editGroup));
-
-        subMonitor.worked(1);
-        return xmlChange;
-    }
-
-    /**
-     * Parse an XML input stream, looking for an opening tag.
-     * <p/>
-     * If found, returns the character offest in the buffer of the closing bracket of that
-     * tag, e.g. the position of > in "<resources>". The first character is at offset 0.
-     * <p/>
-     * The implementation here relies on a simple character-based parser. No DOM nor SAX
-     * parsing is used, due to the simplified nature of the task: we just want the first
-     * opening tag, which in our case should be the document root. We deal however with
-     * with the tag being commented out, so comments are skipped. We assume the XML doc
-     * is sane, e.g. we don't expect the tag to appear in the middle of a string. But
-     * again since in fact we want the root element, that's unlikely to happen.
-     * <p/>
-     * We need to deal with the case where the element is written as <resources/>, in
-     * which case the caller will want to replace /> by ">...</...>". To do that we return
-     * two values: the first offset of the closing tag (e.g. / or >) and the length, which
-     * can only be 1 or 2. If it's 2, the caller has to deal with /> instead of just >.
-     *
-     * @param contents An existing buffer to parse.
-     * @param tag The tag to look for.
-     * @param indices The return values: [0] is the offset of the closing bracket and [1] is
-     *          the length which can be only 1 for > and 2 for />
-     * @return True if we found the tag, in which case <code>indices</code> can be used.
-     */
-    private boolean findXmlOpeningTagPos(InputStream contents, String tag, int[] indices) {
-
-        BufferedReader br = new BufferedReader(new InputStreamReader(contents));
-        StringBuilder sb = new StringBuilder(); // scratch area
-
-        tag = "<" + tag;
-        int tagLen = tag.length();
-        int maxLen = tagLen < 3 ? 3 : tagLen;
-
-        try {
-            int offset = 0;
-            int i = 0;
-            char searching = '<'; // we want opening tags
-            boolean capture = false;
-            boolean inComment = false;
-            boolean inTag = false;
-            while ((i = br.read()) != -1) {
-                char c = (char) i;
-                if (c == searching) {
-                    capture = true;
-                }
-                if (capture) {
-                    sb.append(c);
-                    int len = sb.length();
-                    if (inComment && c == '>') {
-                        // is the comment being closed?
-                        if (len >= 3 && sb.substring(len-3).equals("-->")) {    //$NON-NLS-1$
-                            // yes, comment is closing, stop capturing
-                            capture = false;
-                            inComment = false;
-                            sb.setLength(0);
-                        }
-                    } else if (inTag && c == '>') {
-                        // we're capturing in our tag, waiting for the closing >, we just got it
-                        // so we're totally done here. Simply detect whether it's /> or >.
-                        indices[0] = offset;
-                        indices[1] = 1;
-                        if (sb.charAt(len - 2) == '/') {
-                            indices[0]--;
-                            indices[1]++;
-                        }
-                        return true;
-
-                    } else if (!inComment && !inTag) {
-                        // not a comment and not our tag yet, so we're capturing because a
-                        // tag is being opened but we don't know which one yet.
-
-                        // look for either the opening or a comment or
-                        // the opening of our tag.
-                        if (len == 3 && sb.equals("<--")) {                     //$NON-NLS-1$
-                            inComment = true;
-                        } else if (len == tagLen && sb.toString().equals(tag)) {
-                            inTag = true;
-                        }
-
-                        // if we're not interested in this tag yet, deal with when to stop
-                        // capturing: the opening tag ends with either any kind of whitespace
-                        // or with a > or maybe there's a PI that starts with <?
-                        if (!inComment && !inTag) {
-                            if (c == '>' || c == '?' || c == ' ' || c == '\n' || c == '\r') {
-                                // stop capturing
-                                capture = false;
-                                sb.setLength(0);
-                            }
-                        }
-                    }
-
-                    if (capture && len > maxLen) {
-                        // in any case we don't need to capture more than the size of our tag
-                        // or the comment opening tag
-                        sb.deleteCharAt(0);
-                    }
-                }
-                offset++;
-            }
-        } catch (IOException e) {
-            // Ignore.
-        } finally {
-            try {
-                br.close();
-            } catch (IOException e) {
-                // oh come on...
-            }
-        }
-
-        return false;
-    }
-
-
-    /**
-     * Computes the changes to be made to the source Android XML file(s) and
-     * returns a list of {@link Change}.
-     */
-    private List<Change> computeXmlSourceChanges(IFile sourceFile,
-            String xmlStringId,
-            String tokenString,
-            String xmlAttrName,
-            RefactoringStatus status,
-            IProgressMonitor monitor) {
-
-        if (!sourceFile.exists()) {
-            status.addFatalError(String.format("XML file '%1$s' does not exist.",
-                    sourceFile.getFullPath().toOSString()));
-            return null;
-        }
-
-        // In the initial condition check we validated that this file is part of
-        // an Android resource folder, with a folder path that looks like
-        //   /project/res/<type>-<configuration>/<filename.xml>
-        // Here we are going to offer XML source change for the same filename accross all
-        // configurations of the same res type. E.g. if we're processing a res/layout/main.xml
-        // file then we want to offer changes for res/layout-fr/main.xml. We compute such a
-        // list here.
-        HashSet<IFile> files = new HashSet<IFile>();
-        files.add(sourceFile);
-
-        if (AndroidConstants.EXT_XML.equals(sourceFile.getFileExtension())) {
-            IPath path = sourceFile.getFullPath();
-            if (path.segmentCount() == 4 && path.segment(1).equals(SdkConstants.FD_RESOURCES)) {
-                IProject project = sourceFile.getProject();
-                String filename = path.segment(3);
-                String initialTypeName = path.segment(2);
-                ResourceFolderType type = ResourceFolderType.getFolderType(initialTypeName);
-
-                IContainer res = sourceFile.getParent().getParent();
-                if (type != null && res != null && res.getType() == IResource.FOLDER) {
-                    try {
-                        for (IResource r : res.members()) {
-                            if (r != null && r.getType() == IResource.FOLDER) {
-                                String name = r.getName();
-                                // Skip the initial folder name, it's already in the list.
-                                if (!name.equals(initialTypeName)) {
-                                    // Only accept the same folder type (e.g. layout-*)
-                                    ResourceFolderType t =
-                                        ResourceFolderType.getFolderType(name);
-                                    if (type.equals(t)) {
-                                        // recompute the path
-                                        IPath p = res.getProjectRelativePath().append(name).
-                                                                               append(filename);
-                                        IResource f = project.findMember(p);
-                                        if (f != null && f instanceof IFile) {
-                                            files.add((IFile) f);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    } catch (CoreException e) {
-                        // Ignore.
-                    }
-                }
-            }
-        }
-
-        SubMonitor subMonitor = SubMonitor.convert(monitor, Math.min(1, files.size()));
-
-        ArrayList<Change> changes = new ArrayList<Change>();
-
-        try {
-            // Portability note: getModelManager is part of wst.sse.core however the
-            // interface returned is part of wst.sse.core.internal.provisional so we can
-            // expect it to change in a distant future if they start cleaning their codebase,
-            // however unlikely that is.
-            IModelManager modelManager = StructuredModelManager.getModelManager();
-
-            for (IFile file : files) {
-
-                IStructuredDocument sdoc = modelManager.createStructuredDocumentFor(file);
-
-                if (sdoc == null) {
-                    status.addFatalError("XML structured document not found");     //$NON-NLS-1$
-                    return null;
-                }
-
-                TextFileChange xmlChange = new TextFileChange(getName(), file);
-                xmlChange.setTextType("xml");   //$NON-NLS-1$
-
-                MultiTextEdit multiEdit = new MultiTextEdit();
-                ArrayList<TextEditGroup> editGroups = new ArrayList<TextEditGroup>();
-
-                String quotedReplacement = quotedAttrValue("@string/" + xmlStringId);
-
-                // Prepare the change set
-                try {
-                    for (IStructuredDocumentRegion region : sdoc.getStructuredDocumentRegions()) {
-                        // Only look at XML "top regions"
-                        if (!DOMRegionContext.XML_TAG_NAME.equals(region.getType())) {
-                            continue;
-                        }
-
-                        int nb = region.getNumberOfRegions();
-                        ITextRegionList list = region.getRegions();
-                        String lastAttrName = null;
-
-                        for (int i = 0; i < nb; i++) {
-                            ITextRegion subRegion = list.get(i);
-                            String type = subRegion.getType();
-
-                            if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) {
-                                // Memorize the last attribute name seen
-                                lastAttrName = region.getText(subRegion);
-
-                            } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) {
-                                // Check this is the attribute and the original string
-                                String text = region.getText(subRegion);
-
-                                int len = text.length();
-                                if (len >= 2 &&
-                                        text.charAt(0) == '"' &&
-                                        text.charAt(len - 1) == '"') {
-                                    text = text.substring(1, len - 1);
-                                } else if (len >= 2 &&
-                                        text.charAt(0) == '\'' &&
-                                        text.charAt(len - 1) == '\'') {
-                                    text = text.substring(1, len - 1);
-                                }
-
-                                if (xmlAttrName.equals(lastAttrName) && tokenString.equals(text)) {
-
-                                    // Found an occurrence. Create a change for it.
-                                    TextEdit edit = new ReplaceEdit(
-                                            region.getStartOffset() + subRegion.getStart(),
-                                            subRegion.getTextLength(),
-                                            quotedReplacement);
-                                    TextEditGroup editGroup = new TextEditGroup(
-                                            "Replace attribute string by ID",
-                                            edit);
-
-                                    multiEdit.addChild(edit);
-                                    editGroups.add(editGroup);
-                                }
-                            }
-                        }
-                    }
-                } catch (Throwable t) {
-                    // Since we use some internal APIs, use a broad catch-all to report any
-                    // unexpected issue rather than crash the whole refactoring.
-                    status.addFatalError(
-                            String.format("XML refactoring error: %1$s", t.getMessage()));
-                } finally {
-                    if (multiEdit.hasChildren()) {
-                        xmlChange.setEdit(multiEdit);
-                        for (TextEditGroup group : editGroups) {
-                            xmlChange.addTextEditChangeGroup(
-                                    new TextEditChangeGroup(xmlChange, group));
-                        }
-                        changes.add(xmlChange);
-                    }
-                    subMonitor.worked(1);
-                }
-            } // for files
-
-        } catch (IOException e) {
-            status.addFatalError(String.format("XML model IO error: %1$s.", e.getMessage()));
-        } catch (CoreException e) {
-            status.addFatalError(String.format("XML model core error: %1$s.", e.getMessage()));
-        } finally {
-            if (changes.size() > 0) {
-                return changes;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a quoted attribute value suitable to be placed after an attributeName=
-     * statement in an XML stream.
-     *
-     * According to http://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
-     * the attribute value can be either quoted using ' or " and the corresponding
-     * entities &apos; or &quot; must be used inside.
-     */
-    private String quotedAttrValue(String attrValue) {
-        if (attrValue.indexOf('"') == -1) {
-            // no double-quotes inside, use double-quotes around.
-            return '"' + attrValue + '"';
-        }
-        if (attrValue.indexOf('\'') == -1) {
-            // no single-quotes inside, use single-quotes around.
-            return '\'' + attrValue + '\'';
-        }
-        // If we get here, there's a mix. Opt for double-quote around and replace
-        // inner double-quotes.
-        attrValue = attrValue.replace("\"", "&quot;");  //$NON-NLS-1$ //$NON-NLS-2$
-        return '"' + attrValue + '"';
-    }
-
-    /**
-     * Computes the changes to be made to Java file(s) and returns a list of {@link Change}.
-     */
-    private List<Change> computeJavaChanges(ICompilationUnit unit,
-            String xmlStringId,
-            String tokenString,
-            RefactoringStatus status,
-            SubMonitor subMonitor) {
-
-        // Get the Android package name from the Android Manifest. We need it to create
-        // the FQCN of the R class.
-        String packageName = null;
-        String error = null;
-        IResource manifestFile = mProject.findMember(AndroidConstants.FN_ANDROID_MANIFEST);
-        if (manifestFile == null || manifestFile.getType() != IResource.FILE) {
-            error = "File not found";
-        } else {
-            try {
-                AndroidManifestParser manifest = AndroidManifestParser.parseForData(
-                        (IFile) manifestFile);
-                if (manifest == null) {
-                    error = "Invalid content";
-                } else {
-                    packageName = manifest.getPackage();
-                    if (packageName == null) {
-                        error = "Missing package definition";
-                    }
-                }
-            } catch (CoreException e) {
-                error = e.getLocalizedMessage();
-            }
-        }
-
-        if (error != null) {
-            status.addFatalError(
-                    String.format("Failed to parse file %1$s: %2$s.",
-                            manifestFile == null ? "" : manifestFile.getFullPath(),  //$NON-NLS-1$
-                            error));
-            return null;
-        }
-
-        // TODO in a future version we might want to collect various Java files that
-        // need to be updated in the same project and process them all together.
-        // To do that we need to use an ASTRequestor and parser.createASTs, kind of
-        // like this:
-        //
-        // ASTRequestor requestor = new ASTRequestor() {
-        //    @Override
-        //    public void acceptAST(ICompilationUnit sourceUnit, CompilationUnit astNode) {
-        //        super.acceptAST(sourceUnit, astNode);
-        //        // TODO process astNode
-        //    }
-        // };
-        // ...
-        // parser.createASTs(compilationUnits, bindingKeys, requestor, monitor)
-        //
-        // and then add multiple TextFileChange to the changes arraylist.
-
-        // Right now the changes array will contain one TextFileChange at most.
-        ArrayList<Change> changes = new ArrayList<Change>();
-
-        // This is the unit that will be modified.
-        TextFileChange change = new TextFileChange(getName(), (IFile) unit.getResource());
-        change.setTextType("java"); //$NON-NLS-1$
-
-        // Create an AST for this compilation unit
-        ASTParser parser = ASTParser.newParser(AST.JLS3);
-        parser.setProject(unit.getJavaProject());
-        parser.setSource(unit);
-        parser.setResolveBindings(true);
-        ASTNode node = parser.createAST(subMonitor.newChild(1));
-
-        // The ASTNode must be a CompilationUnit, by design
-        if (!(node instanceof CompilationUnit)) {
-            status.addFatalError(String.format("Internal error: ASTNode class %s",  //$NON-NLS-1$
-                    node.getClass()));
-            return null;
-        }
-
-        // ImportRewrite will allow us to add the new type to the imports and will resolve
-        // what the Java source must reference, e.g. the FQCN or just the simple name.
-        ImportRewrite importRewrite = ImportRewrite.create((CompilationUnit) node, true);
-        String Rqualifier = packageName + ".R"; //$NON-NLS-1$
-        Rqualifier = importRewrite.addImport(Rqualifier);
-
-        // Rewrite the AST itself via an ASTVisitor
-        AST ast = node.getAST();
-        ASTRewrite astRewrite = ASTRewrite.create(ast);
-        ArrayList<TextEditGroup> astEditGroups = new ArrayList<TextEditGroup>();
-        ReplaceStringsVisitor visitor = new ReplaceStringsVisitor(
-                ast, astRewrite, astEditGroups,
-                tokenString, Rqualifier, xmlStringId);
-        node.accept(visitor);
-
-        // Finally prepare the change set
-        try {
-            MultiTextEdit edit = new MultiTextEdit();
-
-            // Create the edit to change the imports, only if anything changed
-            TextEdit subEdit = importRewrite.rewriteImports(subMonitor.newChild(1));
-            if (subEdit.hasChildren()) {
-                edit.addChild(subEdit);
-            }
-
-            // Create the edit to change the Java source, only if anything changed
-            subEdit = astRewrite.rewriteAST();
-            if (subEdit.hasChildren()) {
-                edit.addChild(subEdit);
-            }
-
-            // Only create a change set if any edit was collected
-            if (edit.hasChildren()) {
-                change.setEdit(edit);
-
-                // Create TextEditChangeGroups which let the user turn changes on or off
-                // individually. This must be done after the change.setEdit() call above.
-                for (TextEditGroup editGroup : astEditGroups) {
-                    change.addTextEditChangeGroup(new TextEditChangeGroup(change, editGroup));
-                }
-
-                changes.add(change);
-            }
-
-            // TODO to modify another Java source, loop back to the creation of the
-            // TextFileChange and accumulate in changes. Right now only one source is
-            // modified.
-
-            subMonitor.worked(1);
-
-            if (changes.size() > 0) {
-                return changes;
-            }
-
-        } catch (CoreException e) {
-            // ImportRewrite.rewriteImports failed.
-            status.addFatalError(e.getMessage());
-        }
-        return null;
-    }
-
-    /**
-     * Step 3 of 3 of the refactoring: returns the {@link Change} that will be able to do the
-     * work and creates a descriptor that can be used to replay that refactoring later.
-     *
-     * @see org.eclipse.ltk.core.refactoring.Refactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)
-     *
-     * @throws CoreException
-     */
-    @Override
-    public Change createChange(IProgressMonitor monitor)
-            throws CoreException, OperationCanceledException {
-
-        try {
-            monitor.beginTask("Applying changes...", 1);
-
-            CompositeChange change = new CompositeChange(
-                    getName(),
-                    mChanges.toArray(new Change[mChanges.size()])) {
-                @Override
-                public ChangeDescriptor getDescriptor() {
-
-                    String comment = String.format(
-                            "Extracts string '%1$s' into R.string.%2$s",
-                            mTokenString,
-                            mXmlStringId);
-
-                    ExtractStringDescriptor desc = new ExtractStringDescriptor(
-                            mProject.getName(), //project
-                            comment, //description
-                            comment, //comment
-                            createArgumentMap());
-
-                    return new RefactoringChangeDescriptor(desc);
-                }
-            };
-
-            monitor.worked(1);
-
-            return change;
-
-        } finally {
-            monitor.done();
-        }
-
-    }
-
-    /**
-     * Given a file project path, returns its resource in the same project than the
-     * compilation unit. The resource may not exist.
-     */
-    private IResource getTargetXmlResource(String xmlFileWsPath) {
-        IResource resource = mProject.getFile(xmlFileWsPath);
-        return resource;
-    }
-
-    /**
-     * Sets the replacement string ID. Used by the wizard to set the user input.
-     */
-    public void setNewStringId(String newStringId) {
-        mXmlStringId = newStringId;
-    }
-
-    /**
-     * Sets the replacement string ID. Used by the wizard to set the user input.
-     */
-    public void setNewStringValue(String newStringValue) {
-        mXmlStringValue = newStringValue;
-    }
-
-    /**
-     * Sets the target file. This is a project path, e.g. "/res/values/strings.xml".
-     * Used by the wizard to set the user input.
-     */
-    public void setTargetFile(String targetXmlFileWsPath) {
-        mTargetXmlFileWsPath = targetXmlFileWsPath;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringWizard.java
deleted file mode 100644
index 556dff0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringWizard.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
-
-/**
- * A wizard for ExtractString based on a simple dialog with one page.
- * 
- * @see ExtractStringInputPage
- * @see ExtractStringRefactoring
- */
-public class ExtractStringWizard extends RefactoringWizard {
-
-    private final IProject mProject;
-
-    /**
-     * Create a wizard for ExtractString based on a simple dialog with one page.
-     * 
-     * @param ref The instance of {@link ExtractStringRefactoring} to associate to the wizard.
-     * @param project The project where the wizard was invoked from (e.g. where the user selection
-     *                happened, so that we can retrieve project resources.)
-     */
-    public ExtractStringWizard(ExtractStringRefactoring ref, IProject project) {
-        super(ref, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
-        mProject = project;
-        setDefaultPageTitle(ref.getName());
-    }
-
-    @Override
-    protected void addUserInputPages() {
-        addPage(new ExtractStringInputPage(mProject));
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ReplaceStringsVisitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ReplaceStringsVisitor.java
deleted file mode 100755
index dd0f9f4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ReplaceStringsVisitor.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-import org.eclipse.jdt.core.dom.AST;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.ASTVisitor;
-import org.eclipse.jdt.core.dom.ClassInstanceCreation;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.IMethodBinding;
-import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.IVariableBinding;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.MethodInvocation;
-import org.eclipse.jdt.core.dom.Modifier;
-import org.eclipse.jdt.core.dom.Name;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SimpleType;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jdt.core.dom.Type;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
-import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
-import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
-import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
-import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
-import org.eclipse.text.edits.TextEditGroup;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.TreeMap;
-
-/**
- * Visitor used by {@link ExtractStringRefactoring} to extract a string from an existing
- * Java source and replace it by an Android XML string reference.
- *
- * @see ExtractStringRefactoring#computeJavaChanges
- */
-class ReplaceStringsVisitor extends ASTVisitor {
-
-    private static final String CLASS_ANDROID_CONTEXT    = "android.content.Context"; //$NON-NLS-1$
-    private static final String CLASS_JAVA_CHAR_SEQUENCE = "java.lang.CharSequence";  //$NON-NLS-1$
-    private static final String CLASS_JAVA_STRING        = "java.lang.String";        //$NON-NLS-1$
-
-
-    private final AST mAst;
-    private final ASTRewrite mRewriter;
-    private final String mOldString;
-    private final String mRQualifier;
-    private final String mXmlId;
-    private final ArrayList<TextEditGroup> mEditGroups;
-
-    public ReplaceStringsVisitor(AST ast,
-            ASTRewrite astRewrite,
-            ArrayList<TextEditGroup> editGroups,
-            String oldString,
-            String rQualifier,
-            String xmlId) {
-        mAst = ast;
-        mRewriter = astRewrite;
-        mEditGroups = editGroups;
-        mOldString = oldString;
-        mRQualifier = rQualifier;
-        mXmlId = xmlId;
-    }
-
-    @SuppressWarnings("unchecked")    //$NON-NLS-1$
-    @Override
-    public boolean visit(StringLiteral node) {
-        if (node.getLiteralValue().equals(mOldString)) {
-
-            // We want to analyze the calling context to understand whether we can
-            // just replace the string literal by the named int constant (R.id.foo)
-            // or if we should generate a Context.getString() call.
-            boolean useGetResource = false;
-            useGetResource = examineVariableDeclaration(node) ||
-                                examineMethodInvocation(node);
-
-            Name qualifierName = mAst.newName(mRQualifier + ".string");     //$NON-NLS-1$
-            SimpleName idName = mAst.newSimpleName(mXmlId);
-            ASTNode newNode = mAst.newQualifiedName(qualifierName, idName);
-            String title = "Replace string by ID";
-
-            if (useGetResource) {
-
-                Expression context = methodHasContextArgument(node);
-                if (context == null && !isClassDerivedFromContext(node)) {
-                    // if we don't have a class that derives from Context and
-                    // we don't have a Context method argument, then try a bit harder:
-                    // can we find a method or a field that will give us a context?
-                    context = findContextFieldOrMethod(node);
-
-                    if (context == null) {
-                        // If not, let's  write Context.getString(), which is technically
-                        // invalid but makes it a good clue on how to fix it.
-                        context = mAst.newSimpleName("Context");            //$NON-NLS-1$
-                    }
-                }
-
-                MethodInvocation mi2 = mAst.newMethodInvocation();
-                mi2.setName(mAst.newSimpleName("getString"));               //$NON-NLS-1$
-                mi2.setExpression(context);
-                mi2.arguments().add(newNode);
-
-                newNode = mi2;
-                title = "Replace string by Context.getString(R.string...)";
-            }
-
-            TextEditGroup editGroup = new TextEditGroup(title);
-            mEditGroups.add(editGroup);
-            mRewriter.replace(node, newNode, editGroup);
-        }
-        return super.visit(node);
-    }
-
-    /**
-     * Examines if the StringLiteral is part of of an assignment to a string,
-     * e.g. String foo = id.
-     *
-     * The parent fragment is of syntax "var = expr" or "var[] = expr".
-     * We want the type of the variable, which is either held by a
-     * VariableDeclarationStatement ("type [fragment]") or by a
-     * VariableDeclarationExpression. In either case, the type can be an array
-     * but for us all that matters is to know whether the type is an int or
-     * a string.
-     */
-    private boolean examineVariableDeclaration(StringLiteral node) {
-        VariableDeclarationFragment fragment = findParentClass(node,
-                VariableDeclarationFragment.class);
-
-        if (fragment != null) {
-            ASTNode parent = fragment.getParent();
-
-            Type type = null;
-            if (parent instanceof VariableDeclarationStatement) {
-                type = ((VariableDeclarationStatement) parent).getType();
-            } else if (parent instanceof VariableDeclarationExpression) {
-                type = ((VariableDeclarationExpression) parent).getType();
-            }
-
-            if (type instanceof SimpleType) {
-                return isJavaString(type.resolveBinding());
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * If the expression is part of a method invocation (aka a function call) or a
-     * class instance creation (aka a "new SomeClass" constructor call), we try to
-     * find the type of the argument being used. If it is a String (most likely), we
-     * want to return true (to generate a getString() call). However if there might
-     * be a similar method that takes an int, in which case we don't want to do that.
-     *
-     * This covers the case of Activity.setTitle(int resId) vs setTitle(String str).
-     */
-    @SuppressWarnings("unchecked")  //$NON-NLS-1$
-    private boolean examineMethodInvocation(StringLiteral node) {
-
-        ASTNode parent = null;
-        List arguments = null;
-        IMethodBinding methodBinding = null;
-
-        MethodInvocation invoke = findParentClass(node, MethodInvocation.class);
-        if (invoke != null) {
-            parent = invoke;
-            arguments = invoke.arguments();
-            methodBinding = invoke.resolveMethodBinding();
-        } else {
-            ClassInstanceCreation newclass = findParentClass(node, ClassInstanceCreation.class);
-            if (newclass != null) {
-                parent = newclass;
-                arguments = newclass.arguments();
-                methodBinding = newclass.resolveConstructorBinding();
-            }
-        }
-
-        if (parent != null && arguments != null && methodBinding != null) {
-            // We want to know which argument this is.
-            // Walk up the hierarchy again to find the immediate child of the parent,
-            // which should turn out to be one of the invocation arguments.
-            ASTNode child = null;
-            for (ASTNode n = node; n != parent; ) {
-                ASTNode p = n.getParent();
-                if (p == parent) {
-                    child = n;
-                    break;
-                }
-                n = p;
-            }
-            if (child == null) {
-                // This can't happen: a parent of 'node' must be the child of 'parent'.
-                return false;
-            }
-
-            // Find the index
-            int index = 0;
-            for (Object arg : arguments) {
-                if (arg == child) {
-                    break;
-                }
-                index++;
-            }
-
-            if (index == arguments.size()) {
-                // This can't happen: one of the arguments of 'invoke' must be 'child'.
-                return false;
-            }
-
-            // Eventually we want to determine if the parameter is a string type,
-            // in which case a Context.getString() call must be generated.
-            boolean useStringType = false;
-
-            // Find the type of that argument
-            ITypeBinding[] types = methodBinding.getParameterTypes();
-            if (index < types.length) {
-                ITypeBinding type = types[index];
-                useStringType = isJavaString(type);
-            }
-
-            // Now that we know that this method takes a String parameter, can we find
-            // a variant that would accept an int for the same parameter position?
-            if (useStringType) {
-                String name = methodBinding.getName();
-                ITypeBinding clazz = methodBinding.getDeclaringClass();
-                nextMethod: for (IMethodBinding mb2 : clazz.getDeclaredMethods()) {
-                    if (methodBinding == mb2 || !mb2.getName().equals(name)) {
-                        continue;
-                    }
-                    // We found a method with the same name. We want the same parameters
-                    // except that the one at 'index' must be an int type.
-                    ITypeBinding[] types2 = mb2.getParameterTypes();
-                    int len2 = types2.length;
-                    if (types.length == len2) {
-                        for (int i = 0; i < len2; i++) {
-                            if (i == index) {
-                                ITypeBinding type2 = types2[i];
-                                if (!("int".equals(type2.getQualifiedName()))) {   //$NON-NLS-1$
-                                    // The argument at 'index' is not an int.
-                                    continue nextMethod;
-                                }
-                            } else if (!types[i].equals(types2[i])) {
-                                // One of the other arguments do not match our original method
-                                continue nextMethod;
-                            }
-                        }
-                        // If we got here, we found a perfect match: a method with the same
-                        // arguments except the one at 'index' is an int. In this case we
-                        // don't need to convert our R.id into a string.
-                        useStringType = false;
-                        break;
-                    }
-                }
-            }
-
-            return useStringType;
-        }
-        return false;
-    }
-
-    /**
-     * Examines if the StringLiteral is part of a method declaration (a.k.a. a function
-     * definition) which takes a Context argument.
-     * If such, it returns the name of the variable as a {@link SimpleName}.
-     * Otherwise it returns null.
-     */
-    private SimpleName methodHasContextArgument(StringLiteral node) {
-        MethodDeclaration decl = findParentClass(node, MethodDeclaration.class);
-        if (decl != null) {
-            for (Object obj : decl.parameters()) {
-                if (obj instanceof SingleVariableDeclaration) {
-                    SingleVariableDeclaration var = (SingleVariableDeclaration) obj;
-                    if (isAndroidContext(var.getType())) {
-                        return mAst.newSimpleName(var.getName().getIdentifier());
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Walks up the node hierarchy to find the class (aka type) where this statement
-     * is used and returns true if this class derives from android.content.Context.
-     */
-    private boolean isClassDerivedFromContext(StringLiteral node) {
-        TypeDeclaration clazz = findParentClass(node, TypeDeclaration.class);
-        if (clazz != null) {
-            // This is the class that the user is currently writing, so it can't be
-            // a Context by itself, it has to be derived from it.
-            return isAndroidContext(clazz.getSuperclassType());
-        }
-        return false;
-    }
-
-    private Expression findContextFieldOrMethod(StringLiteral node) {
-        TypeDeclaration clazz = findParentClass(node, TypeDeclaration.class);
-        ITypeBinding clazzType = clazz == null ? null : clazz.resolveBinding();
-        return findContextFieldOrMethod(clazzType);
-    }
-
-    private Expression findContextFieldOrMethod(ITypeBinding clazzType) {
-        TreeMap<Integer, Expression> results = new TreeMap<Integer, Expression>();
-        findContextCandidates(results, clazzType, 0 /*superType*/);
-        if (results.size() > 0) {
-            Integer bestRating = results.keySet().iterator().next();
-            return results.get(bestRating);
-        }
-        return null;
-    }
-
-    /**
-     * Find all method or fields that are candidates for providing a Context.
-     * There can be various choices amongst this class or its super classes.
-     * Sort them by rating in the results map.
-     *
-     * The best ever choice is to find a method with no argument that returns a Context.
-     * The second suitable choice is to find a Context field.
-     * The least desirable choice is to find a method with arguments. It's not really
-     * desirable since we can't generate these arguments automatically.
-     *
-     * Methods and fields from supertypes are ignored if they are private.
-     *
-     * The rating is reversed: the lowest rating integer is used for the best candidate.
-     * Because the superType argument is actually a recursion index, this makes the most
-     * immediate classes more desirable.
-     *
-     * @param results The map that accumulates the rating=>expression results. The lower
-     *                rating number is the best candidate.
-     * @param clazzType The class examined.
-     * @param superType The recursion index.
-     *                  0 for the immediate class, 1 for its super class, etc.
-     */
-    private void findContextCandidates(TreeMap<Integer, Expression> results,
-            ITypeBinding clazzType,
-            int superType) {
-        for (IMethodBinding mb : clazzType.getDeclaredMethods()) {
-            // If we're looking at supertypes, we can't use private methods.
-            if (superType != 0 && Modifier.isPrivate(mb.getModifiers())) {
-                continue;
-            }
-
-            if (isAndroidContext(mb.getReturnType())) {
-                // We found a method that returns something derived from Context.
-
-                int argsLen = mb.getParameterTypes().length;
-                if (argsLen == 0) {
-                    // We'll favor any method that takes no argument,
-                    // That would be the best candidate ever, so we can stop here.
-                    MethodInvocation mi = mAst.newMethodInvocation();
-                    mi.setName(mAst.newSimpleName(mb.getName()));
-                    results.put(Integer.MIN_VALUE, mi);
-                    return;
-                } else {
-                    // A method with arguments isn't as interesting since we wouldn't
-                    // know how to populate such arguments. We'll use it if there are
-                    // no other alternatives. We'll favor the one with the less arguments.
-                    Integer rating = Integer.valueOf(10000 + 1000 * superType + argsLen);
-                    if (!results.containsKey(rating)) {
-                        MethodInvocation mi = mAst.newMethodInvocation();
-                        mi.setName(mAst.newSimpleName(mb.getName()));
-                        results.put(rating, mi);
-                    }
-                }
-            }
-        }
-
-        // A direct Context field would be more interesting than a method with
-        // arguments. Try to find one.
-        for (IVariableBinding var : clazzType.getDeclaredFields()) {
-            // If we're looking at supertypes, we can't use private field.
-            if (superType != 0 && Modifier.isPrivate(var.getModifiers())) {
-                continue;
-            }
-
-            if (isAndroidContext(var.getType())) {
-                // We found such a field. Let's use it.
-                Integer rating = Integer.valueOf(superType);
-                results.put(rating, mAst.newSimpleName(var.getName()));
-                break;
-            }
-        }
-
-        // Examine the super class to see if we can locate a better match
-        clazzType = clazzType.getSuperclass();
-        if (clazzType != null) {
-            findContextCandidates(results, clazzType, superType + 1);
-        }
-    }
-
-    /**
-     * Walks up the node hierarchy and returns the first ASTNode of the requested class.
-     * Only look at parents.
-     *
-     * Implementation note: this is a generic method so that it returns the node already
-     * casted to the requested type.
-     */
-    @SuppressWarnings("unchecked")
-    private <T extends ASTNode> T findParentClass(ASTNode node, Class<T> clazz) {
-        for (node = node.getParent(); node != null; node = node.getParent()) {
-            if (node.getClass().equals(clazz)) {
-                return (T) node;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns true if the given type is or derives from android.content.Context.
-     */
-    private boolean isAndroidContext(Type type) {
-        if (type != null) {
-            return isAndroidContext(type.resolveBinding());
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if the given type is or derives from android.content.Context.
-     */
-    private boolean isAndroidContext(ITypeBinding type) {
-        for (; type != null; type = type.getSuperclass()) {
-            if (CLASS_ANDROID_CONTEXT.equals(type.getQualifiedName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if this type binding represents a String or CharSequence type.
-     */
-    private boolean isJavaString(ITypeBinding type) {
-        for (; type != null; type = type.getSuperclass()) {
-            if (CLASS_JAVA_STRING.equals(type.getQualifiedName()) ||
-                CLASS_JAVA_CHAR_SEQUENCE.equals(type.getQualifiedName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java
deleted file mode 100644
index 4caecd3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
-
-import com.android.sdklib.xml.AndroidXPathFactory;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * An helper utility to get IDs out of an Android XML resource file.
- */
-class XmlStringFileHelper {
-
-    /** A temporary cache of R.string IDs defined by a given xml file. The key is the
-     * project path of the file, the data is a set of known string Ids for that file.
-     *
-     * Map type: map [String filename] => map [String id => String value].
-     */
-    private HashMap<String, Map<String, String>> mResIdCache =
-        new HashMap<String, Map<String, String>>();
-    /** An instance of XPath, created lazily on demand. */
-    private XPath mXPath;
-
-    public XmlStringFileHelper() {
-    }
-
-    /**
-     * Utility method used by the wizard to retrieve the actual value definition of a given
-     * string ID.
-     *
-     * @param project The project contain the XML file.
-     * @param xmlFileWsPath The project path of the XML file, e.g. "/res/values/strings.xml".
-     *          The given file may or may not exist.
-     * @param stringId The string ID to find.
-     * @return The value string if the ID is defined, null otherwise.
-     */
-    public String valueOfStringId(IProject project, String xmlFileWsPath, String stringId) {
-        Map<String, String> cache = getResIdsForFile(project, xmlFileWsPath);
-        return cache.get(stringId);
-    }
-
-    /**
-     * Utility method that retrieves all the *string* IDs defined in the given Android resource
-     * file. The instance maintains an internal cache so a given file is retrieved only once.
-     * Callers should consider the set to be read-only.
-     *
-     * @param project The project contain the XML file.
-     * @param xmlFileWsPath The project path of the XML file, e.g. "/res/values/strings.xml".
-     *          The given file may or may not exist.
-     * @return The map of string IDs => values defined in the given file. Cached. Never null.
-     */
-    public Map<String, String> getResIdsForFile(IProject project, String xmlFileWsPath) {
-        Map<String, String> cache = mResIdCache.get(xmlFileWsPath);
-        if (cache == null) {
-            cache = internalGetResIdsForFile(project, xmlFileWsPath);
-            mResIdCache.put(xmlFileWsPath, cache);
-        }
-        return cache;
-    }
-
-    /**
-     * Extract all the defined string IDs from a given file using XPath.
-     * @param project The project contain the XML file.
-     * @param xmlFileWsPath The project path of the file to parse. It may not exist.
-     * @return The map of all string IDs => values defined in the file.
-     *   The returned set is always non null. It is empty if the file does not exist.
-     */
-    private Map<String, String> internalGetResIdsForFile(IProject project, String xmlFileWsPath) {
-        TreeMap<String, String> ids = new TreeMap<String, String>();
-
-        if (mXPath == null) {
-            mXPath = AndroidXPathFactory.newXPath();
-        }
-
-        // Access the project that contains the resource that contains the compilation unit
-        IResource resource = project.getFile(xmlFileWsPath);
-
-        if (resource != null && resource.exists() && resource.getType() == IResource.FILE) {
-            InputSource source;
-            try {
-                source = new InputSource(((IFile) resource).getContents());
-
-                // We want all the IDs in an XML structure like this:
-                // <resources>
-                //    <string name="ID">something</string>
-                // </resources>
-
-                String xpathExpr = "/resources/string";                         //$NON-NLS-1$
-
-                Object result = mXPath.evaluate(xpathExpr, source, XPathConstants.NODESET);
-                if (result instanceof NodeList) {
-                    NodeList list = (NodeList) result;
-                    for (int n = list.getLength() - 1; n >= 0; n--) {
-                        Node strNode = list.item(n);
-                        NamedNodeMap attrs = strNode.getAttributes();
-                        Node nameAttr = attrs.getNamedItem("name");             //$NON-NLS-1$
-                        if (nameAttr != null) {
-                            String id = nameAttr.getNodeValue();
-                            String text = strNode.getTextContent();
-                            ids.put(id, text);
-                        }
-                    }
-                }
-
-            } catch (CoreException e1) {
-                // IFile.getContents failed. Ignore.
-            } catch (XPathExpressionException e2) {
-                // mXPath.evaluate failed. Ignore.
-            }
-        }
-
-        return ids;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParser.java
deleted file mode 100644
index 7f576c4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParser.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo.Format;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo.LayoutParamsInfo;
-
-import org.eclipse.core.runtime.IStatus;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeSet;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-/**
- * Parser for attributes description files.
- */
-public final class AttrsXmlParser {
-
-    private Document mDocument;
-    private String mOsAttrsXmlPath;
-    // all attributes that have the same name are supposed to have the same
-    // parameters so we'll keep a cache of them to avoid processing them twice.
-    private HashMap<String, AttributeInfo> mAttributeMap;
-
-    /** Map of all attribute names for a given element */
-    private HashMap<String, DeclareStyleableInfo> mStyleMap;
-    
-    /** Map of all (constant, value) pairs for attributes of format enum or flag.
-     * E.g. for attribute name=gravity, this tells us there's an enum/flag called "center"
-     * with value 0x11. 
-     */
-    private Map<String, Map<String, Integer>> mEnumFlagValues;
-    
-    
-    /**
-     * Creates a new {@link AttrsXmlParser}, set to load things from the given
-     * XML file. Nothing has been parsed yet. Callers should call {@link #preload()}
-     * next.
-     */
-    public AttrsXmlParser(String osAttrsXmlPath) {
-        this(osAttrsXmlPath, null /* inheritableAttributes */);
-    }
-
-    /**
-     * Creates a new {@link AttrsXmlParser} set to load things from the given
-     * XML file. If inheritableAttributes is non-null, it must point to a preloaded
-     * {@link AttrsXmlParser} which attributes will be used for this one. Since
-     * already defined attributes are not modifiable, they are thus "inherited".
-     */
-    public AttrsXmlParser(String osAttrsXmlPath, AttrsXmlParser inheritableAttributes) {
-        mOsAttrsXmlPath = osAttrsXmlPath;
-
-        // styles are not inheritable.
-        mStyleMap = new HashMap<String, DeclareStyleableInfo>();
-
-        if (inheritableAttributes == null) {
-            mAttributeMap = new HashMap<String, AttributeInfo>();
-            mEnumFlagValues = new HashMap<String, Map<String,Integer>>();
-        } else {
-            mAttributeMap = new HashMap<String, AttributeInfo>(inheritableAttributes.mAttributeMap);
-            mEnumFlagValues = new HashMap<String, Map<String,Integer>>(
-                                                             inheritableAttributes.mEnumFlagValues);
-        }
-    }
-
-    /**
-     * @return The OS path of the attrs.xml file parsed
-     */
-    public String getOsAttrsXmlPath() {
-        return mOsAttrsXmlPath;
-    }
-    
-    /**
-     * Preloads the document, parsing all attributes and declared styles.
-     * 
-     * @return Self, for command chaining.
-     */
-    public AttrsXmlParser preload() {
-        Document doc = getDocument();
-
-        if (doc == null) {
-            AdtPlugin.log(IStatus.WARNING, "Failed to find %1$s", //$NON-NLS-1$
-                    mOsAttrsXmlPath);
-            return this;
-        }
-
-        Node res = doc.getFirstChild();
-        while (res != null &&
-                res.getNodeType() != Node.ELEMENT_NODE &&
-                !res.getNodeName().equals("resources")) { //$NON-NLS-1$
-            res = res.getNextSibling();
-        }
-        
-        if (res == null) {
-            AdtPlugin.log(IStatus.WARNING, "Failed to find a <resources> node in %1$s", //$NON-NLS-1$
-                    mOsAttrsXmlPath);
-            return this;
-        }
-        
-        parseResources(res);
-        return this;
-    }
-
-    /**
-     * Loads all attributes & javadoc for the view class info based on the class name.
-     */
-    public void loadViewAttributes(ViewClassInfo info) {
-        if (getDocument() != null) {
-            String xmlName = info.getShortClassName();
-            DeclareStyleableInfo style = mStyleMap.get(xmlName);
-            if (style != null) {
-                info.setAttributes(style.getAttributes());
-                info.setJavaDoc(style.getJavaDoc());
-            }
-        }
-    }
-
-    /**
-     * Loads all attributes for the layout data info based on the class name.
-     */
-    public void loadLayoutParamsAttributes(LayoutParamsInfo info) {
-        if (getDocument() != null) {
-            // Transforms "LinearLayout" and "LayoutParams" into "LinearLayout_Layout".
-            String xmlName = String.format("%1$s_%2$s", //$NON-NLS-1$
-                    info.getViewLayoutClass().getShortClassName(),
-                    info.getShortClassName());
-            xmlName = xmlName.replaceFirst("Params$", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
-            DeclareStyleableInfo style = mStyleMap.get(xmlName);
-            if (style != null) {
-                info.setAttributes(style.getAttributes());
-            }
-        }
-    }
-    
-    /**
-     * Returns a list of all decleare-styleable found in the xml file.
-     */
-    public Map<String, DeclareStyleableInfo> getDeclareStyleableList() {
-        return Collections.unmodifiableMap(mStyleMap);
-    }
-    
-    /**
-     * Returns a map of all enum and flag constants sorted by parent attribute name.
-     * The map is attribute_name => (constant_name => integer_value).
-     */
-    public Map<String, Map<String, Integer>> getEnumFlagValues() {
-        return mEnumFlagValues;
-    }
-
-    //-------------------------
-
-    /**
-     * Creates an XML document from the attrs.xml OS path.
-     * May return null if the file doesn't exist or cannot be parsed. 
-     */
-    private Document getDocument() {
-        if (mDocument == null) {
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            factory.setIgnoringComments(false);
-            try {
-                DocumentBuilder builder = factory.newDocumentBuilder();
-                mDocument = builder.parse(new File(mOsAttrsXmlPath));
-            } catch (ParserConfigurationException e) {
-                AdtPlugin.log(e, "Failed to create XML document builder for %1$s", //$NON-NLS-1$
-                        mOsAttrsXmlPath);
-            } catch (SAXException e) {
-                AdtPlugin.log(e, "Failed to parse XML document %1$s", //$NON-NLS-1$
-                        mOsAttrsXmlPath);
-            } catch (IOException e) {
-                AdtPlugin.log(e, "Failed to read XML document %1$s", //$NON-NLS-1$
-                        mOsAttrsXmlPath);
-            }
-        }
-        return mDocument;
-    }
-
-    /**
-     * Finds all the <declare-styleable> and <attr> nodes in the top <resources> node.
-     */
-    private void parseResources(Node res) {
-        Node lastComment = null;
-        for (Node node = res.getFirstChild(); node != null; node = node.getNextSibling()) {
-            switch (node.getNodeType()) {
-            case Node.COMMENT_NODE:
-                lastComment = node;
-                break;
-            case Node.ELEMENT_NODE:
-                if (node.getNodeName().equals("declare-styleable")) {          //$NON-NLS-1$
-                    Node nameNode = node.getAttributes().getNamedItem("name"); //$NON-NLS-1$
-                    if (nameNode != null) {
-                        String name = nameNode.getNodeValue();
-                        
-                        Node parentNode = node.getAttributes().getNamedItem("parent"); //$NON-NLS-1$
-                        String parents = parentNode == null ? null : parentNode.getNodeValue();
-                        
-                        if (name != null && !mStyleMap.containsKey(name)) {
-                            DeclareStyleableInfo style = parseDeclaredStyleable(name, node);
-                            if (parents != null) {
-                                style.setParents(parents.split("[ ,|]"));  //$NON-NLS-1$
-                            }
-                            mStyleMap.put(name, style);
-                            if (lastComment != null) {
-                                style.setJavaDoc(parseJavadoc(lastComment.getNodeValue()));
-                            }
-                        }
-                    }
-                } else if (node.getNodeName().equals("attr")) {                //$NON-NLS-1$
-                    parseAttr(node, lastComment);
-                }
-                lastComment = null;
-                break;
-            }
-        }
-    }
-
-    /**
-     * Parses an <attr> node and convert it into an {@link AttributeInfo} if it is valid.
-     */
-    private AttributeInfo parseAttr(Node attrNode, Node lastComment) {
-        AttributeInfo info = null;
-        Node nameNode = attrNode.getAttributes().getNamedItem("name"); //$NON-NLS-1$
-        if (nameNode != null) {
-            String name = nameNode.getNodeValue();
-            if (name != null) {
-                info = mAttributeMap.get(name);
-                // If the attribute is unknown yet, parse it.
-                // If the attribute is know but its format is unknown, parse it too.
-                if (info == null || info.getFormats().length == 0) {
-                    info = parseAttributeTypes(attrNode, name);
-                    if (info != null) {
-                        mAttributeMap.put(name, info);
-                    }
-                } else if (lastComment != null) {
-                    info = new AttributeInfo(info);
-                }
-                if (info != null) {
-                    if (lastComment != null) {
-                        info.setJavaDoc(parseJavadoc(lastComment.getNodeValue()));
-                        info.setDeprecatedDoc(parseDeprecatedDoc(lastComment.getNodeValue()));
-                    }
-                }
-            }
-        }
-        return info;
-    }
-
-    /**
-     * Finds all the attributes for a particular style node,
-     * e.g. a declare-styleable of name "TextView" or "LinearLayout_Layout".
-     * 
-     * @param styleName The name of the declare-styleable node
-     * @param declareStyleableNode The declare-styleable node itself 
-     */
-    private DeclareStyleableInfo parseDeclaredStyleable(String styleName,
-            Node declareStyleableNode) {
-        ArrayList<AttributeInfo> attrs = new ArrayList<AttributeInfo>();
-        Node lastComment = null;
-        for (Node node = declareStyleableNode.getFirstChild();
-             node != null;
-             node = node.getNextSibling()) {
-
-            switch (node.getNodeType()) {
-            case Node.COMMENT_NODE:
-                lastComment = node;
-                break;
-            case Node.ELEMENT_NODE:
-                if (node.getNodeName().equals("attr")) {                       //$NON-NLS-1$
-                    AttributeInfo info = parseAttr(node, lastComment);
-                    if (info != null) {
-                        attrs.add(info);
-                    }
-                }
-                lastComment = null;
-                break;
-            }
-            
-        }
-        
-        return new DeclareStyleableInfo(styleName, attrs.toArray(new AttributeInfo[attrs.size()]));
-    }
-
-    /**
-     * Returns the {@link AttributeInfo} for a specific <attr> XML node.
-     * This gets the javadoc, the type, the name and the enum/flag values if any.
-     * <p/>
-     * The XML node is expected to have the following attributes:
-     * <ul>
-     * <li>"name", which is mandatory. The node is skipped if this is missing.</li>
-     * <li>"format".</li>
-     * </ul>
-     * The format may be one type or two types (e.g. "reference|color").
-     * An extra format can be implied: "enum" or "flag" are not specified in the "format" attribute,
-     * they are implicitely stated by the presence of sub-nodes <enum> or <flag>.
-     * <p/>
-     * By design, <attr> nodes of the same name MUST have the same type.
-     * Attribute nodes are thus cached by name and reused as much as possible.
-     * When reusing a node, it is duplicated and its javadoc reassigned. 
-     */
-    private AttributeInfo parseAttributeTypes(Node attrNode, String name) {
-        TreeSet<AttributeInfo.Format> formats = new TreeSet<AttributeInfo.Format>();
-        String[] enumValues = null;
-        String[] flagValues = null;
-
-        Node attrFormat = attrNode.getAttributes().getNamedItem("format"); //$NON-NLS-1$
-        if (attrFormat != null) {
-            for (String f : attrFormat.getNodeValue().split("\\|")) { //$NON-NLS-1$
-                try {
-                    Format format = AttributeInfo.Format.valueOf(f.toUpperCase());
-                    // enum and flags are handled differently right below
-                    if (format != null &&
-                            format != AttributeInfo.Format.ENUM &&
-                            format != AttributeInfo.Format.FLAG) {
-                        formats.add(format);
-                    }
-                } catch (IllegalArgumentException e) {
-                    AdtPlugin.log(e, "Unknown format name '%s' in <attr name=\"%s\">, file '%s'.", //$NON-NLS-1$
-                            f, name, getOsAttrsXmlPath());
-                }
-            }
-        }
-
-        // does this <attr> have <enum> children?
-        enumValues = parseEnumFlagValues(attrNode, "enum", name); //$NON-NLS-1$
-        if (enumValues != null) {
-            formats.add(AttributeInfo.Format.ENUM);
-        }
-
-        // does this <attr> have <flag> children?
-        flagValues = parseEnumFlagValues(attrNode, "flag", name); //$NON-NLS-1$
-        if (flagValues != null) {
-            formats.add(AttributeInfo.Format.FLAG);
-        }
-
-        AttributeInfo info = new AttributeInfo(name,
-                formats.toArray(new AttributeInfo.Format[formats.size()]));
-        info.setEnumValues(enumValues);
-        info.setFlagValues(flagValues);
-        return info;
-    }
-
-    /**
-     * Given an XML node that represents an <attr> node, this method searches
-     * if the node has any children nodes named "target" (e.g. "enum" or "flag").
-     * Such nodes must have a "name" attribute.
-     * <p/>
-     * If "attrNode" is null, look for any <attr> that has the given attrNode
-     * and the requested children nodes.
-     * <p/>
-     * This method collects all the possible names of these children nodes and
-     * return them.
-     * 
-     * @param attrNode The <attr> XML node
-     * @param filter The child node to look for, either "enum" or "flag".
-     * @param attrName The value of the name attribute of <attr> 
-     * 
-     * @return Null if there are no such children nodes, otherwise an array of length >= 1
-     *         of all the names of these children nodes.
-     */
-    private String[] parseEnumFlagValues(Node attrNode, String filter, String attrName) {
-        ArrayList<String> names = null;
-        for (Node child = attrNode.getFirstChild(); child != null; child = child.getNextSibling()) {
-            if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(filter)) {
-                Node nameNode = child.getAttributes().getNamedItem("name");  //$NON-NLS-1$
-                if (nameNode == null) {
-                    AdtPlugin.log(IStatus.WARNING,
-                            "Missing name attribute in <attr name=\"%s\"><%s></attr>", //$NON-NLS-1$
-                            attrName, filter);
-                } else {
-                    if (names == null) {
-                        names = new ArrayList<String>();
-                    }
-                    String name = nameNode.getNodeValue();
-                    names.add(name);
-                    
-                    Node valueNode = child.getAttributes().getNamedItem("value");  //$NON-NLS-1$
-                    if (valueNode == null) {
-                        AdtPlugin.log(IStatus.WARNING,
-                                "Missing value attribute in <attr name=\"%s\"><%s name=\"%s\"></attr>", //$NON-NLS-1$
-                                attrName, filter, name);
-                    } else {
-                        String value = valueNode.getNodeValue();
-                        try {
-                            int i = value.startsWith("0x") ?
-                                    Integer.parseInt(value.substring(2), 16 /* radix */) :
-                                    Integer.parseInt(value);
-                            
-                            Map<String, Integer> map = mEnumFlagValues.get(attrName);
-                            if (map == null) {
-                                map = new HashMap<String, Integer>();
-                                mEnumFlagValues.put(attrName, map);
-                            }
-                            map.put(name, Integer.valueOf(i));
-                            
-                        } catch(NumberFormatException e) {
-                            AdtPlugin.log(e,
-                                    "Value in <attr name=\"%s\"><%s name=\"%s\" value=\"%s\"></attr> is not a valid decimal or hexadecimal", //$NON-NLS-1$
-                                    attrName, filter, name, value);
-                        }
-                    }
-                }
-            }
-        }
-        return names == null ? null : names.toArray(new String[names.size()]);
-    }
-    
-    /**
-     * Parses the javadoc comment.
-     * Only keeps the first sentence.
-     * <p/>
-     * This does not remove nor simplify links and references. Such a transformation
-     * is done later at "display" time in {@link DescriptorsUtils#formatTooltip(String)} and co.
-     */
-    private String parseJavadoc(String comment) {
-        if (comment == null) {
-            return null;
-        }
-        
-        // sanitize & collapse whitespace
-        comment = comment.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
-
-        // Explicitly remove any @deprecated tags since they are handled separately.
-        comment = comment.replaceAll("(?:\\{@deprecated[^}]*\\}|@deprecated[^@}]*)", "");
-
-        // take everything up to the first dot that is followed by a space or the end of the line.
-        // I love regexps :-). For the curious, the regexp is:
-        // - start of line
-        // - ignore whitespace
-        // - group:
-        //   - everything, not greedy
-        //   - non-capturing group (?: )
-        //      - end of string
-        //      or
-        //      - not preceded by a letter, a dot and another letter (for "i.e" and "e.g" )
-        //                            (<! non-capturing zero-width negative look-behind)
-        //      - a dot
-        //      - followed by a space (?= non-capturing zero-width positive look-ahead)
-        // - anything else is ignored
-        comment = comment.replaceFirst("^\\s*(.*?(?:$|(?<![a-zA-Z]\\.[a-zA-Z])\\.(?=\\s))).*", "$1"); //$NON-NLS-1$ //$NON-NLS-2$
-        
-        return comment;
-    }
-
-
-    /**
-     * Parses the javadoc and extract the first @deprecated tag, if any.
-     * Returns null if there's no @deprecated tag.
-     * The deprecated tag can be of two forms:
-     * - {+@deprecated ...text till the next bracket }
-     *   Note: there should be no space or + between { and @. I need one in this comment otherwise
-     *   this method will be tagged as deprecated ;-)
-     * - @deprecated ...text till the next @tag or end of the comment.
-     * In both cases the comment can be multi-line.
-     */
-    private String parseDeprecatedDoc(String comment) {
-        // Skip if we can't even find the tag in the comment.
-        if (comment == null) {
-            return null;
-        }
-        
-        // sanitize & collapse whitespace
-        comment = comment.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
-
-        int pos = comment.indexOf("{@deprecated");
-        if (pos >= 0) {
-            comment = comment.substring(pos + 12 /* len of {@deprecated */);
-            comment = comment.replaceFirst("^([^}]*).*", "$1");
-        } else if ((pos = comment.indexOf("@deprecated")) >= 0) {
-            comment = comment.substring(pos + 11 /* len of @deprecated */);
-            comment = comment.replaceFirst("^(.*?)(?:@.*|$)", "$1");
-        } else {
-            return null;
-        }
-        
-        return comment.trim();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/DeclareStyleableInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/DeclareStyleableInfo.java
deleted file mode 100644
index bcfa766..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/DeclareStyleableInfo.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-
-/**
- * Information needed to represent a View or ViewGroup (aka Layout) item
- * in the layout hierarchy, as extracted from the main android.jar and the
- * associated attrs.xml.
- */
-public class DeclareStyleableInfo {
-    /** The style name, never null. */
-    private String mStyleName;
-    /** Attributes for this view or view group. Can be empty but never null. */
-    private AttributeInfo[] mAttributes;
-    /** Short javadoc. Can be null. */
-    private String mJavaDoc;
-    /** Optional name of the parents stylable. Can be null. */
-    private String[] mParents;    
-
-    public static class AttributeInfo {
-        /** XML Name of the attribute */
-        private String mName;
-        
-        public enum Format {
-            STRING,
-            BOOLEAN,
-            INTEGER,
-            FLOAT,
-            REFERENCE,
-            COLOR,
-            DIMENSION,
-            FRACTION,
-            ENUM,
-            FLAG,
-        }
-        
-        /** Formats of the attribute. Cannot be null. Should have at least one format. */
-        private Format[] mFormats;
-        /** Values for enum. null for other types. */
-        private String[] mEnumValues;
-        /** Values for flag. null for other types. */
-        private String[] mFlagValues;
-        /** Short javadoc (i.e. the first sentence). */
-        private String mJavaDoc;
-        /** Documentation for deprecated attributes. Null if not deprecated. */
-        private String mDeprecatedDoc;
-
-        /**
-         * @param name The XML Name of the attribute
-         * @param formats The formats of the attribute. Cannot be null.
-         *                Should have at least one format.
-         */
-        public AttributeInfo(String name, Format[] formats) {
-            mName = name;
-            mFormats = formats;
-        }
-
-        /**
-         * @param name The XML Name of the attribute
-         * @param formats The formats of the attribute. Cannot be null.
-         *                Should have at least one format.
-         * @param javadoc Short javadoc (i.e. the first sentence).
-         */
-        public AttributeInfo(String name, Format[] formats, String javadoc) {
-            mName = name;
-            mFormats = formats;
-            mJavaDoc = javadoc;
-        }
-
-        public AttributeInfo(AttributeInfo info) {
-            mName = info.mName;
-            mFormats = info.mFormats;
-            mEnumValues = info.mEnumValues;
-            mFlagValues = info.mFlagValues;
-            mJavaDoc = info.mJavaDoc;
-            mDeprecatedDoc = info.mDeprecatedDoc;
-        }
-        
-        /** Returns the XML Name of the attribute */
-        public String getName() {
-            return mName;
-        }
-        /** Returns the formats of the attribute. Cannot be null.
-         *  Should have at least one format. */
-        public Format[] getFormats() {
-            return mFormats;
-        }
-        /** Returns the values for enums. null for other types. */
-        public String[] getEnumValues() {
-            return mEnumValues;
-        }
-        /** Returns the values for flags. null for other types. */
-        public String[] getFlagValues() {
-            return mFlagValues;
-        }
-        /** Returns a short javadoc, .i.e. the first sentence. */
-        public String getJavaDoc() {
-            return mJavaDoc;
-        }
-        /** Returns the documentation for deprecated attributes. Null if not deprecated. */
-        public String getDeprecatedDoc() {
-            return mDeprecatedDoc;
-        }
-
-        /** Sets the values for enums. null for other types. */
-        public void setEnumValues(String[] values) {
-            mEnumValues = values;
-        }
-        /** Sets the values for flags. null for other types. */
-        public void setFlagValues(String[] values) {
-            mFlagValues = values;
-        }
-        /** Sets a short javadoc, .i.e. the first sentence. */
-        public void setJavaDoc(String javaDoc) {
-            mJavaDoc = javaDoc;
-        }
-        /** Sets the documentation for deprecated attributes. Null if not deprecated. */
-        public void setDeprecatedDoc(String deprecatedDoc) {
-            mDeprecatedDoc = deprecatedDoc;
-        }
-
-    }
-    
-    // --------
-    
-    /**
-     * Creates a new {@link DeclareStyleableInfo}.
-     * 
-     * @param styleName The name of the style. Should not be empty nor null.
-     * @param attributes The initial list of attributes. Can be null.
-     */
-    public DeclareStyleableInfo(String styleName, AttributeInfo[] attributes) {
-        mStyleName = styleName;
-        mAttributes = attributes == null ? new AttributeInfo[0] : attributes;
-    }
-    
-    /** Returns style name */
-    public String getStyleName() {
-        return mStyleName;
-    }
-
-    /** Returns the attributes for this view or view group. Maybe empty but not null. */
-    public AttributeInfo[] getAttributes() {
-        return mAttributes;
-    }
-
-    /** Sets the list of attributes for this View or ViewGroup. */
-    public void setAttributes(AttributeInfo[] attributes) {
-        mAttributes = attributes;
-    }
-    
-    /** Returns a short javadoc */
-    public String getJavaDoc() {
-        return mJavaDoc;
-    }
-
-    /** Sets the javadoc. */
-    public void setJavaDoc(String javaDoc) {
-        mJavaDoc = javaDoc;
-    }
-
-    /** Sets the name of the parents styleable. Can be null. */
-    public void setParents(String[] parents) {
-        mParents = parents;
-    }
-
-    /** Returns the name of the parents styleable. Can be null. */
-    public String[] getParents() {
-        return mParents;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IIdResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IIdResourceItem.java
deleted file mode 100644
index 7ed6836..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IIdResourceItem.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-/**
- * Classes which implements this interface provides a method indicating the state of a resource of
- * type {@link ResourceType#ID}.
- */
-public interface IIdResourceItem {
-    /**
-     * Returns whether the ID resource has been declared inline inside another resource XML file. 
-     */
-    public boolean isDeclaredInline();
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IResourceRepository.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IResourceRepository.java
deleted file mode 100644
index d125dc0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IResourceRepository.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-/**
- * A repository of resources. This allows access to the resource by {@link ResourceType}.
- */
-public interface IResourceRepository {
-
-    /**
-     * Returns the present {@link ResourceType}s in the project.
-     * @return an array containing all the type of resources existing in the project.
-     */
-    public abstract ResourceType[] getAvailableResourceTypes();
-
-    /**
-     * Returns an array of the existing resource for the specified type.
-     * @param type the type of the resources to return
-     */
-    public abstract ResourceItem[] getResources(ResourceType type);
-
-    /**
-     * Returns whether resources of the specified type are present.
-     * @param type the type of the resources to check.
-     */
-    public abstract boolean hasResources(ResourceType type);
-    
-    /**
-     * Returns whether the repository is a system repository.
-     */
-    public abstract boolean isSystemRepository();
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceItem.java
deleted file mode 100644
index c340ffe..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceItem.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-/**
- * Base class representing a Resource Item, as returned by a {@link IResourceRepository}.
- */
-public class ResourceItem implements Comparable<ResourceItem> {
-    
-    private final String mName;
-    
-    /**
-     * Constructs a new ResourceItem
-     * @param name the name of the resource as it appears in the XML and R.java files.
-     */
-    public ResourceItem(String name) {
-        mName = name;
-    }
-
-    /**
-     * Returns the name of the resource item.
-     */
-    public final String getName() {
-        return mName;
-    }
-
-    /**
-     * Compares the {@link ResourceItem} to another.
-     * @param other the ResourceItem to be compared to.
-     */
-    public int compareTo(ResourceItem other) {
-        return mName.compareTo(other.mName);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceType.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceType.java
deleted file mode 100644
index 008e1fa..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceType.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-/**
- * Enum representing a type of compiled resource.
- */
-public enum ResourceType {
-    ANIM("anim", "Animation"), //$NON-NLS-1$
-    ARRAY("array", "Array", "string-array", "integer-array"), //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-4$
-    ATTR("attr", "Attr"), //$NON-NLS-1$
-    COLOR("color", "Color"), //$NON-NLS-1$
-    DIMEN("dimen", "Dimension"), //$NON-NLS-1$
-    DRAWABLE("drawable", "Drawable"), //$NON-NLS-1$
-    ID("id", "ID"), //$NON-NLS-1$
-    LAYOUT("layout", "Layout"), //$NON-NLS-1$
-    MENU("menu", "Menu"), //$NON-NLS-1$
-    RAW("raw", "Raw"), //$NON-NLS-1$
-    STRING("string", "String"), //$NON-NLS-1$
-    STYLE("style", "Style"), //$NON-NLS-1$
-    STYLEABLE("styleable", "Styleable"), //$NON-NLS-1$
-    XML("xml", "XML"); //$NON-NLS-1$
-
-    private final String mName;
-    private final String mDisplayName;
-    private final String[] mAlternateXmlNames;
-
-    ResourceType(String name, String displayName, String... alternateXmlNames) {
-        mName = name;
-        mDisplayName = displayName;
-        mAlternateXmlNames = alternateXmlNames;
-    }
-    
-    /**
-     * Returns the resource type name, as used by XML files.
-     */
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * Returns a translated display name for the resource type.
-     */
-    public String getDisplayName() {
-        return mDisplayName;
-    }
-    
-    /**
-     * Returns the enum by its name as it appears in the XML or the R class.
-     * @param name name of the resource
-     * @return the matching {@link ResourceType} or <code>null</code> if no match was found.
-     */
-    public static ResourceType getEnum(String name) {
-        for (ResourceType rType : values()) {
-            if (rType.mName.equals(name)) {
-                return rType;
-            } else if (rType.mAlternateXmlNames != null) {
-                // if there are alternate Xml Names, we test those too
-                for (String alternate : rType.mAlternateXmlNames) {
-                    if (alternate.equals(name)) {
-                        return rType;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-    
-    /**
-     * Returns a formatted string usable in an XML to use the specified {@link ResourceItem}.
-     * @param resourceItem The resource item.
-     * @param system Whether this is a system resource or a project resource.
-     * @return a string in the format @[type]/[name] 
-     */
-    public String getXmlString(ResourceItem resourceItem, boolean system) {
-        if (this == ID && resourceItem instanceof IIdResourceItem) {
-            IIdResourceItem idResource = (IIdResourceItem)resourceItem;
-            if (idResource.isDeclaredInline()) {
-                return (system?"@android:":"@+") + mName + "/" + resourceItem.getName(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-            }
-        }
-
-        return (system?"@android:":"@") + mName + "/" + resourceItem.getName(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-    
-    /**
-     * Returns an array with all the names defined by this enum.
-     */
-    public static String[] getNames() {
-        ResourceType[] values = values();
-        String[] names = new String[values.length];
-        for (int i = values.length - 1; i >= 0; --i) {
-            names[i] = values[i].getName();
-        }
-        return names;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ViewClassInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ViewClassInfo.java
deleted file mode 100644
index 23eb1e4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ViewClassInfo.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
-
-/**
- * Information needed to represent a View or ViewGroup (aka Layout) item
- * in the layout hierarchy, as extracted from the main android.jar and the
- * associated attrs.xml.
- */
-public class ViewClassInfo {
-    /** Is this a layout class (i.e. ViewGroup) or just a view? */
-    private boolean mIsLayout;
-    /** FQCN e.g. android.view.View, never null. */
-    private String mCanonicalClassName;
-    /** Short class name, e.g. View, never null. */
-    private String mShortClassName;
-    /** Super class. Can be null. */
-    private ViewClassInfo mSuperClass;
-    /** Short javadoc. Can be null. */
-    private String mJavaDoc;    
-    /** Attributes for this view or view group. Can be empty but never null. */
-    private AttributeInfo[] mAttributes;
-    
-    public static class LayoutParamsInfo {
-        /** Short class name, e.g. LayoutData, never null. */
-        private String mShortClassName;
-        /** ViewLayout class info owning this layout data */
-        private ViewClassInfo mViewLayoutClass;
-        /** Super class. Can be null. */
-        private LayoutParamsInfo mSuperClass; 
-        /** Layout Data Attributes for layout classes. Can be empty but not null. */
-        private AttributeInfo[] mAttributes;
-
-        public LayoutParamsInfo(ViewClassInfo enclosingViewClassInfo,
-                String shortClassName, LayoutParamsInfo superClassInfo) {
-            mShortClassName = shortClassName;
-            mViewLayoutClass = enclosingViewClassInfo;
-            mSuperClass = superClassInfo;
-            mAttributes = new AttributeInfo[0];
-        }
-        
-        /** Returns short class name, e.g. "LayoutData" */
-        public String getShortClassName() {
-            return mShortClassName;
-        }
-        /** Returns the ViewLayout class info enclosing this layout data. Cannot null. */
-        public ViewClassInfo getViewLayoutClass() {
-            return mViewLayoutClass;
-        }
-        /** Returns the super class info. Can be null. */
-        public LayoutParamsInfo getSuperClass() {
-            return mSuperClass;
-        }
-        /** Returns the LayoutData attributes. Can be empty but not null. */
-        public AttributeInfo[] getAttributes() {
-            return mAttributes;
-        }
-        /** Sets the LayoutData attributes. Can be empty but not null. */
-        public void setAttributes(AttributeInfo[] attributes) {
-            mAttributes = attributes;
-        }
-    }
-
-    /** Layout data info for a layout class. Null for all non-layout classes and always
-     *  non-null for a layout class. */
-    public LayoutParamsInfo mLayoutData;
-
-    // --------
-    
-    public ViewClassInfo(boolean isLayout, String canonicalClassName, String shortClassName) {
-        mIsLayout = isLayout;
-        mCanonicalClassName = canonicalClassName;
-        mShortClassName = shortClassName;
-        mAttributes = new AttributeInfo[0];
-    }
-    
-    /** Returns whether this is a layout class (i.e. ViewGroup) or just a View */
-    public boolean isLayout() {
-        return mIsLayout;
-    }
-
-    /** Returns FQCN e.g. "android.view.View" */
-    public String getCanonicalClassName() {
-        return mCanonicalClassName;
-    }
-
-    /** Returns short class name, e.g. "View" */
-    public String getShortClassName() {
-        return mShortClassName;
-    }
-
-    /** Returns the super class. Can be null. */
-    public ViewClassInfo getSuperClass() {
-        return mSuperClass;
-    }
-
-    /** Returns a short javadoc */
-    public String getJavaDoc() {
-        return mJavaDoc;
-    }
-
-    /** Returns the attributes for this view or view group. Maybe empty but not null. */
-    public AttributeInfo[] getAttributes() {
-        return mAttributes;
-    }
-
-    /** Returns the LayoutData info for layout classes. Null for non-layout view classes. */
-    public LayoutParamsInfo getLayoutData() {
-        return mLayoutData;
-    }
-
-    /**
-     * Sets a link on the info of the super class of this View or ViewGroup.
-     * <p/>
-     * The super class info must be of the same kind (i.e. group to group or view to view)
-     * except for the top ViewGroup which links to the View info.
-     * <p/>
-     * The super class cannot be null except for the top View info.
-     */
-    public void setSuperClass(ViewClassInfo superClass) {
-        mSuperClass = superClass;
-    }
-
-    /** Sets the javadoc for this View or ViewGroup. */
-    public void setJavaDoc(String javaDoc) {
-        mJavaDoc = javaDoc;
-    }
-
-    /** Sets the list of attributes for this View or ViewGroup. */
-    public void setAttributes(AttributeInfo[] attributes) {
-        mAttributes = attributes;
-    }
-
-    /**
-     * Sets the {@link LayoutParamsInfo} for layout classes.
-     * Does nothing for non-layout view classes.
-     */
-    public void setLayoutParams(LayoutParamsInfo layoutData) {
-        if (mIsLayout) {
-            mLayoutData = layoutData;
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java
deleted file mode 100644
index 97028e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Resource Qualifier for Mobile Country Code.
- */
-public final class CountryCodeQualifier extends ResourceQualifier {
-    /** Default pixel density value. This means the property is not set. */
-    private final static int DEFAULT_CODE = -1;
-
-    private final static Pattern sCountryCodePattern = Pattern.compile("^mcc(\\d{3})$");//$NON-NLS-1$
-
-    private final int mCode;
-
-    public static final String NAME = "Mobile Country Code";
-
-    /**
-     * Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
-     * <code>null</code> is returned.
-     * @param segment the folder segment from which to create a qualifier.
-     * @return a new {@link CountryCodeQualifier} object or <code>null</code>
-     */
-    public static CountryCodeQualifier getQualifier(String segment) {
-        Matcher m = sCountryCodePattern.matcher(segment);
-        if (m.matches()) {
-            String v = m.group(1);
-
-            int code = -1;
-            try {
-                code = Integer.parseInt(v);
-            } catch (NumberFormatException e) {
-                // looks like the string we extracted wasn't a valid number.
-                return null;
-            }
-
-            CountryCodeQualifier qualifier = new CountryCodeQualifier(code);
-            return qualifier;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the folder name segment for the given value. This is equivalent to calling
-     * {@link #toString()} on a {@link CountryCodeQualifier} object.
-     * @param code the value of the qualifier, as returned by {@link #getCode()}.
-     */
-    public static String getFolderSegment(int code) {
-        if (code != DEFAULT_CODE && code >= 100 && code <=999) { // code is 3 digit.) {
-            return String.format("mcc%1$d", code); //$NON-NLS-1$
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    public CountryCodeQualifier() {
-        this(DEFAULT_CODE);
-    }
-
-    public CountryCodeQualifier(int code) {
-        mCode = code;
-    }
-
-    public int getCode() {
-        return mCode;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Country Code";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("mcc"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mCode != DEFAULT_CODE;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        CountryCodeQualifier qualifier = getQualifier(value);
-        if (qualifier != null) {
-            config.setCountryCodeQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof CountryCodeQualifier) {
-            return mCode == ((CountryCodeQualifier)qualifier).mCode;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mCode;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        return getFolderSegment(mCode);
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mCode != DEFAULT_CODE) {
-            return String.format("MCC %1$d", mCode);
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java
deleted file mode 100644
index f1ac8cf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IProject;
-
-
-/**
- * Represents the configuration for Resource Folders. All the properties have a default
- * value which means that the property is not set.
- */
-public final class FolderConfiguration implements Comparable<FolderConfiguration> {
-    public final static String QUALIFIER_SEP = "-"; //$NON-NLS-1$
-
-    private final ResourceQualifier[] mQualifiers = new ResourceQualifier[INDEX_COUNT];
-
-    private final static int INDEX_COUNTRY_CODE       = 0;
-    private final static int INDEX_NETWORK_CODE       = 1;
-    private final static int INDEX_LANGUAGE           = 2;
-    private final static int INDEX_REGION             = 3;
-    private final static int INDEX_SCREEN_SIZE        = 4;
-    private final static int INDEX_SCREEN_RATIO       = 5;
-    private final static int INDEX_SCREEN_ORIENTATION = 6;
-    private final static int INDEX_PIXEL_DENSITY      = 7;
-    private final static int INDEX_TOUCH_TYPE         = 8;
-    private final static int INDEX_KEYBOARD_STATE     = 9;
-    private final static int INDEX_TEXT_INPUT_METHOD  = 10;
-    private final static int INDEX_NAVIGATION_METHOD  = 11;
-    private final static int INDEX_SCREEN_DIMENSION   = 12;
-    private final static int INDEX_VERSION            = 13;
-    private final static int INDEX_COUNT              = 14;
-
-    /**
-     * Returns the number of {@link ResourceQualifier} that make up a Folder configuration.
-     */
-    public static int getQualifierCount() {
-        return INDEX_COUNT;
-    }
-
-    /**
-     * Sets the config from the qualifiers of a given <var>config</var>.
-     * @param config
-     */
-    public void set(FolderConfiguration config) {
-        if (config != null) {
-            for (int i = 0 ; i < INDEX_COUNT ; i++) {
-                mQualifiers[i] = config.mQualifiers[i];
-            }
-        }
-    }
-
-    /**
-     * Removes the qualifiers from the receiver if they are present (and valid)
-     * in the given configuration.
-     */
-    public void substract(FolderConfiguration config) {
-        for (int i = 0 ; i < INDEX_COUNT ; i++) {
-            if (config.mQualifiers[i] != null && config.mQualifiers[i].isValid()) {
-                mQualifiers[i] = null;
-            }
-        }
-    }
-
-    /**
-     * Returns the first invalid qualifier, or <code>null<code> if they are all valid (or if none
-     * exists).
-     */
-    public ResourceQualifier getInvalidQualifier() {
-        for (int i = 0 ; i < INDEX_COUNT ; i++) {
-            if (mQualifiers[i] != null && mQualifiers[i].isValid() == false) {
-                return mQualifiers[i];
-            }
-        }
-
-        // all allocated qualifiers are valid, we return null.
-        return null;
-    }
-
-    /**
-     * Returns whether the Region qualifier is valid. Region qualifier can only be present if a
-     * Language qualifier is present as well.
-     * @return true if the Region qualifier is valid.
-     */
-    public boolean checkRegion() {
-        if (mQualifiers[INDEX_LANGUAGE] == null && mQualifiers[INDEX_REGION] != null) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Adds a qualifier to the {@link FolderConfiguration}
-     * @param qualifier the {@link ResourceQualifier} to add.
-     */
-    public void addQualifier(ResourceQualifier qualifier) {
-        if (qualifier instanceof CountryCodeQualifier) {
-            mQualifiers[INDEX_COUNTRY_CODE] = qualifier;
-        } else if (qualifier instanceof NetworkCodeQualifier) {
-            mQualifiers[INDEX_NETWORK_CODE] = qualifier;
-        } else if (qualifier instanceof LanguageQualifier) {
-            mQualifiers[INDEX_LANGUAGE] = qualifier;
-        } else if (qualifier instanceof RegionQualifier) {
-            mQualifiers[INDEX_REGION] = qualifier;
-        } else if (qualifier instanceof ScreenSizeQualifier) {
-            mQualifiers[INDEX_SCREEN_SIZE] = qualifier;
-        } else if (qualifier instanceof ScreenRatioQualifier) {
-            mQualifiers[INDEX_SCREEN_RATIO] = qualifier;
-        } else if (qualifier instanceof ScreenOrientationQualifier) {
-            mQualifiers[INDEX_SCREEN_ORIENTATION] = qualifier;
-        } else if (qualifier instanceof PixelDensityQualifier) {
-            mQualifiers[INDEX_PIXEL_DENSITY] = qualifier;
-        } else if (qualifier instanceof TouchScreenQualifier) {
-            mQualifiers[INDEX_TOUCH_TYPE] = qualifier;
-        } else if (qualifier instanceof KeyboardStateQualifier) {
-            mQualifiers[INDEX_KEYBOARD_STATE] = qualifier;
-        } else if (qualifier instanceof TextInputMethodQualifier) {
-            mQualifiers[INDEX_TEXT_INPUT_METHOD] = qualifier;
-        } else if (qualifier instanceof NavigationMethodQualifier) {
-            mQualifiers[INDEX_NAVIGATION_METHOD] = qualifier;
-        } else if (qualifier instanceof ScreenDimensionQualifier) {
-            mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier;
-        } else if (qualifier instanceof VersionQualifier) {
-            mQualifiers[INDEX_VERSION] = qualifier;
-        }
-    }
-
-    /**
-     * Removes a given qualifier from the {@link FolderConfiguration}.
-     * @param qualifier the {@link ResourceQualifier} to remove.
-     */
-    public void removeQualifier(ResourceQualifier qualifier) {
-        for (int i = 0 ; i < INDEX_COUNT ; i++) {
-            if (mQualifiers[i] == qualifier) {
-                mQualifiers[i] = null;
-                return;
-            }
-        }
-    }
-
-    /**
-     * Returns a qualifier by its index. The total number of qualifiers can be accessed by
-     * {@link #getQualifierCount()}.
-     * @param index the index of the qualifier to return.
-     * @return the qualifier or null if there are none at the index.
-     */
-    public ResourceQualifier getQualifier(int index) {
-        return mQualifiers[index];
-    }
-
-    public void setCountryCodeQualifier(CountryCodeQualifier qualifier) {
-        mQualifiers[INDEX_COUNTRY_CODE] = qualifier;
-    }
-
-    public CountryCodeQualifier getCountryCodeQualifier() {
-        return (CountryCodeQualifier)mQualifiers[INDEX_COUNTRY_CODE];
-    }
-
-    public void setNetworkCodeQualifier(NetworkCodeQualifier qualifier) {
-        mQualifiers[INDEX_NETWORK_CODE] = qualifier;
-    }
-
-    public NetworkCodeQualifier getNetworkCodeQualifier() {
-        return (NetworkCodeQualifier)mQualifiers[INDEX_NETWORK_CODE];
-    }
-
-    public void setLanguageQualifier(LanguageQualifier qualifier) {
-        mQualifiers[INDEX_LANGUAGE] = qualifier;
-    }
-
-    public LanguageQualifier getLanguageQualifier() {
-        return (LanguageQualifier)mQualifiers[INDEX_LANGUAGE];
-    }
-
-    public void setRegionQualifier(RegionQualifier qualifier) {
-        mQualifiers[INDEX_REGION] = qualifier;
-    }
-
-    public RegionQualifier getRegionQualifier() {
-        return (RegionQualifier)mQualifiers[INDEX_REGION];
-    }
-
-    public void setScreenSizeQualifier(ScreenSizeQualifier qualifier) {
-        mQualifiers[INDEX_SCREEN_SIZE] = qualifier;
-    }
-
-    public ScreenSizeQualifier getScreenSizeQualifier() {
-        return (ScreenSizeQualifier)mQualifiers[INDEX_SCREEN_SIZE];
-    }
-
-    public void setScreenRatioQualifier(ScreenRatioQualifier qualifier) {
-        mQualifiers[INDEX_SCREEN_RATIO] = qualifier;
-    }
-
-    public ScreenRatioQualifier getScreenRatioQualifier() {
-        return (ScreenRatioQualifier)mQualifiers[INDEX_SCREEN_RATIO];
-    }
-
-    public void setScreenOrientationQualifier(ScreenOrientationQualifier qualifier) {
-        mQualifiers[INDEX_SCREEN_ORIENTATION] = qualifier;
-    }
-
-    public ScreenOrientationQualifier getScreenOrientationQualifier() {
-        return (ScreenOrientationQualifier)mQualifiers[INDEX_SCREEN_ORIENTATION];
-    }
-
-    public void setPixelDensityQualifier(PixelDensityQualifier qualifier) {
-        mQualifiers[INDEX_PIXEL_DENSITY] = qualifier;
-    }
-
-    public PixelDensityQualifier getPixelDensityQualifier() {
-        return (PixelDensityQualifier)mQualifiers[INDEX_PIXEL_DENSITY];
-    }
-
-    public void setTouchTypeQualifier(TouchScreenQualifier qualifier) {
-        mQualifiers[INDEX_TOUCH_TYPE] = qualifier;
-    }
-
-    public TouchScreenQualifier getTouchTypeQualifier() {
-        return (TouchScreenQualifier)mQualifiers[INDEX_TOUCH_TYPE];
-    }
-
-    public void setKeyboardStateQualifier(KeyboardStateQualifier qualifier) {
-        mQualifiers[INDEX_KEYBOARD_STATE] = qualifier;
-    }
-
-    public KeyboardStateQualifier getKeyboardStateQualifier() {
-        return (KeyboardStateQualifier)mQualifiers[INDEX_KEYBOARD_STATE];
-    }
-
-    public void setTextInputMethodQualifier(TextInputMethodQualifier qualifier) {
-        mQualifiers[INDEX_TEXT_INPUT_METHOD] = qualifier;
-    }
-
-    public TextInputMethodQualifier getTextInputMethodQualifier() {
-        return (TextInputMethodQualifier)mQualifiers[INDEX_TEXT_INPUT_METHOD];
-    }
-
-    public void setNavigationMethodQualifier(NavigationMethodQualifier qualifier) {
-        mQualifiers[INDEX_NAVIGATION_METHOD] = qualifier;
-    }
-
-    public NavigationMethodQualifier getNavigationMethodQualifier() {
-        return (NavigationMethodQualifier)mQualifiers[INDEX_NAVIGATION_METHOD];
-    }
-
-    public void setScreenDimensionQualifier(ScreenDimensionQualifier qualifier) {
-        mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier;
-    }
-
-    public ScreenDimensionQualifier getScreenDimensionQualifier() {
-        return (ScreenDimensionQualifier)mQualifiers[INDEX_SCREEN_DIMENSION];
-    }
-
-    public void setVersionQualifier(VersionQualifier qualifier) {
-        mQualifiers[INDEX_VERSION] = qualifier;
-    }
-
-    public VersionQualifier getVersionQualifier() {
-        return (VersionQualifier)mQualifiers[INDEX_VERSION];
-    }
-
-    /**
-     * Returns whether an object is equals to the receiver.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-
-        if (obj instanceof FolderConfiguration) {
-            FolderConfiguration fc = (FolderConfiguration)obj;
-            for (int i = 0 ; i < INDEX_COUNT ; i++) {
-                ResourceQualifier qualifier = mQualifiers[i];
-                ResourceQualifier fcQualifier = fc.mQualifiers[i];
-                if (qualifier != null) {
-                    if (qualifier.equals(fcQualifier) == false) {
-                        return false;
-                    }
-                } else if (fcQualifier != null) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return toString().hashCode();
-    }
-
-    /**
-     * Returns whether the Configuration has only default values.
-     */
-    public boolean isDefault() {
-        for (ResourceQualifier irq : mQualifiers) {
-            if (irq != null) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns the name of a folder with the configuration.
-     */
-    public String getFolderName(ResourceFolderType folder, IAndroidTarget target) {
-        StringBuilder result = new StringBuilder(folder.getName());
-
-        for (ResourceQualifier qualifier : mQualifiers) {
-            if (qualifier != null) {
-                String segment = qualifier.getFolderSegment(target);
-                if (segment != null && segment.length() > 0) {
-                    result.append(QUALIFIER_SEP);
-                    result.append(segment);
-                }
-            }
-        }
-
-        return result.toString();
-    }
-
-    /**
-     * Returns the name of a folder with the configuration.
-     */
-    public String getFolderName(ResourceFolderType folder, IProject project) {
-        IAndroidTarget target = null;
-        if (project != null) {
-            Sdk currentSdk = Sdk.getCurrent();
-            if (currentSdk != null) {
-                target = currentSdk.getTarget(project);
-            }
-        }
-
-        return getFolderName(folder, target);
-    }
-
-    /**
-     * Returns {@link #toDisplayString()}.
-     */
-    @Override
-    public String toString() {
-        return toDisplayString();
-    }
-
-    /**
-     * Returns a string valid for display purpose.
-     */
-    public String toDisplayString() {
-        if (isDefault()) {
-            return "default";
-        }
-
-        StringBuilder result = null;
-        int index = 0;
-        ResourceQualifier qualifier = null;
-
-        // pre- language/region qualifiers
-        while (index < INDEX_LANGUAGE) {
-            qualifier = mQualifiers[index++];
-            if (qualifier != null) {
-                if (result == null) {
-                    result = new StringBuilder();
-                } else {
-                    result.append(", "); //$NON-NLS-1$
-                }
-                result.append(qualifier.getStringValue());
-
-            }
-        }
-
-        // process the language/region qualifier in a custom way, if there are both non null.
-        if (mQualifiers[INDEX_LANGUAGE] != null && mQualifiers[INDEX_REGION] != null) {
-            String language = mQualifiers[INDEX_LANGUAGE].getStringValue();
-            String region = mQualifiers[INDEX_REGION].getStringValue();
-
-            if (result == null) {
-                result = new StringBuilder();
-            } else {
-                result.append(", "); //$NON-NLS-1$
-            }
-            result.append(String.format("%s_%s", language, region)); //$NON-NLS-1$
-
-            index += 2;
-        }
-
-        // post language/region qualifiers.
-        while (index < INDEX_COUNT) {
-            qualifier = mQualifiers[index++];
-            if (qualifier != null) {
-                if (result == null) {
-                    result = new StringBuilder();
-                } else {
-                    result.append(", "); //$NON-NLS-1$
-                }
-                result.append(qualifier.getStringValue());
-
-            }
-        }
-
-        return result == null ? null : result.toString();
-    }
-
-    public int compareTo(FolderConfiguration folderConfig) {
-        // default are always at the top.
-        if (isDefault()) {
-            if (folderConfig.isDefault()) {
-                return 0;
-            }
-            return -1;
-        }
-
-        // now we compare the qualifiers
-        for (int i = 0 ; i < INDEX_COUNT; i++) {
-            ResourceQualifier qualifier1 = mQualifiers[i];
-            ResourceQualifier qualifier2 = folderConfig.mQualifiers[i];
-
-            if (qualifier1 == null) {
-                if (qualifier2 == null) {
-                    continue;
-                } else {
-                    return -1;
-                }
-            } else {
-                if (qualifier2 == null) {
-                    return 1;
-                } else {
-                    int result = qualifier1.compareTo(qualifier2);
-
-                    if (result == 0) {
-                        continue;
-                    }
-
-                    return result;
-                }
-            }
-        }
-
-        // if we arrive here, all the qualifier matches
-        return 0;
-    }
-
-    /**
-     * Returns whether the configuration is a match for the given reference config.
-     * <p/>A match means that, for each qualifier of this config
-     * <ul>
-     * <li>The reference config has no value set
-     * <li>or, the qualifier of the reference config is a match. Depending on the qualifier type
-     * this does not mean the same exact value.</li>
-     * </ul>
-     * @param referenceConfig The reference configuration to test against.
-     * @return true if the configuration matches.
-     */
-    public boolean isMatchFor(FolderConfiguration referenceConfig) {
-        for (int i = 0 ; i < INDEX_COUNT ; i++) {
-            ResourceQualifier testQualifier = mQualifiers[i];
-            ResourceQualifier referenceQualifier = referenceConfig.mQualifiers[i];
-
-            // it's only a non match if both qualifiers are non-null, and they don't match.
-            if (testQualifier != null && referenceQualifier != null &&
-                        testQualifier.isMatchFor(referenceQualifier) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns the index of the first non null {@link ResourceQualifier} starting at index
-     * <var>startIndex</var>
-     * @param startIndex
-     * @return -1 if no qualifier was found.
-     */
-    public int getHighestPriorityQualifier(int startIndex) {
-        for (int i = startIndex ; i < INDEX_COUNT ; i++) {
-            if (mQualifiers[i] != null) {
-                return i;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Create default qualifiers.
-     */
-    public void createDefault() {
-        mQualifiers[INDEX_COUNTRY_CODE] = new CountryCodeQualifier();
-        mQualifiers[INDEX_NETWORK_CODE] = new NetworkCodeQualifier();
-        mQualifiers[INDEX_LANGUAGE] = new LanguageQualifier();
-        mQualifiers[INDEX_REGION] = new RegionQualifier();
-        mQualifiers[INDEX_SCREEN_SIZE] = new ScreenSizeQualifier();
-        mQualifiers[INDEX_SCREEN_RATIO] = new ScreenRatioQualifier();
-        mQualifiers[INDEX_SCREEN_ORIENTATION] = new ScreenOrientationQualifier();
-        mQualifiers[INDEX_PIXEL_DENSITY] = new PixelDensityQualifier();
-        mQualifiers[INDEX_TOUCH_TYPE] = new TouchScreenQualifier();
-        mQualifiers[INDEX_KEYBOARD_STATE] = new KeyboardStateQualifier();
-        mQualifiers[INDEX_TEXT_INPUT_METHOD] = new TextInputMethodQualifier();
-        mQualifiers[INDEX_NAVIGATION_METHOD] = new NavigationMethodQualifier();
-        mQualifiers[INDEX_SCREEN_DIMENSION] = new ScreenDimensionQualifier();
-        mQualifiers[INDEX_VERSION] = new VersionQualifier();
-    }
-
-    /**
-     * Returns an array of all the non null qualifiers.
-     */
-    public ResourceQualifier[] getQualifiers() {
-        int count = 0;
-        for (int i = 0 ; i < INDEX_COUNT ; i++) {
-            if (mQualifiers[i] != null) {
-                count++;
-            }
-        }
-
-        ResourceQualifier[] array = new ResourceQualifier[count];
-        int index = 0;
-        for (int i = 0 ; i < INDEX_COUNT ; i++) {
-            if (mQualifiers[i] != null) {
-                array[index++] = mQualifiers[i];
-            }
-        }
-
-        return array;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java
deleted file mode 100644
index e00428e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-
-
-/**
- * Resource Qualifier for keyboard state.
- */
-public final class KeyboardStateQualifier extends ResourceQualifier {
-
-    public static final String NAME = "Keyboard State";
-
-    private KeyboardState mValue = null;
-
-    /**
-     * Screen Orientation enum.
-     */
-    public static enum KeyboardState {
-        EXPOSED("keysexposed", "Exposed"), //$NON-NLS-1$
-        HIDDEN("keyshidden", "Hidden"),    //$NON-NLS-1$
-        SOFT("keyssoft", "Soft");          //$NON-NLS-1$
-
-        private String mValue;
-        private String mDisplayValue;
-
-        private KeyboardState(String value, String displayValue) {
-            mValue = value;
-            mDisplayValue = displayValue;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static KeyboardState getEnum(String value) {
-            for (KeyboardState orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public String getDisplayValue() {
-            return mDisplayValue;
-        }
-
-        public static int getIndex(KeyboardState value) {
-            int i = 0;
-            for (KeyboardState input : values()) {
-                if (value == input) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static KeyboardState getByIndex(int index) {
-            int i = 0;
-            for (KeyboardState value : values()) {
-                if (i == index) {
-                    return value;
-                }
-                i++;
-            }
-            return null;
-        }
-    }
-
-    public KeyboardStateQualifier() {
-        // pass
-    }
-
-    public KeyboardStateQualifier(KeyboardState value) {
-        mValue = value;
-    }
-
-    public KeyboardState getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Keyboard";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("keyboard"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        KeyboardState orientation = KeyboardState.getEnum(value);
-        if (orientation != null) {
-            KeyboardStateQualifier qualifier = new KeyboardStateQualifier();
-            qualifier.mValue = orientation;
-            config.setKeyboardStateQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean isMatchFor(ResourceQualifier qualifier) {
-        if (qualifier instanceof KeyboardStateQualifier) {
-            KeyboardStateQualifier referenceQualifier = (KeyboardStateQualifier)qualifier;
-
-            // special case where EXPOSED can be used for SOFT
-            if (referenceQualifier.mValue == KeyboardState.SOFT &&
-                    mValue == KeyboardState.EXPOSED) {
-                return true;
-            }
-
-            return referenceQualifier.mValue == mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) {
-        if (compareTo == null) {
-            return true;
-        }
-
-        KeyboardStateQualifier compareQualifier = (KeyboardStateQualifier)compareTo;
-        KeyboardStateQualifier referenceQualifier = (KeyboardStateQualifier)reference;
-        if (referenceQualifier.mValue == KeyboardState.SOFT) { // only case where there could be a
-                                                               // better qualifier
-            // only return true if it's a better value.
-            if (compareQualifier.mValue == KeyboardState.EXPOSED && mValue == KeyboardState.SOFT) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof KeyboardStateQualifier) {
-            return mValue == ((KeyboardStateQualifier)qualifier).mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            return mValue.getValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java
deleted file mode 100644
index 50f5c52..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.util.regex.Pattern;
-
-/**
- * Resource Qualifier for Language.
- */
-public final class LanguageQualifier extends ResourceQualifier {
-    private final static Pattern sLanguagePattern = Pattern.compile("^[a-z]{2}$"); //$NON-NLS-1$
-
-    public static final String NAME = "Language";
-
-    private String mValue;
-
-    /**
-     * Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
-     * <code>null</code> is returned.
-     * @param segment the folder segment from which to create a qualifier.
-     * @return a new {@link LanguageQualifier} object or <code>null</code>
-     */
-    public static LanguageQualifier getQualifier(String segment) {
-        if (sLanguagePattern.matcher(segment).matches()) {
-            LanguageQualifier qualifier = new LanguageQualifier();
-            qualifier.mValue = segment;
-
-            return qualifier;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the folder name segment for the given value. This is equivalent to calling
-     * {@link #toString()} on a {@link LanguageQualifier} object.
-     * @param value the value of the qualifier, as returned by {@link #getValue()}.
-     */
-    public static String getFolderSegment(String value) {
-        String segment = value.toLowerCase();
-        if (sLanguagePattern.matcher(segment).matches()) {
-            return segment;
-        }
-
-        return null;
-    }
-
-    public LanguageQualifier() {
-
-    }
-
-    public LanguageQualifier(String value) {
-        mValue = value;
-    }
-
-    public String getValue() {
-        if (mValue != null) {
-            return mValue;
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return NAME;
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("language"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        LanguageQualifier qualifier = getQualifier(value);
-        if (qualifier != null) {
-            config.setLanguageQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof LanguageQualifier) {
-            if (mValue == null) {
-                return ((LanguageQualifier)qualifier).mValue == null;
-            }
-            return mValue.equals(((LanguageQualifier)qualifier).mValue);
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            return getFolderSegment(mValue);
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue;
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java
deleted file mode 100644
index 50cb9cb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-
-
-/**
- * Resource Qualifier for Navigation Method.
- */
-public final class NavigationMethodQualifier extends ResourceQualifier {
-
-    public static final String NAME = "Navigation Method";
-
-    private NavigationMethod mValue;
-
-    /**
-     * Navigation Method enum.
-     */
-    public static enum NavigationMethod {
-        DPAD("dpad", "D-pad"), //$NON-NLS-1$
-        TRACKBALL("trackball", "Trackball"), //$NON-NLS-1$
-        WHEEL("wheel", "Wheel"), //$NON-NLS-1$
-        NONAV("nonav", "No Navigation"); //$NON-NLS-1$
-
-        private String mValue;
-        private String mDisplay;
-
-        private NavigationMethod(String value, String display) {
-            mValue = value;
-            mDisplay = display;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static NavigationMethod getEnum(String value) {
-            for (NavigationMethod orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public String getDisplayValue() {
-            return mDisplay;
-        }
-
-        public static int getIndex(NavigationMethod value) {
-            int i = 0;
-            for (NavigationMethod nav : values()) {
-                if (nav == value) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static NavigationMethod getByIndex(int index) {
-            int i = 0;
-            for (NavigationMethod value : values()) {
-                if (i == index) {
-                    return value;
-                }
-                i++;
-            }
-            return null;
-        }
-    }
-
-    public NavigationMethodQualifier() {
-        // pass
-    }
-
-    public NavigationMethodQualifier(NavigationMethod value) {
-        mValue = value;
-    }
-
-    public NavigationMethod getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Navigation";
-    }
-
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("navpad"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        NavigationMethod method = NavigationMethod.getEnum(value);
-        if (method != null) {
-            NavigationMethodQualifier qualifier = new NavigationMethodQualifier(method);
-            config.setNavigationMethodQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof NavigationMethodQualifier) {
-            return mValue == ((NavigationMethodQualifier)qualifier).mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            return mValue.getValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java
deleted file mode 100644
index 655fe4e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Resource Qualifier for Mobile Network Code Pixel Density.
- */
-public final class NetworkCodeQualifier extends ResourceQualifier {
-    /** Default pixel density value. This means the property is not set. */
-    private final static int DEFAULT_CODE = -1;
-
-    private final static Pattern sNetworkCodePattern = Pattern.compile("^mnc(\\d{1,3})$"); //$NON-NLS-1$
-
-    private final int mCode;
-
-    public final static String NAME = "Mobile Network Code";
-
-    /**
-     * Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
-     * <code>null</code> is returned.
-     * @param segment the folder segment from which to create a qualifier.
-     * @return a new {@link CountryCodeQualifier} object or <code>null</code>
-     */
-    public static NetworkCodeQualifier getQualifier(String segment) {
-        Matcher m = sNetworkCodePattern.matcher(segment);
-        if (m.matches()) {
-            String v = m.group(1);
-
-            int code = -1;
-            try {
-                code = Integer.parseInt(v);
-            } catch (NumberFormatException e) {
-                // looks like the string we extracted wasn't a valid number.
-                return null;
-            }
-
-            NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code);
-            return qualifier;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the folder name segment for the given value. This is equivalent to calling
-     * {@link #toString()} on a {@link NetworkCodeQualifier} object.
-     * @param code the value of the qualifier, as returned by {@link #getCode()}.
-     */
-    public static String getFolderSegment(int code) {
-        if (code != DEFAULT_CODE && code >= 1 && code <= 999) { // code is 1-3 digit.
-            return String.format("mnc%1$d", code); //$NON-NLS-1$
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    public NetworkCodeQualifier() {
-        this(DEFAULT_CODE);
-    }
-
-    public NetworkCodeQualifier(int code) {
-        mCode = code;
-    }
-
-    public int getCode() {
-        return mCode;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Network Code";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("mnc"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mCode != DEFAULT_CODE;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        Matcher m = sNetworkCodePattern.matcher(value);
-        if (m.matches()) {
-            String v = m.group(1);
-
-            int code = -1;
-            try {
-                code = Integer.parseInt(v);
-            } catch (NumberFormatException e) {
-                // looks like the string we extracted wasn't a valid number.
-                return false;
-            }
-
-            NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code);
-            config.setNetworkCodeQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof NetworkCodeQualifier) {
-            return mCode == ((NetworkCodeQualifier)qualifier).mCode;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mCode;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        return getFolderSegment(mCode);
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mCode != DEFAULT_CODE) {
-            return String.format("MNC %1$d", mCode);
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java
deleted file mode 100644
index ed33994..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.layoutlib.api.IDensityBasedResourceValue;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Resource Qualifier for Screen Pixel Density.
- */
-public final class PixelDensityQualifier extends ResourceQualifier {
-    private final static Pattern sDensityLegacyPattern = Pattern.compile("^(\\d+)dpi$");//$NON-NLS-1$
-
-    public static final String NAME = "Pixel Density";
-
-    private Density mValue = Density.MEDIUM;
-
-    /**
-     * Screen Orientation enum.
-     */
-    public static enum Density {
-        HIGH("hdpi", "High Density", IDensityBasedResourceValue.Density.HIGH), //$NON-NLS-1$
-        MEDIUM("mdpi", "Medium Density", IDensityBasedResourceValue.Density.MEDIUM), //$NON-NLS-1$
-        LOW("ldpi", "Low Density", IDensityBasedResourceValue.Density.LOW), //$NON-NLS-1$
-        NODPI("nodpi", "No Density", IDensityBasedResourceValue.Density.NODPI); //$NON-NLS-1$
-
-        private final String mValue;
-        private final String mDisplayValue;
-        private final IDensityBasedResourceValue.Density mDensity;
-
-        private Density(String value, String displayValue,
-                IDensityBasedResourceValue.Density density) {
-            mValue = value;
-            mDisplayValue = displayValue;
-            mDensity = density;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static Density getEnum(String value) {
-            for (Density orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        static Density getLegacyEnum(String value) {
-            Matcher m = sDensityLegacyPattern.matcher(value);
-            if (m.matches()) {
-                String v = m.group(1);
-
-                try {
-                    int density = Integer.parseInt(v);
-                    for (Density orient : values()) {
-                        if (orient.mDensity.getValue() == density) {
-                            return orient;
-                        }
-                    }
-                } catch (NumberFormatException e) {
-                    // looks like the string we extracted wasn't a valid number
-                    // which really shouldn't happen since the regexp would have failed.
-                }
-            }
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public int getDpiValue() {
-            return mDensity.getValue();
-        }
-
-        public String getLegacyValue() {
-            if (this != NODPI) {
-                return String.format("%1$ddpi", getDpiValue());
-            }
-
-            return "";
-        }
-
-        public String getDisplayValue() {
-            return mDisplayValue;
-        }
-
-        /**
-         * Returns the {@link com.android.layoutlib.api.IDensityBasedResourceValue.Density} value
-         * associated to this {@link Density}.
-         */
-        public IDensityBasedResourceValue.Density getDensity() {
-            return mDensity;
-        }
-
-        public static int getIndex(Density value) {
-            int i = 0;
-            for (Density input : values()) {
-                if (value == input) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static Density getByIndex(int index) {
-            int i = 0;
-            for (Density value : values()) {
-                if (i == index) {
-                    return value;
-                }
-                i++;
-            }
-            return null;
-        }
-    }
-
-    public PixelDensityQualifier() {
-        // pass
-    }
-
-    public PixelDensityQualifier(Density value) {
-        mValue = value;
-    }
-
-    public Density getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return NAME;
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("dpi"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        Density density = Density.getEnum(value);
-        if (density == null) {
-            density = Density.getLegacyEnum(value);
-        }
-
-        if (density != null) {
-            PixelDensityQualifier qualifier = new PixelDensityQualifier();
-            qualifier.mValue = density;
-            config.setPixelDensityQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean isMatchFor(ResourceQualifier qualifier) {
-        if (qualifier instanceof PixelDensityQualifier) {
-            // as long as there's a density qualifier, it's always a match.
-            // The best match will be found later.
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) {
-        if (compareTo == null) {
-            return true;
-        }
-
-        PixelDensityQualifier compareQ = (PixelDensityQualifier)compareTo;
-        PixelDensityQualifier referenceQ = (PixelDensityQualifier)reference;
-
-        if (mValue == referenceQ.mValue && compareQ.mValue != referenceQ.mValue) {
-            // got exact value, this is the best!
-            return true;
-        } else {
-            // in all case we're going to prefer the higher dpi.
-            // if reference is high, we want highest dpi.
-            // if reference is medium, we'll prefer to scale down high dpi, than scale up low dpi
-            // if reference if low, we'll prefer to scale down high than medium (2:1 over 4:3)
-            return mValue.mDensity.getValue() > compareQ.mValue.mDensity.getValue();
-        }
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof PixelDensityQualifier) {
-            return mValue == ((PixelDensityQualifier)qualifier).mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            if (target != null) {
-                AndroidVersion version = target.getVersion();
-                if (version.getApiLevel() <= 3 && version.getCodename() == null) {
-                    return mValue.getLegacyValue();
-                }
-            }
-            return mValue.getValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java
deleted file mode 100644
index bf192c2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Resource Qualifier for Region.
- */
-public final class RegionQualifier extends ResourceQualifier {
-    private final static Pattern sRegionPattern = Pattern.compile("^r([A-Z]{2})$"); //$NON-NLS-1$
-
-    public static final String NAME = "Region";
-
-    private String mValue;
-
-    /**
-     * Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
-     * <code>null</code> is returned.
-     * @param segment the folder segment from which to create a qualifier.
-     * @return a new {@link RegionQualifier} object or <code>null</code>
-     */
-    public static RegionQualifier getQualifier(String segment) {
-        Matcher m = sRegionPattern.matcher(segment);
-        if (m.matches()) {
-            RegionQualifier qualifier = new RegionQualifier();
-            qualifier.mValue = m.group(1);
-
-            return qualifier;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the folder name segment for the given value. This is equivalent to calling
-     * {@link #toString()} on a {@link RegionQualifier} object.
-     * @param value the value of the qualifier, as returned by {@link #getValue()}.
-     */
-    public static String getFolderSegment(String value) {
-        if (value != null) {
-            String segment = "r" + value.toUpperCase(); //$NON-NLS-1$
-            if (sRegionPattern.matcher(segment).matches()) {
-                return segment;
-            }
-        }
-
-        return "";  //$NON-NLS-1$
-    }
-
-    public RegionQualifier() {
-
-    }
-
-    public RegionQualifier(String value) {
-        mValue = value;
-    }
-
-    public String getValue() {
-        if (mValue != null) {
-            return mValue;
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return NAME;
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("region"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        RegionQualifier qualifier = getQualifier(value);
-        if (qualifier != null) {
-            config.setRegionQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof RegionQualifier) {
-            if (mValue == null) {
-                return ((RegionQualifier)qualifier).mValue == null;
-            }
-            return mValue.equals(((RegionQualifier)qualifier).mValue);
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        return getFolderSegment(mValue);
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue;
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java
deleted file mode 100644
index ba54ad0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-/**
- * Base class for resource qualifiers.
- * <p/>The resource qualifier classes are designed as immutable.
- */
-public abstract class ResourceQualifier implements Comparable<ResourceQualifier> {
-
-    /**
-     * Returns the human readable name of the qualifier.
-     */
-    public abstract String getName();
-
-    /**
-     * Returns a shorter human readable name for the qualifier.
-     * @see #getName()
-     */
-    public abstract String getShortName();
-
-    /**
-     * Returns the icon for the qualifier.
-     */
-    public abstract Image getIcon();
-
-    /**
-     * Returns whether the qualifier has a valid filter value.
-     */
-    public abstract boolean isValid();
-
-    /**
-     * Check if the value is valid for this qualifier, and if so sets the value
-     * into a Folder Configuration.
-     * @param value The value to check and set. Must not be null.
-     * @param config The folder configuration to receive the value. Must not be null.
-     * @return true if the value was valid and was set.
-     */
-    public abstract boolean checkAndSet(String value, FolderConfiguration config);
-
-    /**
-     * Returns a string formated to be used in a folder name.
-     * <p/>This is declared as abstract to force children classes to implement it.
-     */
-    public abstract String getFolderSegment(IAndroidTarget target);
-
-    /**
-     * Returns whether the given qualifier is a match for the receiver.
-     * <p/>The default implementation returns the result of {@link #equals(Object)}.
-     * <p/>Children class that re-implements this must implement
-     * {@link #isBetterMatchThan(ResourceQualifier, ResourceQualifier)} too.
-     * @param qualifier the reference qualifier
-     * @return true if the receiver is a match.
-     */
-    public boolean isMatchFor(ResourceQualifier qualifier) {
-        return equals(qualifier);
-    }
-
-    /**
-     * Returns true if the receiver is a better match for the given <var>reference</var> than
-     * the given <var>compareTo</var> comparable.
-     * @param compareTo The {@link ResourceQualifier} to compare to. Can be null, in which
-     * case the method must return <code>true</code>.
-     * @param reference The reference qualifier value for which the match is.
-     * @return true if the receiver is a better match.
-     */
-    public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) {
-        // the default is to always return false. This gives less overhead than always returning
-        // true, as it would only compare same values anyway.
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return getFolderSegment(null);
-    }
-
-    /**
-     * Returns a string formatted for display purpose.
-     */
-    public abstract String getStringValue();
-
-    /**
-     * Returns <code>true</code> if both objects are equal.
-     * <p/>This is declared as abstract to force children classes to implement it.
-     */
-    @Override
-    public abstract boolean equals(Object object);
-
-    /**
-     * Returns a hash code value for the object.
-     * <p/>This is declared as abstract to force children classes to implement it.
-     */
-    @Override
-    public abstract int hashCode();
-
-    public final int compareTo(ResourceQualifier o) {
-        return toString().compareTo(o.toString());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java
deleted file mode 100644
index 30929b2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Resource Qualifier for Screen Dimension.
- */
-public final class ScreenDimensionQualifier extends ResourceQualifier {
-    /** Default screen size value. This means the property is not set */
-    final static int DEFAULT_SIZE = -1;
-
-    private final static Pattern sDimensionPattern = Pattern.compile(
-            "^(\\d+)x(\\d+)$"); //$NON-NLS-1$
-
-    public static final String NAME = "Screen Dimension";
-
-    /** Screen size 1 value. This is not size X or Y because the folder name always
-     * contains the biggest size first. So if the qualifier is 400x200, size 1 will always be
-     * 400 but that'll be X in landscape and Y in portrait.
-     * Default value is <code>DEFAULT_SIZE</code> */
-    private int mValue1 = DEFAULT_SIZE;
-
-    /** Screen size 2 value. This is not size X or Y because the folder name always
-     * contains the biggest size first. So if the qualifier is 400x200, size 2 will always be
-     * 200 but that'll be Y in landscape and X in portrait.
-     * Default value is <code>DEFAULT_SIZE</code> */
-    private int mValue2 = DEFAULT_SIZE;
-
-    public ScreenDimensionQualifier() {
-        // pass
-    }
-
-    public ScreenDimensionQualifier(int value1, int value2) {
-        mValue1 = value1;
-        mValue2 = value2;
-    }
-
-    public int getValue1() {
-        return mValue1;
-    }
-
-    public int getValue2() {
-        return mValue2;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Dimension";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("dimension"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue1 != DEFAULT_SIZE && mValue2 != DEFAULT_SIZE;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        Matcher m = sDimensionPattern.matcher(value);
-        if (m.matches()) {
-            String d1 = m.group(1);
-            String d2 = m.group(2);
-
-            ScreenDimensionQualifier qualifier = getQualifier(d1, d2);
-            if (qualifier != null) {
-                config.setScreenDimensionQualifier(qualifier);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof ScreenDimensionQualifier) {
-            ScreenDimensionQualifier q = (ScreenDimensionQualifier)qualifier;
-            return (mValue1 == q.mValue1 && mValue2 == q.mValue2);
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return toString().hashCode();
-    }
-
-    public static ScreenDimensionQualifier getQualifier(String size1, String size2) {
-        try {
-            int s1 = Integer.parseInt(size1);
-            int s2 = Integer.parseInt(size2);
-
-            ScreenDimensionQualifier qualifier = new ScreenDimensionQualifier();
-
-            if (s1 > s2) {
-                qualifier.mValue1 = s1;
-                qualifier.mValue2 = s2;
-            } else {
-                qualifier.mValue1 = s2;
-                qualifier.mValue2 = s1;
-            }
-
-            return qualifier;
-        } catch (NumberFormatException e) {
-            // looks like the string we extracted wasn't a valid number.
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        return String.format("%1$dx%2$d", mValue1, mValue2); //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue1 != -1 && mValue2 != -1) {
-            return String.format("%1$dx%2$d", mValue1, mValue2);
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java
deleted file mode 100644
index a78f217..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-/**
- * Resource Qualifier for Screen Orientation.
- */
-public final class ScreenOrientationQualifier extends ResourceQualifier {
-
-    public static final String NAME = "Screen Orientation";
-
-    private ScreenOrientation mValue = null;
-
-    /**
-     * Screen Orientation enum.
-     */
-    public static enum ScreenOrientation {
-        PORTRAIT("port", "Portrait"), //$NON-NLS-1$
-        LANDSCAPE("land", "Landscape"), //$NON-NLS-1$
-        SQUARE("square", "Square"); //$NON-NLS-1$
-
-        private String mValue;
-        private String mDisplayValue;
-
-        private ScreenOrientation(String value, String displayValue) {
-            mValue = value;
-            mDisplayValue = displayValue;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static ScreenOrientation getEnum(String value) {
-            for (ScreenOrientation orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public String getDisplayValue() {
-            return mDisplayValue;
-        }
-
-        public static int getIndex(ScreenOrientation orientation) {
-            int i = 0;
-            for (ScreenOrientation orient : values()) {
-                if (orient == orientation) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static ScreenOrientation getByIndex(int index) {
-            int i = 0;
-            for (ScreenOrientation orient : values()) {
-                if (i == index) {
-                    return orient;
-                }
-                i++;
-            }
-
-            return null;
-        }
-    }
-
-    public ScreenOrientationQualifier() {
-    }
-
-    public ScreenOrientationQualifier(ScreenOrientation value) {
-        mValue = value;
-    }
-
-    public ScreenOrientation getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Orientation";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("orientation"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        ScreenOrientation orientation = ScreenOrientation.getEnum(value);
-        if (orientation != null) {
-            ScreenOrientationQualifier qualifier = new ScreenOrientationQualifier(orientation);
-            config.setScreenOrientationQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof ScreenOrientationQualifier) {
-            return mValue == ((ScreenOrientationQualifier)qualifier).mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            return mValue.getValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenRatioQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenRatioQualifier.java
deleted file mode 100644
index 08bce4f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenRatioQualifier.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-public class ScreenRatioQualifier extends ResourceQualifier {
-
-    public static final String NAME = "Screen Ratio";
-
-    private ScreenRatio mValue = null;
-
-    /**
-     * Screen Orientation enum.
-     */
-    public static enum ScreenRatio {
-        NOTLONG("notlong", "Not Long"), //$NON-NLS-1$
-        LONG("long", "Long"); //$NON-NLS-1$
-
-        private String mValue;
-        private String mDisplayValue;
-
-        private ScreenRatio(String value, String displayValue) {
-            mValue = value;
-            mDisplayValue = displayValue;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static ScreenRatio getEnum(String value) {
-            for (ScreenRatio orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public String getDisplayValue() {
-            return mDisplayValue;
-        }
-
-        public static int getIndex(ScreenRatio orientation) {
-            int i = 0;
-            for (ScreenRatio orient : values()) {
-                if (orient == orientation) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static ScreenRatio getByIndex(int index) {
-            int i = 0;
-            for (ScreenRatio orient : values()) {
-                if (i == index) {
-                    return orient;
-                }
-                i++;
-            }
-
-            return null;
-        }
-    }
-
-    public ScreenRatioQualifier() {
-    }
-
-    public ScreenRatioQualifier(ScreenRatio value) {
-        mValue = value;
-    }
-
-    public ScreenRatio getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Ratio";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("ratio"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        ScreenRatio size = ScreenRatio.getEnum(value);
-        if (size != null) {
-            ScreenRatioQualifier qualifier = new ScreenRatioQualifier(size);
-            config.setScreenRatioQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof ScreenRatioQualifier) {
-            return mValue == ((ScreenRatioQualifier)qualifier).mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            if (target == null) {
-                // Default behavior (when target==null) is qualifier is supported
-                return mValue.getValue();
-            }
-
-            AndroidVersion version = target.getVersion();
-            if (version.getApiLevel() >= 4 ||
-                    (version.getApiLevel() == 3 && "Donut".equals(version.getCodename()))) {
-                return mValue.getValue();
-            }
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenSizeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenSizeQualifier.java
deleted file mode 100644
index f48f54d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenSizeQualifier.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-/**
- * Resource Qualifier for Screen Size. Size can be "small", "normal", and "large"
- */
-public class ScreenSizeQualifier extends ResourceQualifier {
-
-    public static final String NAME = "Screen Size";
-
-    private ScreenSize mValue = null;
-
-    /**
-     * Screen Orientation enum.
-     */
-    public static enum ScreenSize {
-        SMALL("small", "Small"), //$NON-NLS-1$
-        NORMAL("normal", "Normal"), //$NON-NLS-1$
-        LARGE("large", "Large"); //$NON-NLS-1$
-
-        private String mValue;
-        private String mDisplayValue;
-
-        private ScreenSize(String value, String displayValue) {
-            mValue = value;
-            mDisplayValue = displayValue;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static ScreenSize getEnum(String value) {
-            for (ScreenSize orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public String getDisplayValue() {
-            return mDisplayValue;
-        }
-
-        public static int getIndex(ScreenSize orientation) {
-            int i = 0;
-            for (ScreenSize orient : values()) {
-                if (orient == orientation) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static ScreenSize getByIndex(int index) {
-            int i = 0;
-            for (ScreenSize orient : values()) {
-                if (i == index) {
-                    return orient;
-                }
-                i++;
-            }
-
-            return null;
-        }
-    }
-
-    public ScreenSizeQualifier() {
-    }
-
-    public ScreenSizeQualifier(ScreenSize value) {
-        mValue = value;
-    }
-
-    public ScreenSize getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Size";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("size"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        ScreenSize size = ScreenSize.getEnum(value);
-        if (size != null) {
-            ScreenSizeQualifier qualifier = new ScreenSizeQualifier(size);
-            config.setScreenSizeQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof ScreenSizeQualifier) {
-            return mValue == ((ScreenSizeQualifier)qualifier).mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            if (target == null) {
-                // Default behavior (when target==null) is qualifier is supported
-                return mValue.getValue();
-            }
-
-            AndroidVersion version = target.getVersion();
-            if (version.getApiLevel() >= 4 ||
-                    (version.getApiLevel() == 3 && "Donut".equals(version.getCodename()))) {
-                return mValue.getValue();
-            }
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java
deleted file mode 100644
index b73776c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-
-
-
-/**
- * Resource Qualifier for Text Input Method.
- */
-public final class TextInputMethodQualifier extends ResourceQualifier {
-
-    public static final String NAME = "Text Input Method";
-
-    private TextInputMethod mValue;
-
-    /**
-     * Screen Orientation enum.
-     */
-    public static enum TextInputMethod {
-        NOKEY("nokeys", "No Keys"), //$NON-NLS-1$
-        QWERTY("qwerty", "Qwerty"), //$NON-NLS-1$
-        TWELVEKEYS("12key", "12 Key"); //$NON-NLS-1$
-
-        private String mValue;
-        private String mDisplayValue;
-
-        private TextInputMethod(String value, String displayValue) {
-            mValue = value;
-            mDisplayValue = displayValue;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static TextInputMethod getEnum(String value) {
-            for (TextInputMethod orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public String getDisplayValue() {
-            return mDisplayValue;
-        }
-
-        public static int getIndex(TextInputMethod value) {
-            int i = 0;
-            for (TextInputMethod input : values()) {
-                if (value == input) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static TextInputMethod getByIndex(int index) {
-            int i = 0;
-            for (TextInputMethod value : values()) {
-                if (i == index) {
-                    return value;
-                }
-                i++;
-            }
-            return null;
-        }
-    }
-
-    public TextInputMethodQualifier() {
-        // pass
-    }
-
-    public TextInputMethodQualifier(TextInputMethod value) {
-        mValue = value;
-    }
-
-    public TextInputMethod getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Text Input";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("text_input"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        TextInputMethod method = TextInputMethod.getEnum(value);
-        if (method != null) {
-            TextInputMethodQualifier qualifier = new TextInputMethodQualifier();
-            qualifier.mValue = method;
-            config.setTextInputMethodQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof TextInputMethodQualifier) {
-            return mValue == ((TextInputMethodQualifier)qualifier).mValue;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            return mValue.getValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java
deleted file mode 100644
index b3bad48..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-
-/**
- * Resource Qualifier for Touch Screen type.
- */
-public final class TouchScreenQualifier extends ResourceQualifier {
-
-    public static final String NAME = "Touch Screen";
-
-    private TouchScreenType mValue;
-
-    /**
-     * Screen Orientation enum.
-     */
-    public static enum TouchScreenType {
-        NOTOUCH("notouch", "No Touch"), //$NON-NLS-1$
-        STYLUS("stylus", "Stylus"), //$NON-NLS-1$
-        FINGER("finger", "Finger"); //$NON-NLS-1$
-
-        private String mValue;
-        private String mDisplayValue;
-
-        private TouchScreenType(String value, String displayValue) {
-            mValue = value;
-            mDisplayValue = displayValue;
-        }
-
-        /**
-         * Returns the enum for matching the provided qualifier value.
-         * @param value The qualifier value.
-         * @return the enum for the qualifier value or null if no matching was found.
-         */
-        public static TouchScreenType getEnum(String value) {
-            for (TouchScreenType orient : values()) {
-                if (orient.mValue.equals(value)) {
-                    return orient;
-                }
-            }
-
-            return null;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public String getDisplayValue() {
-            return mDisplayValue;
-        }
-
-        public static int getIndex(TouchScreenType touch) {
-            int i = 0;
-            for (TouchScreenType t : values()) {
-                if (t == touch) {
-                    return i;
-                }
-
-                i++;
-            }
-
-            return -1;
-        }
-
-        public static TouchScreenType getByIndex(int index) {
-            int i = 0;
-            for (TouchScreenType value : values()) {
-                if (i == index) {
-                    return value;
-                }
-                i++;
-            }
-
-            return null;
-        }
-    }
-
-    public TouchScreenQualifier() {
-        // pass
-    }
-
-    public TouchScreenQualifier(TouchScreenType touchValue) {
-        mValue = touchValue;
-    }
-
-    public TouchScreenType getValue() {
-        return mValue;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return NAME;
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("touch"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValue != null;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        TouchScreenType type = TouchScreenType.getEnum(value);
-        if (type != null) {
-            TouchScreenQualifier qualifier = new TouchScreenQualifier();
-            qualifier.mValue = type;
-            config.setTouchTypeQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof TouchScreenQualifier) {
-            return mValue == ((TouchScreenQualifier)qualifier).mValue;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mValue != null) {
-            return mValue.hashCode();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (mValue != null) {
-            return mValue.getValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != null) {
-            return mValue.getDisplayValue();
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/VersionQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/VersionQualifier.java
deleted file mode 100644
index 5744fea..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/VersionQualifier.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.graphics.Image;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Resource Qualifier for Platform Version.
- */
-public final class VersionQualifier extends ResourceQualifier {
-    /** Default pixel density value. This means the property is not set. */
-    private final static int DEFAULT_VERSION = -1;
-
-    private final static Pattern sCountryCodePattern = Pattern.compile("^v(\\d+)$");//$NON-NLS-1$
-
-    private int mVersion = DEFAULT_VERSION;
-
-    public static final String NAME = "Platform Version";
-
-    /**
-     * Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
-     * <code>null</code> is returned.
-     * @param segment the folder segment from which to create a qualifier.
-     * @return a new {@link VersionQualifier} object or <code>null</code>
-     */
-    public static VersionQualifier getQualifier(String segment) {
-        Matcher m = sCountryCodePattern.matcher(segment);
-        if (m.matches()) {
-            String v = m.group(1);
-
-            int code = -1;
-            try {
-                code = Integer.parseInt(v);
-            } catch (NumberFormatException e) {
-                // looks like the string we extracted wasn't a valid number.
-                return null;
-            }
-
-            VersionQualifier qualifier = new VersionQualifier();
-            qualifier.mVersion = code;
-            return qualifier;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the folder name segment for the given value. This is equivalent to calling
-     * {@link #toString()} on a {@link VersionQualifier} object.
-     * @param version the value of the qualifier, as returned by {@link #getVersion()}.
-     */
-    public static String getFolderSegment(int version) {
-        if (version != DEFAULT_VERSION) {
-            return String.format("v%1$d", version); //$NON-NLS-1$
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    public int getVersion() {
-        return mVersion;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public String getShortName() {
-        return "Version";
-    }
-
-    @Override
-    public Image getIcon() {
-        return IconFactory.getInstance().getIcon("version"); //$NON-NLS-1$
-    }
-
-    @Override
-    public boolean isValid() {
-        return mVersion != DEFAULT_VERSION;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        VersionQualifier qualifier = getQualifier(value);
-        if (qualifier != null) {
-            config.setVersionQualifier(qualifier);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof VersionQualifier) {
-            return mVersion == ((VersionQualifier)qualifier).mVersion;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mVersion;
-    }
-
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String getFolderSegment(IAndroidTarget target) {
-        if (target == null) {
-            // Default behavior (when target==null) is qualifier is supported
-            return getFolderSegment(mVersion);
-        }
-
-        AndroidVersion version = target.getVersion();
-        if (version.getApiLevel() >= 3) {
-            return getFolderSegment(mVersion);
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mVersion != DEFAULT_VERSION) {
-            return String.format("API %1$d", mVersion);
-        }
-
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java
deleted file mode 100644
index df716b2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IProjectListener;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A monitor for the compiled resources. This only monitors changes in the resources of type
- *  {@link ResourceType#ID}.
- */
-public final class CompiledResourcesMonitor implements IFileListener, IProjectListener {
-
-    private final static CompiledResourcesMonitor sThis = new CompiledResourcesMonitor();
-
-    /**
-     * Sets up the monitoring system.
-     * @param monitor The main Resource Monitor.
-     */
-    public static void setupMonitor(ResourceMonitor monitor) {
-        monitor.addFileListener(sThis, IResourceDelta.ADDED | IResourceDelta.CHANGED);
-        monitor.addProjectListener(sThis);
-    }
-
-    /**
-     * private constructor to prevent construction.
-     */
-    private CompiledResourcesMonitor() {
-    }
-
-
-    /* (non-Javadoc)
-     * Sent when a file changed : if the file is the R class, then it is parsed again to update
-     * the internal data.
-     *
-     * @param file The file that changed.
-     * @param markerDeltas The marker deltas for the file.
-     * @param kind The change kind. This is equivalent to
-     * {@link IResourceDelta#accept(IResourceDeltaVisitor)}
-     *
-     * @see IFileListener#fileChanged
-     */
-    public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
-        if (file.getName().equals(AndroidConstants.FN_COMPILED_RESOURCE_CLASS)) {
-            loadAndParseRClass(file.getProject());
-        }
-    }
-
-    /**
-     * Processes project close event.
-     */
-    public void projectClosed(IProject project) {
-        // the ProjectResources object will be removed by the ResourceManager.
-    }
-
-    /**
-     * Processes project delete event.
-     */
-    public void projectDeleted(IProject project) {
-        // the ProjectResources object will be removed by the ResourceManager.
-    }
-
-    /**
-     * Processes project open event.
-     */
-    public void projectOpened(IProject project) {
-        // when the project is opened, we get an ADDED event for each file, so we don't
-        // need to do anything here.
-    }
-
-    /**
-     * Processes existing project at init time.
-     */
-    public void projectOpenedWithWorkspace(IProject project) {
-        try {
-            // check this is an android project
-            if (project.hasNature(AndroidConstants.NATURE)) {
-                loadAndParseRClass(project);
-            }
-        } catch (CoreException e) {
-            // pass
-        }
-    }
-
-    private void loadAndParseRClass(IProject project) {
-        try {
-            // first check there's a ProjectResources to store the content
-            ProjectResources projectResources = ResourceManager.getInstance().getProjectResources(
-                    project);
-
-            if (projectResources != null) {
-                // create the classname
-                String className = getRClassName(project);
-                if (className == null) {
-                    // We need to abort.
-                    AdtPlugin.log(IStatus.ERROR,
-                            "loadAndParseRClass: failed to find manifest package for project %1$s", //$NON-NLS-1$
-                            project.getName());
-                    return;
-                }
-
-                // create a temporary class loader to load it.
-                ProjectClassLoader loader = new ProjectClassLoader(null /* parentClassLoader */,
-                        project);
-
-                try {
-                    Class<?> clazz = loader.loadClass(className);
-
-                    if (clazz != null) {
-                        // create the maps to store the result of the parsing
-                        Map<String, Map<String, Integer>> resourceValueMap =
-                            new HashMap<String, Map<String, Integer>>();
-                        Map<Integer, String[]> genericValueToNameMap =
-                            new HashMap<Integer, String[]>();
-                        Map<IntArrayWrapper, String> styleableValueToNameMap =
-                            new HashMap<IntArrayWrapper, String>();
-
-                        // parse the class
-                        if (parseClass(clazz, genericValueToNameMap, styleableValueToNameMap,
-                                resourceValueMap)) {
-                            // now we associate the maps to the project.
-                            projectResources.setCompiledResources(genericValueToNameMap,
-                                    styleableValueToNameMap, resourceValueMap);
-                        }
-                    }
-                } catch (Error e) {
-                    // Log this error with the class name we're trying to load and abort.
-                    AdtPlugin.log(e, "loadAndParseRClass failed to find class %1$s", className); //$NON-NLS-1$
-                }
-            }
-        } catch (ClassNotFoundException e) {
-            // pass
-        }
-    }
-
-    /**
-     * Parses a R class, and fills maps.
-     * @param rClass the class to parse
-     * @param genericValueToNameMap
-     * @param styleableValueToNameMap
-     * @param resourceValueMap
-     * @return True if we managed to parse the R class.
-     */
-    private boolean parseClass(Class<?> rClass, Map<Integer, String[]> genericValueToNameMap,
-            Map<IntArrayWrapper, String> styleableValueToNameMap, Map<String,
-            Map<String, Integer>> resourceValueMap) {
-        try {
-            for (Class<?> inner : rClass.getDeclaredClasses()) {
-                String resType = inner.getSimpleName();
-
-                Map<String, Integer> fullMap = new HashMap<String, Integer>();
-                resourceValueMap.put(resType, fullMap);
-
-                for (Field f : inner.getDeclaredFields()) {
-                    // only process static final fields.
-                    int modifiers = f.getModifiers();
-                    if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
-                        Class<?> type = f.getType();
-                        if (type.isArray() && type.getComponentType() == int.class) {
-                            // if the object is an int[] we put it in the styleable map
-                            styleableValueToNameMap.put(new IntArrayWrapper((int[]) f.get(null)),
-                                    f.getName());
-                        } else if (type == int.class) {
-                            Integer value = (Integer) f.get(null);
-                            genericValueToNameMap.put(value, new String[] { f.getName(), resType });
-                            fullMap.put(f.getName(), value);
-                        } else {
-                            assert false;
-                        }
-                    }
-                }
-            }
-
-            return true;
-        } catch (IllegalArgumentException e) {
-        } catch (IllegalAccessException e) {
-        }
-        return false;
-    }
-
-    /**
-     * Returns the class name of the R class, based on the project's manifest's package.
-     *
-     * @return A class name (e.g. "my.app.R") or null if there's no valid package in the manifest.
-     */
-    private String getRClassName(IProject project) {
-        try {
-            IFile manifestFile = AndroidManifestParser.getManifest(project);
-            if (manifestFile != null && manifestFile.isSynchronized(IResource.DEPTH_ZERO)) {
-                AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile);
-                if (data != null) {
-                    String javaPackage = data.getPackage();
-                    return javaPackage + ".R"; //$NON-NLS-1$
-                }
-            }
-        } catch (CoreException e) {
-            // This will typically happen either because the manifest file is not present
-            // and/or the workspace needs to be refreshed.
-            AdtPlugin.logAndPrintError(e,
-                    "Android Resources",
-                    "Failed to find the package of the AndroidManifest of project %1$s. Reason: %2$s",
-                    project.getName(),
-                    e.getMessage());
-        }
-        return null;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ConfigurableResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ConfigurableResourceItem.java
deleted file mode 100644
index 2a998f8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ConfigurableResourceItem.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-/**
- * Represents a resource item that can exist in multiple "alternate" versions. 
- */
-public class ConfigurableResourceItem extends ProjectResourceItem {
-    
-    /**
-     * Constructs a new Resource Item.
-     * @param name the name of the resource as it appears in the XML and R.java files.
-     */
-    public ConfigurableResourceItem(String name) {
-        super(name);
-    }
-
-    /**
-     * Returns if the resource item has at least one non-default configuration.
-     */
-    public boolean hasAlternates() {
-        for (ResourceFile file : mFiles) {
-            if (file.getFolder().getConfiguration().isDefault() == false) {
-                return true;
-            }
-        }
-        
-        return false;
-    }
-
-    /**
-     * Returns whether the resource has a default version, with no qualifier.
-     */
-    public boolean hasDefault() {
-        for (ResourceFile file : mFiles) {
-            if (file.getFolder().getConfiguration().isDefault()) {
-                return true;
-            }
-        }
-        
-        // We only want to return false if there's no default and more than 0 items.
-        return (mFiles.size() == 0);
-    }
-
-    /**
-     * Returns the number of alternate versions of this resource.
-     */
-    public int getAlternateCount() {
-        int count = 0;
-        for (ResourceFile file : mFiles) {
-            if (file.getFolder().getConfiguration().isDefault() == false) {
-                count++;
-            }
-        }
-
-        return count;
-    }
-
-    /*
-     * (non-Javadoc)
-     * Returns whether the item can be edited directly (ie it does not have alternate versions).
-     */
-    @Override
-    public boolean isEditableDirectly() {
-        return hasAlternates() == false;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/FolderTypeRelationship.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/FolderTypeRelationship.java
deleted file mode 100644
index 4b45f6e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/FolderTypeRelationship.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This class gives access to the bi directional relationship between {@link ResourceType} and
- * {@link ResourceFolderType}.
- */
-public final class FolderTypeRelationship {
-    
-    private final static HashMap<ResourceType, ResourceFolderType[]> mTypeToFolderMap =
-        new HashMap<ResourceType, ResourceFolderType[]>();
-        
-    private final static HashMap<ResourceFolderType, ResourceType[]> mFolderToTypeMap =
-        new HashMap<ResourceFolderType, ResourceType[]>();
-    
-    // generate the relationships.
-    static {
-        HashMap<ResourceType, List<ResourceFolderType>> typeToFolderMap =
-            new HashMap<ResourceType, List<ResourceFolderType>>();
-        
-        HashMap<ResourceFolderType, List<ResourceType>> folderToTypeMap =
-            new HashMap<ResourceFolderType, List<ResourceType>>();
-
-        add(ResourceType.ANIM, ResourceFolderType.ANIM, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.ARRAY, ResourceFolderType.VALUES, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.COLOR, ResourceFolderType.VALUES, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.COLOR, ResourceFolderType.COLOR, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.DIMEN, ResourceFolderType.VALUES, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.DRAWABLE, ResourceFolderType.VALUES, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.DRAWABLE, ResourceFolderType.DRAWABLE, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.ID, ResourceFolderType.VALUES, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.LAYOUT, ResourceFolderType.LAYOUT, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.MENU, ResourceFolderType.MENU, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.RAW, ResourceFolderType.RAW, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.STRING, ResourceFolderType.VALUES, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.STYLE, ResourceFolderType.VALUES, typeToFolderMap, folderToTypeMap);
-        add(ResourceType.XML, ResourceFolderType.XML, typeToFolderMap, folderToTypeMap);
-        
-        optimize(typeToFolderMap, folderToTypeMap);
-    }
-    
-    /**
-     * Returns a list of {@link ResourceType}s that can be generated from files inside a folder
-     * of the specified type.
-     * @param folderType The folder type.
-     * @return an array of {@link ResourceType}
-     */
-    public static ResourceType[] getRelatedResourceTypes(ResourceFolderType folderType) {
-        ResourceType[] array = mFolderToTypeMap.get(folderType);
-        if (array != null) {
-            return array;
-        }
-        return new ResourceType[0];
-    }
-    
-    /**
-     * Returns a list of {@link ResourceFolderType} that can contain files generating resources
-     * of the specified type.
-     * @param resType the type of resource.
-     * @return an array of {@link ResourceFolderType}
-     */
-    public static ResourceFolderType[] getRelatedFolders(ResourceType resType) {
-        ResourceFolderType[] array = mTypeToFolderMap.get(resType);
-        if (array != null) {
-            return array;
-        }
-        return new ResourceFolderType[0];
-    }
-    
-    /**
-     * Returns true if the {@link ResourceType} and the {@link ResourceFolderType} values match.
-     * @param resType the resource type.
-     * @param folderType the folder type.
-     * @return true if files inside the folder of the specified {@link ResourceFolderType}
-     * could generate a resource of the specified {@link ResourceType}
-     */
-    public static boolean match(ResourceType resType, ResourceFolderType folderType) {
-        ResourceFolderType[] array = mTypeToFolderMap.get(resType);
-        
-        if (array != null && array.length > 0) {
-            for (ResourceFolderType fType : array) {
-                if (fType == folderType) {
-                    return true;
-                }
-            }
-        }
-        
-        return false;
-    }
-    
-    /**
-     * Adds a {@link ResourceType} - {@link ResourceFolderType} relationship. this indicates that
-     * a file in the folder can generate a resource of the specified type.
-     * @param type The resourceType
-     * @param folder The {@link ResourceFolderType}
-     * @param folderToTypeMap 
-     * @param typeToFolderMap 
-     */
-    private static void add(ResourceType type, ResourceFolderType folder,
-            HashMap<ResourceType, List<ResourceFolderType>> typeToFolderMap,
-            HashMap<ResourceFolderType, List<ResourceType>> folderToTypeMap) {
-        // first we add the folder to the list associated with the type.
-        List<ResourceFolderType> folderList = typeToFolderMap.get(type);
-        if (folderList == null) {
-            folderList = new ArrayList<ResourceFolderType>();
-            typeToFolderMap.put(type, folderList);
-        }
-        if (folderList.indexOf(folder) == -1) {
-            folderList.add(folder);
-        }
-        
-        // now we add the type to the list associated with the folder.
-        List<ResourceType> typeList = folderToTypeMap.get(folder);
-        if (typeList == null) {
-            typeList = new ArrayList<ResourceType>();
-            folderToTypeMap.put(folder, typeList);
-        }
-        if (typeList.indexOf(type) == -1) {
-            typeList.add(type);
-        }
-    }
-
-    /**
-     * Optimize the map to contains array instead of lists (since the api returns arrays)
-     * @param typeToFolderMap
-     * @param folderToTypeMap
-     */
-    private static void optimize(HashMap<ResourceType, List<ResourceFolderType>> typeToFolderMap,
-            HashMap<ResourceFolderType, List<ResourceType>> folderToTypeMap) {
-        Set<ResourceType> types = typeToFolderMap.keySet();
-        for (ResourceType type : types) {
-            List<ResourceFolderType> list = typeToFolderMap.get(type);
-            mTypeToFolderMap.put(type, list.toArray(new ResourceFolderType[list.size()]));
-        }
-
-        Set<ResourceFolderType> folders = folderToTypeMap.keySet();
-        for (ResourceFolderType folder : folders) {
-            List<ResourceType> list = folderToTypeMap.get(folder);
-            mFolderToTypeMap.put(folder, list.toArray(new ResourceType[list.size()]));
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IdResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IdResourceItem.java
deleted file mode 100644
index a3e42c6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IdResourceItem.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.IIdResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-
-/**
- * Represents a resource item of type {@link ResourceType#ID}
- */
-public class IdResourceItem extends ProjectResourceItem implements IIdResourceItem {
-
-    private final boolean mIsDeclaredInline;
-
-    /**
-     * Constructs a new ResourceItem.
-     * @param name the name of the resource as it appears in the XML and R.java files.
-     * @param isDeclaredInline Whether this id was declared inline.
-     */
-    IdResourceItem(String name, boolean isDeclaredInline) {
-        super(name);
-        mIsDeclaredInline = isDeclaredInline;
-    }
-
-    /*
-     * (non-Javadoc)
-     * Returns whether the ID resource has been declared inline inside another resource XML file. 
-     */
-    public boolean isDeclaredInline() {
-        return mIsDeclaredInline;
-    }
-
-    /* (non-Javadoc)
-     * Returns whether the item can be edited (ie, the id was not declared inline).
-     */
-    @Override
-    public boolean isEditableDirectly() {
-        return !mIsDeclaredInline;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IntArrayWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IntArrayWrapper.java
deleted file mode 100644
index f21b15e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IntArrayWrapper.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import java.util.Arrays;
-
-
-/**
- * Wrapper around a int[] to provide hashCode/equals support.
- */
-public final class IntArrayWrapper {
-    
-    private int[] mData;
-    
-    public IntArrayWrapper(int[] data) {
-        mData = data;
-    }
-    
-    public void set(int[] data) {
-        mData = data;
-    }
-    
-    @Override
-    public int hashCode() {
-        return Arrays.hashCode(mData);
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (getClass().equals(obj.getClass())) {
-            return Arrays.equals(mData, ((IntArrayWrapper)obj).mData);
-        }
-
-        return super.equals(obj);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/MultiResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/MultiResourceFile.java
deleted file mode 100644
index 2d2749d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/MultiResourceFile.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFile;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.utils.ResourceValue;
-import com.android.layoutlib.utils.ValueResourceParser;
-import com.android.layoutlib.utils.ValueResourceParser.IValueResourceRepository;
-
-import org.eclipse.core.runtime.CoreException;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Set;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Represents a resource file able to declare multiple resources, which could be of
- * different {@link ResourceType}.
- * <p/>
- * This is typically an XML file inside res/values.
- */
-public final class MultiResourceFile extends ResourceFile implements IValueResourceRepository {
-
-    private final static SAXParserFactory sParserFactory = SAXParserFactory.newInstance();
-
-    private final HashMap<ResourceType, HashMap<String, ResourceValue>> mResourceItems =
-        new HashMap<ResourceType, HashMap<String, ResourceValue>>();
-
-    public MultiResourceFile(IAbstractFile file, ResourceFolder folder) {
-        super(file, folder);
-    }
-
-    @Override
-    public ResourceType[] getResourceTypes() {
-        update();
-
-        Set<ResourceType> keys = mResourceItems.keySet();
-
-        return keys.toArray(new ResourceType[keys.size()]);
-    }
-
-    @Override
-    public boolean hasResources(ResourceType type) {
-        update();
-
-        HashMap<String, ResourceValue> list = mResourceItems.get(type);
-        return (list != null && list.size() > 0);
-    }
-
-    @Override
-    public Collection<ProjectResourceItem> getResources(ResourceType type,
-            ProjectResources projectResources) {
-        update();
-
-        HashMap<String, ResourceValue> list = mResourceItems.get(type);
-
-        ArrayList<ProjectResourceItem> items = new ArrayList<ProjectResourceItem>();
-
-        if (list != null) {
-            Collection<ResourceValue> values = list.values();
-            for (ResourceValue res : values) {
-                ProjectResourceItem item = projectResources.findResourceItem(type, res.getName());
-
-                if (item == null) {
-                    if (type == ResourceType.ID) {
-                        item = new IdResourceItem(res.getName(), false /* isDeclaredInline */);
-                    } else {
-                        item = new ConfigurableResourceItem(res.getName());
-                    }
-                    items.add(item);
-                }
-
-                item.add(this);
-            }
-        }
-
-        return items;
-    }
-
-    /**
-     * Updates the Resource items if necessary.
-     */
-    private void update() {
-        if (isTouched() == true) {
-            // reset current content.
-            mResourceItems.clear();
-
-            // need to parse the file and find the content.
-            parseFile();
-
-            resetTouch();
-        }
-    }
-
-    /**
-     * Parses the file and creates a list of {@link ResourceType}.
-     */
-    private void parseFile() {
-        try {
-            SAXParser parser = sParserFactory.newSAXParser();
-            parser.parse(getFile().getContents(), new ValueResourceParser(this, isFramework()));
-        } catch (ParserConfigurationException e) {
-        } catch (SAXException e) {
-        } catch (IOException e) {
-        } catch (CoreException e) {
-        }
-    }
-
-    /**
-     * Adds a resource item to the list
-     * @param resType The type of the resource
-     * @param value The value of the resource.
-     */
-    public void addResourceValue(String resType, ResourceValue value) {
-        ResourceType type = ResourceType.getEnum(resType);
-        if (type != null) {
-            HashMap<String, ResourceValue> list = mResourceItems.get(type);
-
-            // if the list does not exist, create it.
-            if (list == null) {
-                list = new HashMap<String, ResourceValue>();
-                mResourceItems.put(type, list);
-            } else {
-                // look for a possible value already existing.
-                ResourceValue oldValue = list.get(value.getName());
-
-                if (oldValue != null) {
-                    oldValue.replaceWith(value);
-                    return;
-                }
-            }
-
-            // empty list or no match found? add the given resource
-            list.put(value.getName(), value);
-        }
-    }
-
-    @Override
-    public IResourceValue getValue(ResourceType type, String name) {
-        update();
-
-        // get the list for the given type
-        HashMap<String, ResourceValue> list = mResourceItems.get(type);
-
-        if (list != null) {
-            return list.get(name);
-        }
-
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java
deleted file mode 100644
index 3e1259c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-
-/**
- * ClassLoader able to load class from output of an Eclipse project.
- */
-public final class ProjectClassLoader extends ClassLoader {
-
-    private final IJavaProject mJavaProject;
-    private URLClassLoader mJarClassLoader;
-    private boolean mInsideJarClassLoader = false;
-
-    public ProjectClassLoader(ClassLoader parentClassLoader, IProject project) {
-        super(parentClassLoader);
-        mJavaProject = JavaCore.create(project);
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        try {
-            // get the project output folder.
-            IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-            IPath outputLocation = mJavaProject.getOutputLocation();
-            IResource outRes = root.findMember(outputLocation);
-            if (outRes == null) {
-                throw new ClassNotFoundException(name);
-            }
-
-            File outFolder = new File(outRes.getLocation().toOSString());
-
-            // get the class name segments
-            String[] segments = name.split("\\."); //$NON-NLS-1$
-            
-            File classFile = getFile(outFolder, segments, 0);
-            if (classFile == null) {
-                if (mInsideJarClassLoader == false) {
-                    // if no file matching the class name was found, look in the 3rd party jars
-                    return loadClassFromJar(name);
-                } else {
-                    throw new ClassNotFoundException(name);
-                }
-            }
-            
-            // load the content of the file and create the class.
-            FileInputStream fis = new FileInputStream(classFile);
-            byte[] data = new byte[(int)classFile.length()];
-            int read = 0;
-            try {
-                read = fis.read(data);
-            } catch (IOException e) {
-                data = null;
-            }
-            fis.close();
-            
-            if (data != null) {
-                Class<?> clazz = defineClass(null, data, 0, read);
-                if (clazz != null) {
-                    return clazz;
-                }
-            }
-        } catch (Exception e) {
-            throw new ClassNotFoundException(e.getMessage());
-        }
-
-        throw new ClassNotFoundException(name);
-    }
-    
-    /**
-     * Returns the File matching the a certain path from a root {@link File}.
-     * <p/>The methods checks that the file ends in .class even though the last segment
-     * does not.
-     * @param parent the root of the file.
-     * @param segments the segments containing the path of the file
-     * @param index the offset at which to start looking into segments.
-     * @throws FileNotFoundException
-     */
-    private File getFile(File parent, String[] segments, int index)
-            throws FileNotFoundException {
-        // reached the end with no match?
-        if (index == segments.length) {
-            throw new FileNotFoundException();
-        }
-
-        String toMatch = segments[index];
-        File[] files = parent.listFiles();
-
-        // we're at the last segments. we look for a matching <file>.class
-        if (index == segments.length - 1) {
-            toMatch = toMatch + ".class"; 
-
-            if (files != null) {
-                for (File file : files) {
-                    if (file.isFile() && file.getName().equals(toMatch)) {
-                        return file;
-                    }
-                }
-            }
-            
-            // no match? abort.
-            throw new FileNotFoundException();
-        }
-        
-        String innerClassName = null;
-        
-        if (files != null) {
-            for (File file : files) {
-                if (file.isDirectory()) {
-                    if (toMatch.equals(file.getName())) {
-                        return getFile(file, segments, index+1);
-                    }
-                } else if (file.getName().startsWith(toMatch)) {
-                    if (innerClassName == null) {
-                        StringBuilder sb = new StringBuilder(segments[index]);
-                        for (int i = index + 1 ; i < segments.length ; i++) {
-                            sb.append('$');
-                            sb.append(segments[i]);
-                        }
-                        sb.append(".class");
-                        
-                        innerClassName = sb.toString();
-                    }
-                    
-                    if (file.getName().equals(innerClassName)) {
-                        return file;
-                    }
-                }
-            }
-        }
-        
-        return null;
-    }
-    
-    /**
-     * Loads a class from the 3rd party jar present in the project
-     * @throws ClassNotFoundException
-     */
-    private Class<?> loadClassFromJar(String name) throws ClassNotFoundException {
-        if (mJarClassLoader == null) {
-            // get the OS path to all the external jars
-            URL[] jars = getExternalJars();
-            
-            mJarClassLoader = new URLClassLoader(jars, this /* parent */);
-        }
-        
-        try {
-            // because a class loader always look in its parent loader first, we need to know
-            // that we are querying the jar classloader. This will let us know to not query
-            // it again for classes we don't find, or this would create an infinite loop.
-            mInsideJarClassLoader = true;
-            return mJarClassLoader.loadClass(name);
-        } finally {
-            mInsideJarClassLoader = false;
-        }
-    }
-    
-    /**
-     * Returns an array of external jar files used by the project.
-     * @return an array of OS-specific absolute file paths
-     */
-    private final URL[] getExternalJars() {
-        // get a java project from it
-        IJavaProject javaProject = JavaCore.create(mJavaProject.getProject());
-        
-        IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
-
-        ArrayList<URL> oslibraryList = new ArrayList<URL>();
-        IClasspathEntry[] classpaths = javaProject.readRawClasspath();
-        if (classpaths != null) {
-            for (IClasspathEntry e : classpaths) {
-                if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY ||
-                        e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
-                    // if this is a classpath variable reference, we resolve it.
-                    if (e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
-                        e = JavaCore.getResolvedClasspathEntry(e); 
-                    }
-
-                    // get the IPath
-                    IPath path = e.getPath();
-
-                    // check the name ends with .jar
-                    if (AndroidConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
-                        boolean local = false;
-                        IResource resource = wsRoot.findMember(path);
-                        if (resource != null && resource.exists() &&
-                                resource.getType() == IResource.FILE) {
-                            local = true;
-                            try {
-                                oslibraryList.add(
-                                        new File(resource.getLocation().toOSString()).toURL());
-                            } catch (MalformedURLException mue) {
-                                // pass
-                            }
-                        }
-
-                        if (local == false) {
-                            // if the jar path doesn't match a workspace resource,
-                            // then we get an OSString and check if this links to a valid file.
-                            String osFullPath = path.toOSString();
-
-                            File f = new File(osFullPath);
-                            if (f.exists()) {
-                                try {
-                                    oslibraryList.add(f.toURL());
-                                } catch (MalformedURLException mue) {
-                                    // pass
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return oslibraryList.toArray(new URL[oslibraryList.size()]);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResourceItem.java
deleted file mode 100644
index 7c382d5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResourceItem.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Base class for Resource Item coming from an Android Project.
- */
-public abstract class ProjectResourceItem extends ResourceItem {
-
-    private final static Comparator<ResourceFile> sComparator = new Comparator<ResourceFile>() {
-        public int compare(ResourceFile file1, ResourceFile file2) {
-            // get both FolderConfiguration and compare them
-            FolderConfiguration fc1 = file1.getFolder().getConfiguration();
-            FolderConfiguration fc2 = file2.getFolder().getConfiguration();
-            
-            return fc1.compareTo(fc2);
-        }
-    };
-
-    /**
-     * List of files generating this ResourceItem.
-     */
-    protected final ArrayList<ResourceFile> mFiles = new ArrayList<ResourceFile>();
-
-    /**
-     * Constructs a new ResourceItem.
-     * @param name the name of the resource as it appears in the XML and R.java files.
-     */
-    public ProjectResourceItem(String name) {
-        super(name);
-    }
-    
-    /**
-     * Returns whether the resource item is editable directly.
-     * <p/>
-     * This is typically the case for resources that don't have alternate versions, or resources
-     * of type {@link ResourceType#ID} that aren't declared inline.
-     */
-    public abstract boolean isEditableDirectly();
-
-    /**
-     * Adds a new version of this resource item, by adding its {@link ResourceFile}.
-     * @param file the {@link ResourceFile} object.
-     */
-    protected void add(ResourceFile file) {
-        mFiles.add(file);
-    }
-    
-    /**
-     * Reset the item by emptying its version list.
-     */
-    protected void reset() {
-        mFiles.clear();
-    }
-    
-    /**
-     * Returns the sorted list of {@link ResourceItem} objects for this resource item.
-     */
-    public ResourceFile[] getSourceFileArray() {
-        ArrayList<ResourceFile> list = new ArrayList<ResourceFile>();
-        list.addAll(mFiles);
-        
-        Collections.sort(list, sComparator);
-        
-        return list.toArray(new ResourceFile[list.size()]);
-    }
-    
-    /**
-     * Returns the list of {@link ResourceItem} objects for this resource item.
-     */
-    public List<ResourceFile> getSourceFileList() {
-        return Collections.unmodifiableList(mFiles);
-    }
-    
-
-    /**
-     * Replaces the content of the receiver with the ResourceItem received as parameter.
-     * @param item
-     */
-    protected void replaceWith(ProjectResourceItem item) {
-        mFiles.clear();
-        mFiles.addAll(item.mFiles);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java
deleted file mode 100644
index dce2622..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFolder;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.utils.ResourceValue;
-
-import org.eclipse.core.resources.IFolder;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * Represents the resources of a project. This is a file view of the resources, with handling
- * for the alternate resource types. For a compiled view use CompiledResources.
- */
-public class ProjectResources implements IResourceRepository {
-    private final HashMap<ResourceFolderType, List<ResourceFolder>> mFolderMap =
-        new HashMap<ResourceFolderType, List<ResourceFolder>>();
-
-    private final HashMap<ResourceType, List<ProjectResourceItem>> mResourceMap =
-        new HashMap<ResourceType, List<ProjectResourceItem>>();
-
-    /** Map of (name, id) for resources of type {@link ResourceType#ID} coming from R.java */
-    private Map<String, Map<String, Integer>> mResourceValueMap;
-    /** Map of (id, [name, resType]) for all resources coming from R.java */
-    private Map<Integer, String[]> mResIdValueToNameMap;
-    /** Map of (int[], name) for styleable resources coming from R.java */
-    private Map<IntArrayWrapper, String> mStyleableValueToNameMap;
-
-    /** Cached list of {@link IdResourceItem}. This is mix of IdResourceItem created by
-     * {@link MultiResourceFile} for ids coming from XML files under res/values and
-     * {@link IdResourceItem} created manually, from the list coming from R.java */
-    private final ArrayList<IdResourceItem> mIdResourceList = new ArrayList<IdResourceItem>();
-
-    private final boolean mIsFrameworkRepository;
-
-    private final IntArrayWrapper mWrapper = new IntArrayWrapper(null);
-
-    public ProjectResources(boolean isFrameworkRepository) {
-        mIsFrameworkRepository = isFrameworkRepository;
-    }
-
-    public boolean isSystemRepository() {
-        return mIsFrameworkRepository;
-    }
-
-    /**
-     * Adds a Folder Configuration to the project.
-     * @param type The resource type.
-     * @param config The resource configuration.
-     * @param folder The workspace folder object.
-     * @return the {@link ResourceFolder} object associated to this folder.
-     */
-    protected ResourceFolder add(ResourceFolderType type, FolderConfiguration config,
-            IAbstractFolder folder) {
-        // get the list for the resource type
-        List<ResourceFolder> list = mFolderMap.get(type);
-
-        if (list == null) {
-            list = new ArrayList<ResourceFolder>();
-
-            ResourceFolder cf = new ResourceFolder(type, config, folder, mIsFrameworkRepository);
-            list.add(cf);
-
-            mFolderMap.put(type, list);
-
-            return cf;
-        }
-
-        // look for an already existing folder configuration.
-        for (ResourceFolder cFolder : list) {
-            if (cFolder.mConfiguration.equals(config)) {
-                // config already exist. Nothing to be done really, besides making sure
-                // the IFolder object is up to date.
-                cFolder.mFolder = folder;
-                return cFolder;
-            }
-        }
-
-        // If we arrive here, this means we didn't find a matching configuration.
-        // So we add one.
-        ResourceFolder cf = new ResourceFolder(type, config, folder, mIsFrameworkRepository);
-        list.add(cf);
-
-        return cf;
-    }
-
-    /**
-     * Removes a {@link ResourceFolder} associated with the specified {@link IAbstractFolder}.
-     * @param type The type of the folder
-     * @param folder the IFolder object.
-     */
-    protected void removeFolder(ResourceFolderType type, IFolder folder) {
-        // get the list of folders for the resource type.
-        List<ResourceFolder> list = mFolderMap.get(type);
-
-        if (list != null) {
-            int count = list.size();
-            for (int i = 0 ; i < count ; i++) {
-                ResourceFolder resFolder = list.get(i);
-                if (resFolder.getFolder().getIFolder().equals(folder)) {
-                    // we found the matching ResourceFolder. we need to remove it.
-                    list.remove(i);
-
-                    // we now need to invalidate this resource type.
-                    // The easiest way is to touch one of the other folders of the same type.
-                    if (list.size() > 0) {
-                        list.get(0).touch();
-                    } else {
-                        // if the list is now empty, and we have a single ResouceType out of this
-                        // ResourceFolderType, then we are done.
-                        // However, if another ResourceFolderType can generate similar ResourceType
-                        // than this, we need to update those ResourceTypes as well.
-                        // For instance, if the last "drawable-*" folder is deleted, we need to
-                        // refresh the ResourceItem associated with ResourceType.DRAWABLE.
-                        // Those can be found in ResourceFolderType.DRAWABLE but also in
-                        // ResourceFolderType.VALUES.
-                        // If we don't find a single folder to touch, then it's fine, as the top
-                        // level items (the list of generated resource types) is not cached
-                        // (for now)
-
-                        // get the lists of ResourceTypes generated by this ResourceFolderType
-                        ResourceType[] resTypes = FolderTypeRelationship.getRelatedResourceTypes(
-                                type);
-
-                        // for each of those, make sure to find one folder to touch so that the
-                        // list of ResourceItem associated with the type is rebuilt.
-                        for (ResourceType resType : resTypes) {
-                            // get the list of folder that can generate this type
-                            ResourceFolderType[] folderTypes =
-                                FolderTypeRelationship.getRelatedFolders(resType);
-
-                            // we only need to touch one folder in any of those (since it's one
-                            // folder per type, not per folder type).
-                            for (ResourceFolderType folderType : folderTypes) {
-                                List<ResourceFolder> resFolders = mFolderMap.get(folderType);
-
-                                if (resFolders != null && resFolders.size() > 0) {
-                                    resFolders.get(0).touch();
-                                    break;
-                                }
-                            }
-                        }
-                    }
-
-                    // we're done updating/touching, we can stop
-                    break;
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Returns a list of {@link ResourceFolder} for a specific {@link ResourceFolderType}.
-     * @param type The {@link ResourceFolderType}
-     */
-    public List<ResourceFolder> getFolders(ResourceFolderType type) {
-        return mFolderMap.get(type);
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.IResourceRepository#getAvailableResourceTypes()
-     */
-    public ResourceType[] getAvailableResourceTypes() {
-        ArrayList<ResourceType> list = new ArrayList<ResourceType>();
-
-        // For each key, we check if there's a single ResourceType match.
-        // If not, we look for the actual content to give us the resource type.
-
-        for (ResourceFolderType folderType : mFolderMap.keySet()) {
-            ResourceType types[] = FolderTypeRelationship.getRelatedResourceTypes(folderType);
-            if (types.length == 1) {
-                // before we add it we check if it's not already present, since a ResourceType
-                // could be created from multiple folders, even for the folders that only create
-                // one type of resource (drawable for instance, can be created from drawable/ and
-                // values/)
-                if (list.indexOf(types[0]) == -1) {
-                    list.add(types[0]);
-                }
-            } else {
-                // there isn't a single resource type out of this folder, so we look for all
-                // content.
-                List<ResourceFolder> folders = mFolderMap.get(folderType);
-                if (folders != null) {
-                    for (ResourceFolder folder : folders) {
-                        Collection<ResourceType> folderContent = folder.getResourceTypes();
-
-                        // then we add them, but only if they aren't already in the list.
-                        for (ResourceType folderResType : folderContent) {
-                            if (list.indexOf(folderResType) == -1) {
-                                list.add(folderResType);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // in case ResourceType.ID haven't been added yet because there's no id defined
-        // in XML, we check on the list of compiled id resources.
-        if (list.indexOf(ResourceType.ID) == -1 && mResourceValueMap != null) {
-            Map<String, Integer> map = mResourceValueMap.get(ResourceType.ID.getName());
-            if (map != null && map.size() > 0) {
-                list.add(ResourceType.ID);
-            }
-        }
-
-        // at this point the list is full of ResourceType defined in the files.
-        // We need to sort it.
-        Collections.sort(list);
-
-        return list.toArray(new ResourceType[list.size()]);
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.IResourceRepository#getResources(com.android.ide.eclipse.common.resources.ResourceType)
-     */
-    public ProjectResourceItem[] getResources(ResourceType type) {
-        checkAndUpdate(type);
-
-        if (type == ResourceType.ID) {
-            synchronized (mIdResourceList) {
-                return mIdResourceList.toArray(new ProjectResourceItem[mIdResourceList.size()]);
-            }
-        }
-
-        List<ProjectResourceItem> items = mResourceMap.get(type);
-
-        return items.toArray(new ProjectResourceItem[items.size()]);
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.IResourceRepository#hasResources(com.android.ide.eclipse.common.resources.ResourceType)
-     */
-    public boolean hasResources(ResourceType type) {
-        checkAndUpdate(type);
-
-        if (type == ResourceType.ID) {
-            synchronized (mIdResourceList) {
-                return mIdResourceList.size() > 0;
-            }
-        }
-
-        List<ProjectResourceItem> items = mResourceMap.get(type);
-        return (items != null && items.size() > 0);
-    }
-
-    /**
-     * Returns the {@link ResourceFolder} associated with a {@link IFolder}.
-     * @param folder The {@link IFolder} object.
-     * @return the {@link ResourceFolder} or null if it was not found.
-     */
-    public ResourceFolder getResourceFolder(IFolder folder) {
-        for (List<ResourceFolder> list : mFolderMap.values()) {
-            for (ResourceFolder resFolder : list) {
-                if (resFolder.getFolder().getIFolder().equals(folder)) {
-                    return resFolder;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the {@link ResourceFile} matching the given name, {@link ResourceFolderType} and
-     * configuration.
-     * <p/>This only works with files generating one resource named after the file (for instance,
-     * layouts, bitmap based drawable, xml, anims).
-     * @return the matching file or <code>null</code> if no match was found.
-     */
-    public ResourceFile getMatchingFile(String name, ResourceFolderType type,
-            FolderConfiguration config) {
-        // get the folders for the given type
-        List<ResourceFolder> folders = mFolderMap.get(type);
-
-        // look for folders containing a file with the given name.
-        ArrayList<ResourceFolder> matchingFolders = new ArrayList<ResourceFolder>();
-
-        // remove the folders that do not have a file with the given name, or if their config
-        // is incompatible.
-        for (int i = 0 ; i < folders.size(); i++) {
-            ResourceFolder folder = folders.get(i);
-
-            if (folder.hasFile(name) == true) {
-                matchingFolders.add(folder);
-            }
-        }
-
-        // from those, get the folder with a config matching the given reference configuration.
-        Resource match = findMatchingConfiguredResource(matchingFolders, config);
-
-        // do we have a matching folder?
-        if (match instanceof ResourceFolder) {
-            // get the ResourceFile from the filename
-            return ((ResourceFolder)match).getFile(name);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the resources values matching a given {@link FolderConfiguration}.
-     * @param referenceConfig the configuration that each value must match.
-     */
-    public Map<String, Map<String, IResourceValue>> getConfiguredResources(
-            FolderConfiguration referenceConfig) {
-
-        Map<String, Map<String, IResourceValue>> map =
-            new HashMap<String, Map<String, IResourceValue>>();
-
-        // special case for Id since there's a mix of compiled id (declared inline) and id declared
-        // in the XML files.
-        if (mIdResourceList.size() > 0) {
-            Map<String, IResourceValue> idMap = new HashMap<String, IResourceValue>();
-            String idType = ResourceType.ID.getName();
-            for (IdResourceItem id : mIdResourceList) {
-                // FIXME: cache the ResourceValue!
-                idMap.put(id.getName(), new ResourceValue(idType, id.getName(),
-                        mIsFrameworkRepository));
-            }
-
-            map.put(ResourceType.ID.getName(), idMap);
-        }
-
-        Set<ResourceType> keys = mResourceMap.keySet();
-        for (ResourceType key : keys) {
-            // we don't process ID resources since we already did it above.
-            if (key != ResourceType.ID) {
-                map.put(key.getName(), getConfiguredResource(key, referenceConfig));
-            }
-        }
-
-        return map;
-    }
-
-    /**
-     * Loads all the resources. Essentially this forces to load the values from the
-     * {@link ResourceFile} objects to make sure they are up to date and loaded
-     * in {@link #mResourceMap}.
-     */
-    public void loadAll() {
-        // gets all the resource types available.
-        ResourceType[] types = getAvailableResourceTypes();
-
-        // loop on them and load them
-        for (ResourceType type: types) {
-            checkAndUpdate(type);
-        }
-    }
-
-    /**
-     * Resolves a compiled resource id into the resource name and type
-     * @param id
-     * @return an array of 2 strings { name, type } or null if the id could not be resolved
-     */
-    public String[] resolveResourceValue(int id) {
-        if (mResIdValueToNameMap != null) {
-            return mResIdValueToNameMap.get(id);
-        }
-
-        return null;
-    }
-
-    /**
-     * Resolves a compiled resource id of type int[] into the resource name.
-     */
-    public String resolveResourceValue(int[] id) {
-        if (mStyleableValueToNameMap != null) {
-            mWrapper.set(id);
-            return mStyleableValueToNameMap.get(mWrapper);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the value of a resource by its type and name.
-     */
-    public Integer getResourceValue(String type, String name) {
-        if (mResourceValueMap != null) {
-            Map<String, Integer> map = mResourceValueMap.get(type);
-            if (map != null) {
-                return map.get(name);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the sorted list of languages used in the resources.
-     */
-    public SortedSet<String> getLanguages() {
-        SortedSet<String> set = new TreeSet<String>();
-
-        Collection<List<ResourceFolder>> folderList = mFolderMap.values();
-        for (List<ResourceFolder> folderSubList : folderList) {
-            for (ResourceFolder folder : folderSubList) {
-                FolderConfiguration config = folder.getConfiguration();
-                LanguageQualifier lang = config.getLanguageQualifier();
-                if (lang != null) {
-                    set.add(lang.getStringValue());
-                }
-            }
-        }
-
-        return set;
-    }
-
-    /**
-     * Returns the sorted list of regions used in the resources with the given language.
-     * @param currentLanguage the current language the region must be associated with.
-     */
-    public SortedSet<String> getRegions(String currentLanguage) {
-        SortedSet<String> set = new TreeSet<String>();
-
-        Collection<List<ResourceFolder>> folderList = mFolderMap.values();
-        for (List<ResourceFolder> folderSubList : folderList) {
-            for (ResourceFolder folder : folderSubList) {
-                FolderConfiguration config = folder.getConfiguration();
-
-                // get the language
-                LanguageQualifier lang = config.getLanguageQualifier();
-                if (lang != null && lang.getStringValue().equals(currentLanguage)) {
-                    RegionQualifier region = config.getRegionQualifier();
-                    if (region != null) {
-                        set.add(region.getStringValue());
-                    }
-                }
-            }
-        }
-
-        return set;
-    }
-
-    /**
-     * Returns a map of (resource name, resource value) for the given {@link ResourceType}.
-     * <p/>The values returned are taken from the resource files best matching a given
-     * {@link FolderConfiguration}.
-     * @param type the type of the resources.
-     * @param referenceConfig the configuration to best match.
-     */
-    private Map<String, IResourceValue> getConfiguredResource(ResourceType type,
-            FolderConfiguration referenceConfig) {
-        // get the resource item for the given type
-        List<ProjectResourceItem> items = mResourceMap.get(type);
-
-        // create the map
-        HashMap<String, IResourceValue> map = new HashMap<String, IResourceValue>();
-
-        for (ProjectResourceItem item : items) {
-            // get the source files generating this resource
-            List<ResourceFile> list = item.getSourceFileList();
-
-            // look for the best match for the given configuration
-            Resource match = findMatchingConfiguredResource(list, referenceConfig);
-
-            if (match instanceof ResourceFile) {
-                ResourceFile matchResFile = (ResourceFile)match;
-
-                // get the value of this configured resource.
-                IResourceValue value = matchResFile.getValue(type, item.getName());
-
-                if (value != null) {
-                    map.put(item.getName(), value);
-                }
-            }
-        }
-
-        return map;
-    }
-
-    /**
-     * Returns the best matching {@link Resource}.
-     * @param resources the list of {@link Resource} to choose from.
-     * @param referenceConfig the {@link FolderConfiguration} to match.
-     * @see http://d.android.com/guide/topics/resources/resources-i18n.html#best-match
-     */
-    private Resource findMatchingConfiguredResource(List<? extends Resource> resources,
-            FolderConfiguration referenceConfig) {
-        //
-        // 1: eliminate resources that contradict the reference configuration
-        // 2: pick next qualifier type
-        // 3: check if any resources use this qualifier, if no, back to 2, else move on to 4.
-        // 4: eliminate resources that don't use this qualifier.
-        // 5: if more than one resource left, go back to 2.
-        //
-        // The precedence of the qualifiers is more important than the number of qualifiers that
-        // exactly match the device.
-
-        // 1: eliminate resources that contradict
-        ArrayList<Resource> matchingResources = new ArrayList<Resource>();
-        for (int i = 0 ; i < resources.size(); i++) {
-            Resource res = resources.get(i);
-
-            if (res.getConfiguration().isMatchFor(referenceConfig)) {
-                matchingResources.add(res);
-            }
-        }
-
-        // if there is only one match, just take it
-        if (matchingResources.size() == 1) {
-            return matchingResources.get(0);
-        } else if (matchingResources.size() == 0) {
-            return null;
-        }
-
-        // 2. Loop on the qualifiers, and eliminate matches
-        final int count = FolderConfiguration.getQualifierCount();
-        for (int q = 0 ; q < count ; q++) {
-            // look to see if one resource has this qualifier.
-            // At the same time also record the best match value for the qualifier (if applicable).
-
-            // The reference value, to find the best match.
-            // Note that this qualifier could be null. In which case any qualifier found in the
-            // possible match, will all be considered best match.
-            ResourceQualifier referenceQualifier = referenceConfig.getQualifier(q);
-
-            boolean found = false;
-            ResourceQualifier bestMatch = null; // this is to store the best match.
-            for (Resource res : matchingResources) {
-                ResourceQualifier qualifier = res.getConfiguration().getQualifier(q);
-                if (qualifier != null) {
-                    // set the flag.
-                    found = true;
-
-                    // Now check for a best match. If the reference qualifier is null ,
-                    // any qualifier is a "best" match (we don't need to record all of them.
-                    // Instead the non compatible ones are removed below)
-                    if (referenceQualifier != null) {
-                        if (qualifier.isBetterMatchThan(bestMatch, referenceQualifier)) {
-                            bestMatch = qualifier;
-                        }
-                    }
-                }
-            }
-
-            // 4. If a resources has a qualifier at the current index, remove all the resources that
-            // do not have one, or whose qualifier value does not equal the best match found above
-            // unless there's no reference qualifier, in which case they are all considered
-            // "best" match.
-            if (found) {
-                for (int i = 0 ; i < matchingResources.size(); ) {
-                    Resource res = matchingResources.get(i);
-                    ResourceQualifier qualifier = res.getConfiguration().getQualifier(q);
-
-                    if (qualifier == null) {
-                        // this resources has no qualifier of this type: rejected.
-                        matchingResources.remove(res);
-                    } else if (referenceQualifier != null && bestMatch != null &&
-                            bestMatch.equals(qualifier) == false) {
-                        // there's a reference qualifier and there is a better match for it than
-                        // this resource, so we reject it.
-                        matchingResources.remove(res);
-                    } else {
-                        // looks like we keep this resource, move on to the next one.
-                        i++;
-                    }
-                }
-
-                // at this point we may have run out of matching resources before going
-                // through all the qualifiers.
-                if (matchingResources.size() < 2) {
-                    break;
-                }
-            }
-        }
-
-        // Because we accept resources whose configuration have qualifiers where the reference 
-        // configuration doesn't, we can end up with more than one match. In this case, we just
-        // take the first one.
-        if (matchingResources.size() == 0) {
-            return null;
-        }
-        return matchingResources.get(0);
-    }
-
-    /**
-     * Checks if the list of {@link ResourceItem}s for the specified {@link ResourceType} needs
-     * to be updated.
-     * @param type the Resource Type.
-     */
-    private void checkAndUpdate(ResourceType type) {
-        // get the list of folder that can output this type
-        ResourceFolderType[] folderTypes = FolderTypeRelationship.getRelatedFolders(type);
-
-        for (ResourceFolderType folderType : folderTypes) {
-            List<ResourceFolder> folders = mFolderMap.get(folderType);
-
-            if (folders != null) {
-                for (ResourceFolder folder : folders) {
-                    if (folder.isTouched()) {
-                        // if this folder is touched we need to update all the types that can
-                        // be generated from a file in this folder.
-                        // This will include 'type' obviously.
-                        ResourceType[] resTypes = FolderTypeRelationship.getRelatedResourceTypes(
-                                folderType);
-                        for (ResourceType resType : resTypes) {
-                            update(resType);
-                        }
-                        return;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Updates the list of {@link ResourceItem} objects associated with a {@link ResourceType}.
-     * This will reset the touch status of all the folders that can generate this resource type.
-     * @param type the Resource Type.
-     */
-    private void update(ResourceType type) {
-        // get the cache list, and lets make a backup
-        List<ProjectResourceItem> items = mResourceMap.get(type);
-        List<ProjectResourceItem> backup = new ArrayList<ProjectResourceItem>();
-
-        if (items == null) {
-            items = new ArrayList<ProjectResourceItem>();
-            mResourceMap.put(type, items);
-        } else {
-            // backup the list
-            backup.addAll(items);
-
-            // we reset the list itself.
-            items.clear();
-        }
-
-        // get the list of folder that can output this type
-        ResourceFolderType[] folderTypes = FolderTypeRelationship.getRelatedFolders(type);
-
-        for (ResourceFolderType folderType : folderTypes) {
-            List<ResourceFolder> folders = mFolderMap.get(folderType);
-
-            if (folders != null) {
-                for (ResourceFolder folder : folders) {
-                    items.addAll(folder.getResources(type, this));
-                    folder.resetTouch();
-                }
-            }
-        }
-
-        // now items contains the new list. We "merge" it with the backup list.
-        // Basically, we need to keep the old instances of ResourceItem (where applicable),
-        // but replace them by the content of the new items.
-        // This will let the resource explorer keep the expanded state of the nodes whose data
-        // is a ResourceItem object.
-        if (backup.size() > 0) {
-            // this is not going to change as we're only replacing instances.
-            int count = items.size();
-
-            for (int i = 0 ; i < count;) {
-                // get the "new" item
-                ProjectResourceItem item = items.get(i);
-
-                // look for a similar item in the old list.
-                ProjectResourceItem foundOldItem = null;
-                for (ProjectResourceItem oldItem : backup) {
-                    if (oldItem.getName().equals(item.getName())) {
-                        foundOldItem = oldItem;
-                        break;
-                    }
-                }
-
-                if (foundOldItem != null) {
-                    // erase the data of the old item with the data from the new one.
-                    foundOldItem.replaceWith(item);
-
-                    // remove the old and new item from their respective lists
-                    items.remove(i);
-                    backup.remove(foundOldItem);
-
-                    // add the old item to the new list
-                    items.add(foundOldItem);
-                } else {
-                    // this is a new item, we skip to the next object
-                    i++;
-                }
-            }
-        }
-
-        // if this is the ResourceType.ID, we create the actual list, from this list and
-        // the compiled resource list.
-        if (type == ResourceType.ID) {
-            mergeIdResources();
-        } else {
-            // else this is the list that will actually be displayed, so we sort it.
-            Collections.sort(items);
-        }
-    }
-
-    /**
-     * Looks up an existing {@link ProjectResourceItem} by {@link ResourceType} and name.
-     * @param type the Resource Type.
-     * @param name the Resource name.
-     * @return the existing ResourceItem or null if no match was found.
-     */
-    protected ProjectResourceItem findResourceItem(ResourceType type, String name) {
-        List<ProjectResourceItem> list = mResourceMap.get(type);
-
-        for (ProjectResourceItem item : list) {
-            if (name.equals(item.getName())) {
-                return item;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets compiled resource information.
-     * @param resIdValueToNameMap a map of compiled resource id to resource name.
-     *  The map is acquired by the {@link ProjectResources} object.
-     * @param styleableValueMap
-     * @param resourceValueMap a map of (name, id) for resources of type {@link ResourceType#ID}.
-     * The list is acquired by the {@link ProjectResources} object.
-     */
-    void setCompiledResources(Map<Integer, String[]> resIdValueToNameMap,
-            Map<IntArrayWrapper, String> styleableValueMap,
-            Map<String, Map<String, Integer>> resourceValueMap) {
-        mResourceValueMap = resourceValueMap;
-        mResIdValueToNameMap = resIdValueToNameMap;
-        mStyleableValueToNameMap = styleableValueMap;
-        mergeIdResources();
-    }
-
-    /**
-     * Merges the list of ID resource coming from R.java and the list of ID resources
-     * coming from XML declaration into the cached list {@link #mIdResourceList}.
-     */
-    void mergeIdResources() {
-        // get the list of IDs coming from XML declaration. Those ids are present in
-        // mCompiledIdResources already, so we'll need to use those instead of creating
-        // new IdResourceItem
-        List<ProjectResourceItem> xmlIdResources = mResourceMap.get(ResourceType.ID);
-
-        synchronized (mIdResourceList) {
-            // copy the currently cached items.
-            ArrayList<IdResourceItem> oldItems = new ArrayList<IdResourceItem>();
-            oldItems.addAll(mIdResourceList);
-
-            // empty the current list
-            mIdResourceList.clear();
-
-            // get the list of compile id resources.
-            Map<String, Integer> idMap = null;
-            if (mResourceValueMap != null) {
-                idMap = mResourceValueMap.get(ResourceType.ID.getName());
-            }
-
-            if (idMap == null) {
-                if (xmlIdResources != null) {
-                    for (ProjectResourceItem resourceItem : xmlIdResources) {
-                        // check the actual class just for safety.
-                        if (resourceItem instanceof IdResourceItem) {
-                            mIdResourceList.add((IdResourceItem)resourceItem);
-                        }
-                    }
-                }
-            } else {
-                // loop on the full list of id, and look for a match in the old list,
-                // in the list coming from XML (in case a new XML item was created.)
-
-                Set<String> idSet = idMap.keySet();
-
-                idLoop: for (String idResource : idSet) {
-                    // first look in the XML list in case an id went from inline to XML declared.
-                    if (xmlIdResources != null) {
-                        for (ProjectResourceItem resourceItem : xmlIdResources) {
-                            if (resourceItem instanceof IdResourceItem &&
-                                    resourceItem.getName().equals(idResource)) {
-                                mIdResourceList.add((IdResourceItem)resourceItem);
-                                continue idLoop;
-                            }
-                        }
-                    }
-
-                    // if we haven't found it, look in the old items.
-                    int count = oldItems.size();
-                    for (int i = 0 ; i < count ; i++) {
-                        IdResourceItem resourceItem = oldItems.get(i);
-                        if (resourceItem.getName().equals(idResource)) {
-                            oldItems.remove(i);
-                            mIdResourceList.add(resourceItem);
-                            continue idLoop;
-                        }
-                    }
-
-                    // if we haven't found it, it looks like it's a new id that was
-                    // declared inline.
-                    mIdResourceList.add(new IdResourceItem(idResource,
-                            true /* isDeclaredInline */));
-                }
-            }
-
-            // now we sort the list
-            Collections.sort(mIdResourceList);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/Resource.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/Resource.java
deleted file mode 100644
index fd9005b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/Resource.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-
-/**
- * Base class for file system resource items (Folders, Files).
- */
-public abstract class Resource {
-    private boolean mTouched = true;
-    
-    /**
-     * Returns the {@link FolderConfiguration} for this object.
-     */
-    public abstract FolderConfiguration getConfiguration();
-
-    /**
-     * Indicates that the underlying file was changed.
-     */
-    public final void touch() {
-       mTouched = true; 
-    }
-    
-    public final boolean isTouched() {
-        return mTouched;
-    }
-    
-    public final void resetTouch() {
-        mTouched = false;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFile.java
deleted file mode 100644
index f7fb93f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFile.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFile;
-import com.android.layoutlib.api.IResourceValue;
-
-import java.util.Collection;
-
-/**
- * Represents a Resource file (a file under $Project/res/)
- */
-public abstract class ResourceFile extends Resource {
-    
-    private final IAbstractFile mFile;
-    private final ResourceFolder mFolder;
-    
-    protected ResourceFile(IAbstractFile file, ResourceFolder folder) {
-        mFile = file;
-        mFolder = folder;
-    }
-    
-    /*
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.Resource#getConfiguration()
-     */
-    @Override
-    public FolderConfiguration getConfiguration() {
-        return mFolder.getConfiguration();
-    }
-    
-    /**
-     * Returns the IFile associated with the ResourceFile.
-     */
-    public final IAbstractFile getFile() {
-        return mFile;
-    }
-    
-    /**
-     * Returns the parent folder as a {@link ResourceFolder}.
-     */
-    public final ResourceFolder getFolder() {
-        return mFolder;
-    }
-    
-    /**
-     * Returns whether the resource is a framework resource.
-     */
-    public final boolean isFramework() {
-        return mFolder.isFramework();
-    }
-
-    /**
-     * Returns the list of {@link ResourceType} generated by the file.
-     */
-    public abstract ResourceType[] getResourceTypes();
-
-    /**
-     * Returns whether the file generated a resource of a specific type.
-     * @param type The {@link ResourceType}
-     */
-    public abstract boolean hasResources(ResourceType type);
-
-    /**
-     * Get the list of {@link ProjectResourceItem} of a specific type generated by the file.
-     * This method must make sure not to create duplicate.
-     * @param type The type of {@link ProjectResourceItem} to return.
-     * @param projectResources The global Project Resource object, allowing the implementation to
-     * query for already existing {@link ProjectResourceItem}
-     * @return The list of <b>new</b> {@link ProjectResourceItem}
-     * @see ProjectResources#findResourceItem(ResourceType, String)
-     */
-    public abstract Collection<ProjectResourceItem> getResources(ResourceType type,
-            ProjectResources projectResources);
-    
-    /**
-     * Returns the value of a resource generated by this file by {@link ResourceType} and name.
-     * <p/>If no resource match, <code>null</code> is returned. 
-     * @param type the type of the resource.
-     * @param name the name of the resource.
-     */
-    public abstract IResourceValue getValue(ResourceType type, String name);
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java
deleted file mode 100644
index 95a2d90..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFile;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFolder;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Resource Folder class. Contains list of {@link ResourceFile}s,
- * the {@link FolderConfiguration}, and a link to the workspace {@link IFolder} object.
- */
-public final class ResourceFolder extends Resource {
-    ResourceFolderType mType;
-    FolderConfiguration mConfiguration;
-    IAbstractFolder mFolder;
-    ArrayList<ResourceFile> mFiles = null;
-    private final boolean mIsFramework;
-    
-    /**
-     * Creates a new {@link ResourceFolder}
-     * @param type The type of the folder
-     * @param config The configuration of the folder
-     * @param folder The associated {@link IAbstractFolder} object.
-     * @param isFrameworkRepository 
-     */
-    public ResourceFolder(ResourceFolderType type, FolderConfiguration config,
-            IAbstractFolder folder, boolean isFrameworkRepository) {
-        mType = type;
-        mConfiguration = config;
-        mFolder = folder;
-        mIsFramework = isFrameworkRepository;
-    }
-    
-    /**
-     * Adds a {@link ResourceFile} to the folder.
-     * @param file The {@link ResourceFile}.
-     */
-    public void addFile(ResourceFile file) {
-        if (mFiles == null) {
-            mFiles = new ArrayList<ResourceFile>();
-        }
-
-        mFiles.add(file);
-    }
-    
-    /**
-     * Attempts to remove the {@link ResourceFile} associated with a specified {@link IFile}.
-     * @param file the IFile object.
-     */
-    public void removeFile(IFile file) {
-        if (mFiles != null) {
-            int count = mFiles.size();
-            for (int i = 0 ; i < count ; i++) {
-                ResourceFile resFile = mFiles.get(i);
-                if (resFile != null) {
-                    IFile iFile = resFile.getFile().getIFile();
-                    if (iFile != null && iFile.equals(file)) {
-                        mFiles.remove(i);
-                        touch();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the {@link IFolder} associated with this object.
-     */
-    public IAbstractFolder getFolder() {
-        return mFolder;
-    }
-
-    /**
-     * Returns the {@link ResourceFolderType} of this object.
-     */
-    public ResourceFolderType getType() {
-        return mType;
-    }
-    
-    /**
-     * Returns whether the folder is a framework resource folder.
-     */
-    public boolean isFramework() {
-        return mIsFramework;
-    }
-    
-    /**
-     * Returns the list of {@link ResourceType}s generated by the files inside this folder.
-     */
-    public Collection<ResourceType> getResourceTypes() {
-        ArrayList<ResourceType> list = new ArrayList<ResourceType>();
-
-        if (mFiles != null) {
-            for (ResourceFile file : mFiles) {
-                ResourceType[] types = file.getResourceTypes();
-                
-                // loop through those and add them to the main list,
-                // if they are not already present
-                if (types != null) {
-                    for (ResourceType resType : types) {
-                        if (list.indexOf(resType) == -1) {
-                            list.add(resType);
-                        }
-                    }
-                }
-            }
-        }
-        
-        return list;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.Resource#getConfiguration()
-     */
-    @Override
-    public FolderConfiguration getConfiguration() {
-        return mConfiguration;
-    }
-    
-    /**
-     * Returns whether the folder contains a file with the given name.
-     * @param name the name of the file.
-     */
-    public boolean hasFile(String name) {
-        return mFolder.hasFile(name);
-    }
-
-    /**
-     * Returns the {@link ResourceFile} matching a {@link IAbstractFile} object.
-     * @param file The {@link IFile} object.
-     * @return the {@link ResourceFile} or null if no match was found.
-     */
-    public ResourceFile getFile(IAbstractFile file) {
-        if (mFiles != null) {
-            for (ResourceFile f : mFiles) {
-                if (f.getFile().equals(file)) {
-                    return f;
-                }
-            }
-        }
-        return null;
-    }
-    
-    /**
-     * Returns the {@link ResourceFile} matching a {@link IFile} object.
-     * @param file The {@link IFile} object.
-     * @return the {@link ResourceFile} or null if no match was found.
-     */
-    public ResourceFile getFile(IFile file) {
-        if (mFiles != null) {
-            for (ResourceFile f : mFiles) {
-                IFile iFile = f.getFile().getIFile();
-                if (iFile != null && iFile.equals(file)) {
-                    return f;
-                }
-            }
-        }
-        return null;
-    }
-
-    
-    /**
-     * Returns the {@link ResourceFile} matching a given name.
-     * @param filename The name of the file to return.
-     * @return the {@link ResourceFile} or <code>null</code> if no match was found.
-     */
-    public ResourceFile getFile(String filename) {
-        if (mFiles != null) {
-            for (ResourceFile f : mFiles) {
-                if (f.getFile().getName().equals(filename)) {
-                    return f;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns whether a file in the folder is generating a resource of a specified type.
-     * @param type The {@link ResourceType} being looked up.
-     */
-    public boolean hasResources(ResourceType type) {
-        // Check if the folder type is able to generate resource of the type that was asked.
-        // this is a first check to avoid going through the files.
-        ResourceFolderType[] folderTypes = FolderTypeRelationship.getRelatedFolders(type);
-        
-        boolean valid = false;
-        for (ResourceFolderType rft : folderTypes) {
-            if (rft == mType) {
-                valid = true;
-                break;
-            }
-        }
-        
-        if (valid) {
-            if (mFiles != null) {
-                for (ResourceFile f : mFiles) {
-                    if (f.hasResources(type)) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Get the list of {@link ResourceItem} of a specific type generated by all the files
-     * in the folder.
-     * This method must make sure not to create duplicates.
-     * @param type The type of {@link ResourceItem} to return.
-     * @param projectResources The global Project Resource object, allowing the implementation to
-     * query for already existing {@link ResourceItem}
-     * @return The list of <b>new</b> {@link ResourceItem}
-     * @see ProjectResources#findResourceItem(ResourceType, String)
-     */
-    public Collection<ProjectResourceItem> getResources(ResourceType type,
-            ProjectResources projectResources) {
-        Collection<ProjectResourceItem> list = new ArrayList<ProjectResourceItem>();
-        if (mFiles != null) {
-            for (ResourceFile f : mFiles) {
-                list.addAll(f.getResources(type, projectResources));
-            }
-        }
-        return list;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolderType.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolderType.java
deleted file mode 100644
index 0a56ff5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolderType.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.sdklib.SdkConstants;
-
-/**
- * Enum representing a type of resource folder.
- */
-public enum ResourceFolderType {
-    ANIM(SdkConstants.FD_ANIM),
-    COLOR(SdkConstants.FD_COLOR),
-    DRAWABLE(SdkConstants.FD_DRAWABLE),
-    LAYOUT(SdkConstants.FD_LAYOUT),
-    MENU(SdkConstants.FD_MENU),
-    RAW(SdkConstants.FD_RAW),
-    VALUES(SdkConstants.FD_VALUES),
-    XML(SdkConstants.FD_XML);
-
-    private final String mName;
-
-    ResourceFolderType(String name) {
-        mName = name;
-    }
-
-    public String getName() {
-        return mName;
-    }
-    
-    /**
-     * Returns the enum by name.
-     * @param name The enum string value.
-     * @return the enum or null if not found.
-     */
-    public static ResourceFolderType getTypeByName(String name) {
-        for (ResourceFolderType rType : values()) {
-            if (rType.mName.equals(name)) {
-                return rType;
-            }
-        }
-        return null;
-    }
-    
-    /**
-     * Returns the {@link ResourceFolderType} from the folder name
-     * @param folderName The name of the folder. This must be a valid folder name in the format
-     * <code>resType[-resqualifiers[-resqualifiers[...]]</code>
-     * @return the <code>ResourceFolderType</code> representing the type of the folder, or
-     * <code>null</code> if no matching type was found.
-     */
-    public static ResourceFolderType getFolderType(String folderName) {
-        // split the name of the folder in segments.
-        String[] folderSegments = folderName.split(FolderConfiguration.QUALIFIER_SEP);
-
-        // get the enum for the resource type.
-        return getTypeByName(folderSegments[0]);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
deleted file mode 100644
index 88693b0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IFolderListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IProjectListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.FileWrapper;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.FolderWrapper;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFile;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IFolderWrapper;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-
-public final class ResourceManager implements IProjectListener, IFolderListener, IFileListener {
-
-    private final static ResourceManager sThis = new ResourceManager();
-
-    /** List of the qualifier object helping for the parsing of folder names */
-    private final ResourceQualifier[] mQualifiers;
-
-    /**
-     * Map associating project resource with project objects.
-     */
-    private final HashMap<IProject, ProjectResources> mMap =
-        new HashMap<IProject, ProjectResources>();
-
-    /**
-     * Sets up the resource manager with the global resource monitor.
-     * @param monitor The global resource monitor
-     */
-    public static void setup(ResourceMonitor monitor) {
-        monitor.addProjectListener(sThis);
-        int mask = IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED;
-        monitor.addFolderListener(sThis, mask);
-        monitor.addFileListener(sThis, mask);
-
-        CompiledResourcesMonitor.setupMonitor(monitor);
-    }
-
-    /**
-     * Returns the singleton instance.
-     */
-    public static ResourceManager getInstance() {
-        return sThis;
-    }
-
-    /**
-     * Returns the resources of a project.
-     * @param project The project
-     * @return a ProjectResources object or null if none was found.
-     */
-    public ProjectResources getProjectResources(IProject project) {
-        return mMap.get(project);
-    }
-
-    /**
-     * Processes folder event.
-     */
-    public void folderChanged(IFolder folder, int kind) {
-        ProjectResources resources;
-
-        final IProject project = folder.getProject();
-
-        try {
-            if (project.hasNature(AndroidConstants.NATURE) == false) {
-                return;
-            }
-        } catch (CoreException e) {
-            // can't get the project nature? return!
-            return;
-        }
-
-        switch (kind) {
-            case IResourceDelta.ADDED:
-                // checks if the folder is under res.
-                IPath path = folder.getFullPath();
-
-                // the path will be project/res/<something>
-                if (path.segmentCount() == 3) {
-                    if (isInResFolder(path)) {
-                        // get the project and its resource object.
-                        resources = mMap.get(project);
-
-                        // if it doesn't exist, we create it.
-                        if (resources == null) {
-                            resources = new ProjectResources(false /* isFrameworkRepository */);
-                            mMap.put(project, resources);
-                        }
-
-                        processFolder(new IFolderWrapper(folder), resources);
-                    }
-                }
-                break;
-            case IResourceDelta.CHANGED:
-                resources = mMap.get(folder.getProject());
-                if (resources != null) {
-                    ResourceFolder resFolder = resources.getResourceFolder(folder);
-                    if (resFolder != null) {
-                        resFolder.touch();
-                    }
-                }
-                break;
-            case IResourceDelta.REMOVED:
-                resources = mMap.get(folder.getProject());
-                if (resources != null) {
-                    // lets get the folder type
-                    ResourceFolderType type = ResourceFolderType.getFolderType(folder.getName());
-
-                    resources.removeFolder(type, folder);
-                }
-                break;
-        }
-    }
-
-    /* (non-Javadoc)
-     * Sent when a file changed. Depending on the file being changed, and the type of change (ADDED,
-     * REMOVED, CHANGED), the file change is processed to update the resource manager data.
-     *
-     * @param file The file that changed.
-     * @param markerDeltas The marker deltas for the file.
-     * @param kind The change kind. This is equivalent to
-     * {@link IResourceDelta#accept(IResourceDeltaVisitor)}
-     *
-     * @see IFileListener#fileChanged
-     */
-    public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
-        ProjectResources resources;
-
-        final IProject project = file.getProject();
-
-        try {
-            if (project.hasNature(AndroidConstants.NATURE) == false) {
-                return;
-            }
-        } catch (CoreException e) {
-            // can't get the project nature? return!
-            return;
-        }
-
-        switch (kind) {
-            case IResourceDelta.ADDED:
-                // checks if the file is under res/something.
-                IPath path = file.getFullPath();
-
-                if (path.segmentCount() == 4) {
-                    if (isInResFolder(path)) {
-                        // get the project and its resources
-                        resources = mMap.get(project);
-
-                        IContainer container = file.getParent();
-                        if (container instanceof IFolder && resources != null) {
-
-                            ResourceFolder folder = resources.getResourceFolder((IFolder)container);
-
-                            if (folder != null) {
-                                processFile(new IFileWrapper(file), folder);
-                            }
-                        }
-                    }
-                }
-                break;
-            case IResourceDelta.CHANGED:
-                // try to find a matching ResourceFile
-                resources = mMap.get(project);
-                if (resources != null) {
-                    IContainer container = file.getParent();
-                    if (container instanceof IFolder) {
-                        ResourceFolder resFolder = resources.getResourceFolder((IFolder)container);
-
-                        // we get the delete on the folder before the file, so it is possible
-                        // the associated ResourceFolder doesn't exist anymore.
-                        if (resFolder != null) {
-                            // get the resourceFile, and touch it.
-                            ResourceFile resFile = resFolder.getFile(file);
-                            if (resFile != null) {
-                                resFile.touch();
-                            }
-                        }
-                    }
-                }
-                break;
-            case IResourceDelta.REMOVED:
-                // try to find a matching ResourceFile
-                resources = mMap.get(project);
-                if (resources != null) {
-                    IContainer container = file.getParent();
-                    if (container instanceof IFolder) {
-                        ResourceFolder resFolder = resources.getResourceFolder((IFolder)container);
-
-                        // we get the delete on the folder before the file, so it is possible
-                        // the associated ResourceFolder doesn't exist anymore.
-                        if (resFolder != null) {
-                            // remove the file
-                            resFolder.removeFile(file);
-                        }
-                    }
-                }
-                break;
-        }
-    }
-
-    public void projectClosed(IProject project) {
-        mMap.remove(project);
-    }
-
-    public void projectDeleted(IProject project) {
-        mMap.remove(project);
-    }
-
-    public void projectOpened(IProject project) {
-        createProject(project);
-    }
-
-    public void projectOpenedWithWorkspace(IProject project) {
-        createProject(project);
-    }
-
-    /**
-     * Returns the {@link ResourceFolder} for the given file or <code>null</code> if none exists.
-     */
-    public ResourceFolder getResourceFolder(IFile file) {
-        IContainer container = file.getParent();
-        if (container.getType() == IResource.FOLDER) {
-            IFolder parent = (IFolder)container;
-            IProject project = file.getProject();
-
-            ProjectResources resources = getProjectResources(project);
-            if (resources != null) {
-                return resources.getResourceFolder(parent);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Loads and returns the resources for a given {@link IAndroidTarget}
-     * @param androidTarget the target from which to load the framework resources
-     */
-    public ProjectResources loadFrameworkResources(IAndroidTarget androidTarget) {
-        String osResourcesPath = androidTarget.getPath(IAndroidTarget.RESOURCES);
-
-        File frameworkRes = new File(osResourcesPath);
-        if (frameworkRes.isDirectory()) {
-            ProjectResources resources = new ProjectResources(true /* isFrameworkRepository */);
-
-            try {
-                loadResources(resources, frameworkRes);
-                return resources;
-            } catch (IOException e) {
-                // since we test that folders are folders, and files are files, this shouldn't
-                // happen. We can ignore it.
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Loads the resources from a folder, and fills the given {@link ProjectResources}.
-     * <p/>
-     * This is mostly a utility method that should not be used to process actual Eclipse projects
-     * (Those are loaded with {@link #createProject(IProject)} for new project or
-     * {@link #processFolder(IAbstractFolder, ProjectResources)} and
-     * {@link #processFile(IAbstractFile, ResourceFolder)} for folder/file modifications)<br>
-     * This method will process files/folders with implementations of {@link IAbstractFile} and
-     * {@link IAbstractFolder} based on {@link File} instead of {@link IFile} and {@link IFolder}
-     * respectively. This is not proper for handling {@link IProject}s.
-     * </p>
-     * This is used to load the framework resources, or to do load project resources when
-     * setting rendering tests.
-     *
-     *
-     * @param resources The {@link ProjectResources} files to load. It is expected that the
-     * framework flag has been properly setup. This is filled up with the content of the folder.
-     * @param folder The folder to read the resources from. This is the top level resource folder
-     * (res/)
-     * @throws IOException
-     */
-    public void loadResources(ProjectResources resources, File folder) throws IOException {
-        File[] files = folder.listFiles();
-        for (File file : files) {
-            if (file.isDirectory()) {
-                ResourceFolder resFolder = processFolder(new FolderWrapper(file),
-                        resources);
-
-                if (resFolder != null) {
-                    // now we process the content of the folder
-                    File[] children = file.listFiles();
-
-                    for (File childRes : children) {
-                        if (childRes.isFile()) {
-                            processFile(new FileWrapper(childRes), resFolder);
-                        }
-                    }
-                }
-
-            }
-        }
-
-        // now that we have loaded the files, we need to force load the resources from them
-        resources.loadAll();
-    }
-
-    /**
-     * Initial project parsing to gather resource info.
-     * @param project
-     */
-    private void createProject(IProject project) {
-        if (project.isOpen()) {
-            try {
-                if (project.hasNature(AndroidConstants.NATURE) == false) {
-                    return;
-                }
-            } catch (CoreException e1) {
-                // can't check the nature of the project? ignore it.
-                return;
-            }
-
-            IFolder resourceFolder = project.getFolder(SdkConstants.FD_RESOURCES);
-
-            ProjectResources projectResources = mMap.get(project);
-            if (projectResources == null) {
-                projectResources = new ProjectResources(false /* isFrameworkRepository */);
-                mMap.put(project, projectResources);
-            }
-
-            if (resourceFolder != null && resourceFolder.exists()) {
-                try {
-                    IResource[] resources = resourceFolder.members();
-
-                    for (IResource res : resources) {
-                        if (res.getType() == IResource.FOLDER) {
-                            IFolder folder = (IFolder)res;
-                            ResourceFolder resFolder = processFolder(new IFolderWrapper(folder),
-                                    projectResources);
-
-                            if (resFolder != null) {
-                                // now we process the content of the folder
-                                IResource[] files = folder.members();
-
-                                for (IResource fileRes : files) {
-                                    if (fileRes.getType() == IResource.FILE) {
-                                        IFile file = (IFile)fileRes;
-
-                                        processFile(new IFileWrapper(file), resFolder);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } catch (CoreException e) {
-                    // This happens if the project is closed or if the folder doesn't exist.
-                    // Since we already test for that, we can ignore this exception.
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates a {@link FolderConfiguration} matching the folder segments.
-     * @param folderSegments The segments of the folder name. The first segments should contain
-     * the name of the folder
-     * @return a FolderConfiguration object, or null if the folder name isn't valid..
-     */
-    public FolderConfiguration getConfig(String[] folderSegments) {
-        FolderConfiguration config = new FolderConfiguration();
-
-        // we are going to loop through the segments, and match them with the first
-        // available qualifier. If the segment doesn't match we try with the next qualifier.
-        // Because the order of the qualifier is fixed, we do not reset the first qualifier
-        // after each sucessful segment.
-        // If we run out of qualifier before processing all the segments, we fail.
-
-        int qualifierIndex = 0;
-        int qualifierCount = mQualifiers.length;
-
-        for (int i = 1 ; i < folderSegments.length; i++) {
-            String seg = folderSegments[i];
-            if (seg.length() > 0) {
-                while (qualifierIndex < qualifierCount &&
-                        mQualifiers[qualifierIndex].checkAndSet(seg, config) == false) {
-                    qualifierIndex++;
-                }
-
-                // if we reached the end of the qualifier we didn't find a matching qualifier.
-                if (qualifierIndex == qualifierCount) {
-                    return null;
-                }
-
-            } else {
-                return null;
-            }
-        }
-
-        return config;
-    }
-
-    /**
-     * Processes a folder and adds it to the list of the project resources.
-     * @param folder the folder to process
-     * @param project the folder's project.
-     * @return the ConfiguredFolder created from this folder, or null if the process failed.
-     */
-    private ResourceFolder processFolder(IAbstractFolder folder, ProjectResources project) {
-        // split the name of the folder in segments.
-        String[] folderSegments = folder.getName().split(FolderConfiguration.QUALIFIER_SEP);
-
-        // get the enum for the resource type.
-        ResourceFolderType type = ResourceFolderType.getTypeByName(folderSegments[0]);
-
-        if (type != null) {
-            // get the folder configuration.
-            FolderConfiguration config = getConfig(folderSegments);
-
-            if (config != null) {
-                ResourceFolder configuredFolder = project.add(type, config, folder);
-
-                return configuredFolder;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Processes a file and adds it to its parent folder resource.
-     * @param file
-     * @param folder
-     */
-    private void processFile(IAbstractFile file, ResourceFolder folder) {
-        // get the type of the folder
-        ResourceFolderType type = folder.getType();
-
-        // look for this file if it's already been created
-        ResourceFile resFile = folder.getFile(file);
-
-        if (resFile != null) {
-            // invalidate the file
-            resFile.touch();
-        } else {
-            // create a ResourceFile for it.
-
-            // check if that's a single or multi resource type folder. For now we define this by
-            // the number of possible resource type output by files in the folder. This does
-            // not make the difference between several resource types from a single file or
-            // the ability to have 2 files in the same folder generating 2 different types of
-            // resource. The former is handled by MultiResourceFile properly while we don't
-            // handle the latter. If we were to add this behavior we'd have to change this call.
-            ResourceType[] types = FolderTypeRelationship.getRelatedResourceTypes(type);
-
-            if (types.length == 1) {
-                resFile = new SingleResourceFile(file, folder);
-            } else {
-                resFile = new MultiResourceFile(file, folder);
-            }
-
-            // add it to the folder
-            folder.addFile(resFile);
-        }
-    }
-
-    /**
-     * Returns true if the path is under /project/res/
-     * @param path a workspace relative path
-     * @return true if the path is under /project res/
-     */
-    private boolean isInResFolder(IPath path) {
-        return SdkConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1));
-    }
-
-    /**
-     * Private constructor to enforce singleton design.
-     */
-    ResourceManager() {
-        // get the default qualifiers.
-        FolderConfiguration defaultConfig = new FolderConfiguration();
-        defaultConfig.createDefault();
-        mQualifiers = defaultConfig.getQualifiers();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceMonitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceMonitor.java
deleted file mode 100644
index 06b23d5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceMonitor.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-
-import java.util.ArrayList;
-
-/**
- * Resource Monitor for the whole editor plugin. Other, more simple, listeners can register to
- * that one.
- */
-public class ResourceMonitor implements IResourceChangeListener {
-
-    private final static ResourceMonitor sThis = new ResourceMonitor();
-
-    /**
-     * Classes which implement this interface provide a method that deals
-     * with file change events.
-     */
-    public interface IFileListener {
-        /**
-         * Sent when a file changed.
-         * @param file The file that changed.
-         * @param markerDeltas The marker deltas for the file.
-         * @param kind The change kind. This is equivalent to
-         * {@link IResourceDelta#accept(IResourceDeltaVisitor)}
-         */
-        public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind);
-    }
-
-    /**
-     * Classes which implements this interface provide methods dealing with project events.
-     */
-    public interface IProjectListener {
-        /**
-         * Sent for each opened android project at the time the listener is put in place.
-         * @param project the opened project.
-         */
-        public void projectOpenedWithWorkspace(IProject project);
-        /**
-         * Sent when a project is opened.
-         * @param project the project being opened.
-         */
-        public void projectOpened(IProject project);
-        /**
-         * Sent when a project is closed.
-         * @param project the project being closed.
-         */
-        public void projectClosed(IProject project);
-        /**
-         * Sent when a project is deleted.
-         * @param project the project about to be deleted.
-         */
-        public void projectDeleted(IProject project);
-    }
-
-    /**
-     * Classes which implement this interface provide a method that deals
-     * with folder change events
-     */
-    public interface IFolderListener {
-        /**
-         * Sent when a folder changed.
-         * @param folder The file that was changed
-         * @param kind The change kind. This is equivalent to {@link IResourceDelta#getKind()}
-         */
-        public void folderChanged(IFolder folder, int kind);
-    }
-    
-    /**
-     * Interface for a listener to be notified when resource change event starts and ends.
-     */
-    public interface IResourceEventListener {
-        public void resourceChangeEventStart();
-        public void resourceChangeEventEnd();
-    }
-    
-    /**
-     * Base listener bundle to associate a listener to an event mask.
-     */
-    private static class ListenerBundle {
-        /** Mask value to accept all events */
-        public final static int MASK_NONE = -1; 
-
-        /**
-         * Event mask. Values accepted are IResourceDelta.###
-         * @see IResourceDelta#ADDED
-         * @see IResourceDelta#REMOVED
-         * @see IResourceDelta#CHANGED
-         * @see IResourceDelta#ADDED_PHANTOM
-         * @see IResourceDelta#REMOVED_PHANTOM
-         * */
-        int kindMask;
-    }
-    
-    /**
-     * Listener bundle for file event.
-     */
-    private static class FileListenerBundle extends ListenerBundle {
-
-        /** The file listener */
-        IFileListener listener;
-    }
-    
-    /**
-     * Listener bundle for folder event.
-     */
-    private static class FolderListenerBundle extends ListenerBundle {
-        /** The file listener */
-        IFolderListener listener;
-    }
-    
-    private final ArrayList<FileListenerBundle> mFileListeners =
-        new ArrayList<FileListenerBundle>();
-
-    private final ArrayList<FolderListenerBundle> mFolderListeners =
-        new ArrayList<FolderListenerBundle>();
-
-    private final ArrayList<IProjectListener> mProjectListeners = new ArrayList<IProjectListener>();
-    
-    private final ArrayList<IResourceEventListener> mEventListeners =
-        new ArrayList<IResourceEventListener>();
-    
-    private IWorkspace mWorkspace;
-
-    /**
-     * Delta visitor for resource changes.
-     */
-    private final class DeltaVisitor implements IResourceDeltaVisitor {
-
-        public boolean visit(IResourceDelta delta) {
-            IResource r = delta.getResource();
-            int type = r.getType();
-            if (type == IResource.FILE) {
-                int kind = delta.getKind();
-                // notify the listeners.
-                for (FileListenerBundle bundle : mFileListeners) {
-                    if (bundle.kindMask == ListenerBundle.MASK_NONE
-                            || (bundle.kindMask & kind) != 0) {
-                        bundle.listener.fileChanged((IFile)r, delta.getMarkerDeltas(), kind);
-                    }
-                }
-                return false;
-            } else if (type == IResource.FOLDER) {
-                int kind = delta.getKind();
-                // notify the listeners.
-                for (FolderListenerBundle bundle : mFolderListeners) {
-                    if (bundle.kindMask == ListenerBundle.MASK_NONE
-                            || (bundle.kindMask & kind) != 0) {
-                        bundle.listener.folderChanged((IFolder)r, kind);
-                    }
-                }
-                return true;
-            } else if (type == IResource.PROJECT) {
-                int flags = delta.getFlags();
-
-                if (flags == IResourceDelta.OPEN) {
-                    // the project is opening or closing.
-                    IProject project = (IProject)r;
-                    
-                    if (project.isOpen()) {
-                        // notify the listeners.
-                        for (IProjectListener pl : mProjectListeners) {
-                            pl.projectOpened(project);
-                        }
-                    } else {
-                        // notify the listeners.
-                        for (IProjectListener pl : mProjectListeners) {
-                            pl.projectClosed(project);
-                        }
-                    }
-                }
-            }
-
-            return true;
-        }
-    }
-    
-    public static ResourceMonitor getMonitor() {
-        return sThis;
-    }
-
-    
-    /**
-     * Starts the resource monitoring.
-     * @param ws The current workspace.
-     * @return The monitor object.
-     */
-    public static ResourceMonitor startMonitoring(IWorkspace ws) {
-        if (sThis != null) {
-            ws.addResourceChangeListener(sThis,
-                    IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE);
-            sThis.mWorkspace = ws;
-        }
-        return sThis;
-    }
-
-    /**
-     * Stops the resource monitoring.
-     * @param ws The current workspace.
-     */
-    public static void stopMonitoring(IWorkspace ws) {
-        if (sThis != null) {
-            ws.removeResourceChangeListener(sThis);
-            
-            sThis.mFileListeners.clear();
-            sThis.mProjectListeners.clear();
-        }
-    }
-
-    /**
-     * Adds a file listener.
-     * @param listener The listener to receive the events.
-     * @param kindMask The event mask to filter out specific events.
-     * {@link ListenerBundle#MASK_NONE} will forward all events. 
-     */
-    public synchronized void addFileListener(IFileListener listener, int kindMask) {
-        FileListenerBundle bundle = new FileListenerBundle();
-        bundle.listener = listener;
-        bundle.kindMask = kindMask;
-        
-        mFileListeners.add(bundle);
-    }
-    
-    /**
-     * Removes an existing file listener.
-     * @param listener the listener to remove.
-     */
-    public synchronized void removeFileListener(IFileListener listener) {
-        for (int i = 0 ; i < mFileListeners.size() ; i++) {
-            FileListenerBundle bundle = mFileListeners.get(i);
-            if (bundle.listener == listener) {
-                mFileListeners.remove(i);
-                return;
-            }
-        }
-    }
-
-    /**
-     * Adds a folder listener.
-     * @param listener The listener to receive the events.
-     * @param kindMask The event mask to filter out specific events.
-     * {@link ListenerBundle#MASK_NONE} will forward all events. 
-     */
-    public synchronized void addFolderListener(IFolderListener listener, int kindMask) {
-        FolderListenerBundle bundle = new FolderListenerBundle();
-        bundle.listener = listener;
-        bundle.kindMask = kindMask;
-        
-        mFolderListeners.add(bundle);
-    }
-
-    /**
-     * Removes an existing folder listener.
-     * @param listener the listener to remove.
-     */
-    public synchronized void removeFolderListener(IFolderListener listener) {
-        for (int i = 0 ; i < mFolderListeners.size() ; i++) {
-            FolderListenerBundle bundle = mFolderListeners.get(i);
-            if (bundle.listener == listener) {
-                mFolderListeners.remove(i);
-                return;
-            }
-        }
-    }
-
-    /**
-     * Adds a project listener.
-     * @param listener The listener to receive the events.
-     */
-    public synchronized void addProjectListener(IProjectListener listener) {
-        mProjectListeners.add(listener);
-        
-        // we need to look at the opened projects and give them to the listener.
-
-        // get the list of opened android projects.
-        IWorkspaceRoot workspaceRoot = mWorkspace.getRoot();
-        IJavaModel javaModel = JavaCore.create(workspaceRoot);
-        IJavaProject[] androidProjects = BaseProjectHelper.getAndroidProjects(javaModel);
-
-        for (IJavaProject androidProject : androidProjects) {
-            listener.projectOpenedWithWorkspace(androidProject.getProject());
-        }
-    }
-    
-    /**
-     * Removes an existing project listener.
-     * @param listener the listener to remove.
-     */
-    public synchronized void removeProjectListener(IProjectListener listener) {
-        mProjectListeners.remove(listener);
-    }
-    
-    /**
-     * Adds a resource event listener.
-     * @param listener The listener to receive the events.
-     */
-    public synchronized void addResourceEventListener(IResourceEventListener listener) {
-        mEventListeners.add(listener);
-    }
-
-    /**
-     * Removes an existing Resource Event listener.
-     * @param listener the listener to remove.
-     */
-    public synchronized void removeResourceEventListener(IResourceEventListener listener) {
-        mEventListeners.remove(listener);
-    }
-
-    /**
-     * Processes the workspace resource change events.
-     */
-    public void resourceChanged(IResourceChangeEvent event) {
-        // notify the event listeners of a start.
-        for (IResourceEventListener listener : mEventListeners) {
-            listener.resourceChangeEventStart();
-        }
-        
-        if (event.getType() == IResourceChangeEvent.PRE_DELETE) {
-            // a project is being deleted. Lets get the project object and remove
-            // its compiled resource list.
-            IResource r = event.getResource();
-            IProject project = r.getProject();
-
-            // notify the listeners.
-            for (IProjectListener pl : mProjectListeners) {
-                pl.projectDeleted(project);
-            }
-        } else {
-            // this a regular resource change. We get the delta and go through it with a visitor.
-            IResourceDelta delta = event.getDelta();
-            
-            DeltaVisitor visitor = new DeltaVisitor();
-            try {
-                delta.accept(visitor);
-            } catch (CoreException e) {
-            }
-        }
-
-        // we're done, notify the event listeners.
-        for (IResourceEventListener listener : mEventListeners) {
-            listener.resourceChangeEventEnd();
-        }
-    }
-    
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/SingleResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/SingleResourceFile.java
deleted file mode 100644
index 8900500..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/SingleResourceFile.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFile;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.utils.DensityBasedResourceValue;
-import com.android.layoutlib.utils.ResourceValue;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Represents a resource file describing a single resource.
- * <p/>
- * This is typically an XML file inside res/anim, res/layout, or res/menu or an image file
- * under res/drawable.
- */
-public class SingleResourceFile extends ResourceFile {
-
-    private final static SAXParserFactory sParserFactory = SAXParserFactory.newInstance();
-    static {
-        sParserFactory.setNamespaceAware(true);
-    }
-
-    private final static Pattern sXmlPattern = Pattern.compile("^(.+)\\.xml", //$NON-NLS-1$
-            Pattern.CASE_INSENSITIVE);
-
-    private final static Pattern[] sDrawablePattern = new Pattern[] {
-        Pattern.compile("^(.+)\\.9\\.png", Pattern.CASE_INSENSITIVE), //$NON-NLS-1$
-        Pattern.compile("^(.+)\\.png", Pattern.CASE_INSENSITIVE), //$NON-NLS-1$
-        Pattern.compile("^(.+)\\.jpg", Pattern.CASE_INSENSITIVE), //$NON-NLS-1$
-        Pattern.compile("^(.+)\\.gif", Pattern.CASE_INSENSITIVE), //$NON-NLS-1$
-    };
-
-    private String mResourceName;
-    private ResourceType mType;
-    private IResourceValue mValue;
-
-    public SingleResourceFile(IAbstractFile file, ResourceFolder folder) {
-        super(file, folder);
-
-        // we need to infer the type of the resource from the folder type.
-        // This is easy since this is a single Resource file.
-        ResourceType[] types = FolderTypeRelationship.getRelatedResourceTypes(folder.getType());
-        mType = types[0];
-
-        // compute the resource name
-        mResourceName = getResourceName(mType);
-
-        // test if there's a density qualifier associated with the resource
-        PixelDensityQualifier qualifier = folder.getConfiguration().getPixelDensityQualifier();
-
-        if (qualifier == null) {
-            mValue = new ResourceValue(mType.getName(), getResourceName(mType),
-                    file.getOsLocation(), isFramework());
-        } else {
-            mValue = new DensityBasedResourceValue(mType.getName(), getResourceName(mType),
-                    file.getOsLocation(), qualifier.getValue().getDensity(), isFramework());
-        }
-    }
-
-    @Override
-    public ResourceType[] getResourceTypes() {
-        return FolderTypeRelationship.getRelatedResourceTypes(getFolder().getType());
-    }
-
-    @Override
-    public boolean hasResources(ResourceType type) {
-        return FolderTypeRelationship.match(type, getFolder().getType());
-    }
-
-    @Override
-    public Collection<ProjectResourceItem> getResources(ResourceType type,
-            ProjectResources projectResources) {
-
-        // looking for an existing ResourceItem with this name and type
-        ProjectResourceItem item = projectResources.findResourceItem(type, mResourceName);
-
-        ArrayList<ProjectResourceItem> items = new ArrayList<ProjectResourceItem>();
-
-        if (item == null) {
-            item = new ConfigurableResourceItem(mResourceName);
-            items.add(item);
-        }
-
-        // add this ResourceFile to the ResourceItem
-        item.add(this);
-
-        return items;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ide.eclipse.editors.resources.manager.ResourceFile#getValue(com.android.ide.eclipse.common.resources.ResourceType, java.lang.String)
-     *
-     * This particular implementation does not care about the type or name since a
-     * SingleResourceFile represents a file generating only one resource.
-     * The value returned is the full absolute path of the file in OS form.
-     */
-    @Override
-    public IResourceValue getValue(ResourceType type, String name) {
-        return mValue;
-    }
-
-    /**
-     * Returns the name of the resources.
-     */
-    private String getResourceName(ResourceType type) {
-        // get the name from the filename.
-        String name = getFile().getName();
-
-        if (type == ResourceType.ANIM || type == ResourceType.LAYOUT || type == ResourceType.MENU ||
-                type == ResourceType.COLOR || type == ResourceType.XML) {
-            Matcher m = sXmlPattern.matcher(name);
-            if (m.matches()) {
-                return m.group(1);
-            }
-        } else if (type == ResourceType.DRAWABLE) {
-            for (Pattern p : sDrawablePattern) {
-                Matcher m = p.matcher(name);
-                if (m.matches()) {
-                    return m.group(1);
-                }
-            }
-
-            // also try the Xml pattern for selector/shape based drawable.
-            Matcher m = sXmlPattern.matcher(name);
-            if (m.matches()) {
-                return m.group(1);
-            }
-        }
-        return name;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FileWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FileWrapper.java
deleted file mode 100644
index 9de5290..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FileWrapper.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager.files;
-
-import org.eclipse.core.resources.IFile;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * An implementation of {@link IAbstractFile} on top of a {@link File} object.
- *
- */
-public class FileWrapper implements IAbstractFile {
-    
-    private File mFile;
-
-    /**
-     * Constructs a {@link FileWrapper} object. If {@link File#isFile()} returns <code>false</code>
-     * then an {@link IOException} is thrown. 
-     */
-    public FileWrapper(File file) throws IOException {
-        if (file.isFile() == false) {
-            throw new IOException("FileWrapper must wrap a File object representing an existing file!"); //$NON-NLS-1$
-        }
-        
-        mFile = file;
-    }
-
-    public InputStream getContents() {
-        try {
-            return new FileInputStream(mFile);
-        } catch (FileNotFoundException e) {
-            // we'll return null below.
-        }
-        
-        return null;
-    }
-
-    public IFile getIFile() {
-        return null;
-    }
-
-    public String getOsLocation() {
-        return mFile.getAbsolutePath();
-    }
-
-    public String getName() {
-        return mFile.getName();
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof FileWrapper) {
-            return mFile.equals(((FileWrapper)obj).mFile);
-        }
-        
-        if (obj instanceof File) {
-            return mFile.equals(obj);
-        }
-
-        return super.equals(obj);
-    }
-    
-    @Override
-    public int hashCode() {
-        return mFile.hashCode();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FolderWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FolderWrapper.java
deleted file mode 100644
index 1e96164..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FolderWrapper.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager.files;
-
-import org.eclipse.core.resources.IFolder;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * An implementation of {@link IAbstractFolder} on top of a {@link File} object.
- */
-public class FolderWrapper implements IAbstractFolder {
-
-    private File mFolder;
-
-    /**
-     * Constructs a {@link FileWrapper} object. If {@link File#isDirectory()} returns
-     * <code>false</code> then an {@link IOException} is thrown. 
-     */
-    public FolderWrapper(File folder) throws IOException {
-        if (folder.isDirectory() == false) {
-            throw new IOException("FileWrapper must wrap a File object representing an existing folder!"); //$NON-NLS-1$
-        }
-        
-        mFolder = folder;
-    }
-    
-    public boolean hasFile(String name) {
-        return false;
-    }
-
-    public String getName() {
-        return mFolder.getName();
-    }
-
-    public IFolder getIFolder() {
-        return null;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof FolderWrapper) {
-            return mFolder.equals(((FolderWrapper)obj).mFolder);
-        }
-        
-        if (obj instanceof File) {
-            return mFolder.equals(obj);
-        }
-
-        return super.equals(obj);
-    }
-    
-    @Override
-    public int hashCode() {
-        return mFolder.hashCode();
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFile.java
deleted file mode 100644
index db1de5a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFile.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager.files;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-
-import java.io.InputStream;
-
-/**
- * A file.
- */
-public interface IAbstractFile extends IAbstractResource {
-
-    /**
-     * Returns an {@link InputStream} object on the file content.
-     * @throws CoreException
-     */
-    InputStream getContents() throws CoreException;
-
-    /**
-     * Returns the OS path of the file location.
-     */
-    String getOsLocation();
-
-    /**
-     * Returns the {@link IFile} object that the receiver could represent. Can be <code>null</code>
-     */
-    IFile getIFile();
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFolder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFolder.java
deleted file mode 100644
index 8557ae2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFolder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager.files;
-
-import org.eclipse.core.resources.IFolder;
-
-/**
- *  A folder.
- */
-public interface IAbstractFolder extends IAbstractResource {
-
-    /**
-     * Returns true if the receiver contains a file with a given name 
-     * @param name the name of the file. This is the name without the path leading to the
-     * parent folder.
-     */
-    boolean hasFile(String name);
-
-    /**
-     * Returns the {@link IFolder} object that the receiver could represent.
-     * Can be <code>null</code>
-     */
-    IFolder getIFolder();
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractResource.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractResource.java
deleted file mode 100644
index 76f338a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractResource.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager.files;
-
-import org.eclipse.core.resources.IFile;
-
-import java.io.File;
-
-/**
- * Base representation of a file system resource.<p/>
- * This somewhat limited interface is designed to let classes use file-system resources, without
- * having the manually handle  {@link IFile} and/or {@link File} manually.
- */
-public interface IAbstractResource {
-
-    /**
-     * Returns the name of the resource.
-     */
-    String getName();
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFileWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFileWrapper.java
deleted file mode 100644
index a85d36b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFileWrapper.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager.files;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-
-import java.io.InputStream;
-
-/**
- * An implementation of {@link IAbstractFile} on top of an {@link IFile} object.
- */
-public class IFileWrapper implements IAbstractFile {
-
-    private IFile mFile;
-
-    public IFileWrapper(IFile file) {
-        mFile = file;
-    }
-    
-    public InputStream getContents() throws CoreException {
-        return mFile.getContents();
-    }
-
-    public String getOsLocation() {
-        return mFile.getLocation().toOSString();
-    }
-
-    public String getName() {
-        return mFile.getName();
-    }
-
-    public IFile getIFile() {
-        return mFile;
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof IFileWrapper) {
-            return mFile.equals(((IFileWrapper)obj).mFile);
-        }
-        
-        if (obj instanceof IFile) {
-            return mFile.equals(obj);
-        }
-
-        return super.equals(obj);
-    }
-    
-    @Override
-    public int hashCode() {
-        return mFile.hashCode();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFolderWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFolderWrapper.java
deleted file mode 100644
index a92fecd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFolderWrapper.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager.files;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-
-/**
- * An implementation of {@link IAbstractFolder} on top of an {@link IFolder} object.
- */
-public class IFolderWrapper implements IAbstractFolder {
-    
-    private IFolder mFolder;
-
-    public IFolderWrapper(IFolder folder) {
-        mFolder = folder;
-    }
-
-    public String getName() {
-        return mFolder.getName();
-    }
-
-    public boolean hasFile(String name) {
-        try {
-            IResource[] files = mFolder.members();
-            for (IResource file : files) {
-                if (name.equals(file.getName())) {
-                    return true;
-                }
-            }
-        } catch (CoreException e) {
-            // we'll return false below.
-        }
-
-        return false;
-    }
-    
-    public IFolder getIFolder() {
-        return mFolder;
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof IFolderWrapper) {
-            return mFolder.equals(((IFolderWrapper)obj).mFolder);
-        }
-        
-        if (obj instanceof IFolder) {
-            return mFolder.equals(obj);
-        }
-
-        return super.equals(obj);
-    }
-    
-    @Override
-    public int hashCode() {
-        return mFolder.hashCode();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoader.java
deleted file mode 100644
index 477d14a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoader.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubMonitor;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import javax.management.InvalidAttributeValueException;
-
-/**
- * Custom class loader able to load a class from the SDK jar file.
- */
-public class AndroidJarLoader extends ClassLoader implements IAndroidClassLoader {
-    
-    /**
-     * Wrapper around a {@link Class} to provide the methods of
-     * {@link IAndroidClassLoader.IClassDescriptor}.
-     */
-    public final static class ClassWrapper implements IClassDescriptor {
-        private Class<?> mClass;
-
-        public ClassWrapper(Class<?> clazz) {
-            mClass = clazz;
-        }
-
-        public String getCanonicalName() {
-            return mClass.getCanonicalName();
-        }
-
-        public IClassDescriptor[] getDeclaredClasses() {
-            Class<?>[] classes = mClass.getDeclaredClasses();
-            IClassDescriptor[] iclasses = new IClassDescriptor[classes.length];
-            for (int i = 0 ; i < classes.length ; i++) {
-                iclasses[i] = new ClassWrapper(classes[i]);
-            }
-
-            return iclasses;
-        }
-
-        public IClassDescriptor getEnclosingClass() {
-            return new ClassWrapper(mClass.getEnclosingClass());
-        }
-
-        public String getSimpleName() {
-            return mClass.getSimpleName();
-        }
-
-        public IClassDescriptor getSuperclass() {
-            return new ClassWrapper(mClass.getSuperclass());
-        }
-        
-        @Override
-        public boolean equals(Object clazz) {
-            if (clazz instanceof ClassWrapper) {
-                return mClass.equals(((ClassWrapper)clazz).mClass);
-            }
-            return super.equals(clazz);
-        }
-        
-        @Override
-        public int hashCode() {
-            return mClass.hashCode();
-        }
-
-
-        public boolean isInstantiable() {
-            int modifiers = mClass.getModifiers();
-            return Modifier.isAbstract(modifiers) == false && Modifier.isPublic(modifiers) == true;
-        }
-
-        public Class<?> wrappedClass() {
-            return mClass;
-        }
-
-    }
-    
-    private String mOsFrameworkLocation;
-    
-    /** A cache for binary data extracted from the zip */
-    private final HashMap<String, byte[]> mEntryCache = new HashMap<String, byte[]>();
-    /** A cache for already defined Classes */
-    private final HashMap<String, Class<?> > mClassCache = new HashMap<String, Class<?> >();
-    
-    /**
-     * Creates the class loader by providing the os path to the framework jar archive
-     * 
-     * @param osFrameworkLocation OS Path of the framework JAR file
-     */
-    public AndroidJarLoader(String osFrameworkLocation) {
-        super();
-        mOsFrameworkLocation = osFrameworkLocation;
-    }
-    
-    public String getSource() {
-        return mOsFrameworkLocation;
-    }
-    
-    /**
-     * Pre-loads all class binary data that belong to the given package by reading the archive
-     * once and caching them internally.
-     * <p/>
-     * This does not actually preload "classes", it just reads the unzipped bytes for a given
-     * class. To obtain a class, one must call {@link #findClass(String)} later.
-     * <p/>
-     * All classes which package name starts with "packageFilter" will be included and can be
-     * found later.
-     * <p/>
-     * May throw some exceptions if the framework JAR cannot be read.
-     * 
-     * @param packageFilter The package that contains all the class data to preload, using a fully
-     *                    qualified binary name (.e.g "com.my.package."). The matching algorithm
-     *                    is simple "startsWith". Use an empty string to include everything.
-     * @param taskLabel An optional task name for the sub monitor. Can be null.
-     * @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
-     * @throws IOException
-     * @throws InvalidAttributeValueException
-     * @throws ClassFormatError
-     */
-    public void preLoadClasses(String packageFilter, String taskLabel, IProgressMonitor monitor)
-        throws IOException, InvalidAttributeValueException, ClassFormatError {
-        // Transform the package name into a zip entry path
-        String pathFilter = packageFilter.replaceAll("\\.", "/"); //$NON-NLS-1$ //$NON-NLS-2$
-        
-        SubMonitor progress = SubMonitor.convert(monitor, taskLabel == null ? "" : taskLabel, 100);
-        
-        // create streams to read the intermediary archive
-        FileInputStream fis = new FileInputStream(mOsFrameworkLocation);
-        ZipInputStream zis = new ZipInputStream(fis);
-        ZipEntry entry;       
-        while ((entry = zis.getNextEntry()) != null) {
-            // get the name of the entry.
-            String entryPath = entry.getName();
-            
-            if (!entryPath.endsWith(AndroidConstants.DOT_CLASS)) {
-                // only accept class files
-                continue;
-            }
-
-            // check if it is part of the package to preload
-            if (pathFilter.length() > 0 && !entryPath.startsWith(pathFilter)) {
-                continue;
-            }
-            String className = entryPathToClassName(entryPath);
-
-            if (!mEntryCache.containsKey(className)) {
-                long entrySize = entry.getSize();
-                if (entrySize > Integer.MAX_VALUE) {
-                    throw new InvalidAttributeValueException();
-                }
-                byte[] data = readZipData(zis, (int)entrySize);
-                mEntryCache.put(className, data);
-            }
-
-            // advance 5% of whatever is allocated on the progress bar
-            progress.setWorkRemaining(100);
-            progress.worked(5);
-            progress.subTask(String.format("Preload %1$s", className));
-        }
-    }
-
-    /**
-     * Finds and loads all classes that derive from a given set of super classes.
-     * <p/>
-     * As a side-effect this will load and cache most, if not all, classes in the input JAR file.
-     * 
-     * @param packageFilter Base name of package of classes to find.
-     *                      Use an empty string to find everyting.
-     * @param superClasses The super classes of all the classes to find. 
-     * @return An hash map which keys are the super classes looked for and which values are
-     *         ArrayList of the classes found. The array lists are always created for all the
-     *         valid keys, they are simply empty if no deriving class is found for a given
-     *         super class. 
-     * @throws IOException
-     * @throws InvalidAttributeValueException
-     * @throws ClassFormatError
-     */
-    public HashMap<String, ArrayList<IClassDescriptor>> findClassesDerivingFrom(
-            String packageFilter,
-            String[] superClasses)
-            throws IOException, InvalidAttributeValueException, ClassFormatError {
-
-        packageFilter = packageFilter.replaceAll("\\.", "/"); //$NON-NLS-1$ //$NON-NLS-2$
-
-        HashMap<String, ArrayList<IClassDescriptor>> mClassesFound =
-                new HashMap<String, ArrayList<IClassDescriptor>>();
-
-        for (String className : superClasses) {
-            mClassesFound.put(className, new ArrayList<IClassDescriptor>());
-        }
-
-        // create streams to read the intermediary archive
-        FileInputStream fis = new FileInputStream(mOsFrameworkLocation);
-        ZipInputStream zis = new ZipInputStream(fis);
-        ZipEntry entry;
-        while ((entry = zis.getNextEntry()) != null) {
-            // get the name of the entry and convert to a class binary name
-            String entryPath = entry.getName();
-            if (!entryPath.endsWith(AndroidConstants.DOT_CLASS)) {
-                // only accept class files
-                continue;
-            }
-            if (packageFilter.length() > 0 && !entryPath.startsWith(packageFilter)) {
-                // only accept stuff from the requested root package.
-                continue;
-            }
-            String className = entryPathToClassName(entryPath);
-      
-            Class<?> loaded_class = mClassCache.get(className);
-            if (loaded_class == null) {
-                byte[] data = mEntryCache.get(className);
-                if (data == null) {    
-                    // Get the class and cache it
-                    long entrySize = entry.getSize();
-                    if (entrySize > Integer.MAX_VALUE) {
-                        throw new InvalidAttributeValueException();
-                    }
-                    data = readZipData(zis, (int)entrySize);
-                }
-                loaded_class = defineAndCacheClass(className, data);
-            }
-
-            for (Class<?> superClass = loaded_class.getSuperclass();
-                    superClass != null;
-                    superClass = superClass.getSuperclass()) {
-                String superName = superClass.getCanonicalName();
-                if (mClassesFound.containsKey(superName)) {
-                    mClassesFound.get(superName).add(new ClassWrapper(loaded_class));
-                    break;
-                }
-            }
-        }
-
-        return mClassesFound;
-    }
-
-    /** Helper method that converts a Zip entry path into a corresponding
-     *  Java full qualified binary class name.
-     *  <p/>
-     *  F.ex, this converts "com/my/package/Foo.class" into "com.my.package.Foo".
-     */
-    private String entryPathToClassName(String entryPath) {
-        return entryPath.replaceFirst("\\.class$", "").replaceAll("[/\\\\]", "."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-    /**
-     * Finds the class with the specified binary name.
-     * 
-     * {@inheritDoc}
-     */
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        try {
-            // try to find the class in the cache
-            Class<?> cached_class = mClassCache.get(name);
-            if (cached_class == ClassNotFoundException.class) {
-                // we already know we can't find this class, don't try again
-                throw new ClassNotFoundException(name);
-            } else if (cached_class != null) {
-                return cached_class;
-            }
-            
-            // if not found, look it up and cache it
-            byte[] data = loadClassData(name);
-            if (data != null) {
-                return defineAndCacheClass(name, data);
-            } else {
-                // if the class can't be found, record a CNFE class in the map so
-                // that we don't try to reload it next time
-                mClassCache.put(name, ClassNotFoundException.class);
-                throw new ClassNotFoundException(name);
-            }
-        } catch (ClassNotFoundException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new ClassNotFoundException(e.getMessage()); 
-        }
-    }
-
-    /**
-     * Defines a class based on its binary data and caches the resulting class object.
-     * 
-     * @param name The binary name of the class (i.e. package.class1$class2)
-     * @param data The binary data from the loader.
-     * @return The class defined
-     * @throws ClassFormatError if defineClass failed.
-     */
-    private Class<?> defineAndCacheClass(String name, byte[] data) throws ClassFormatError {
-        Class<?> cached_class;
-        cached_class = defineClass(null, data, 0, data.length);
-
-        if (cached_class != null) {
-            // Add new class to the cache class and remove it from the zip entry data cache
-            mClassCache.put(name, cached_class);
-            mEntryCache.remove(name);
-        }
-        return cached_class;
-    }
-    
-    /**
-     * Loads a class data from its binary name.
-     * <p/>
-     * This uses the class binary data that has been preloaded earlier by the preLoadClasses()
-     * method if possible.
-     * 
-     * @param className the binary name
-     * @return an array of bytes representing the class data or null if not found
-     * @throws InvalidAttributeValueException 
-     * @throws IOException 
-     */
-    private synchronized byte[] loadClassData(String className)
-            throws InvalidAttributeValueException, IOException {
-
-        byte[] data = mEntryCache.get(className);
-        if (data != null) {
-            return data;
-        }
-        
-        // The name is a binary name. Something like "android.R", or "android.R$id".
-        // Make a path out of it.
-        String entryName = className.replaceAll("\\.", "/") + AndroidConstants.DOT_CLASS; //$NON-NLS-1$ //$NON-NLS-2$
-
-       // create streams to read the intermediary archive
-        FileInputStream fis = new FileInputStream(mOsFrameworkLocation);
-        ZipInputStream zis = new ZipInputStream(fis);
-        
-        // loop on the entries of the intermediary package and put them in the final package.
-        ZipEntry entry;
-
-        while ((entry = zis.getNextEntry()) != null) {
-            // get the name of the entry.
-            String currEntryName = entry.getName();
-            
-            if (currEntryName.equals(entryName)) {
-                long entrySize = entry.getSize();
-                if (entrySize > Integer.MAX_VALUE) {
-                    throw new InvalidAttributeValueException();
-                }
-
-                data = readZipData(zis, (int)entrySize);
-                return data;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Reads data for the <em>current</em> entry from the zip input stream.
-     * 
-     * @param zis The Zip input stream
-     * @param entrySize The entry size. -1 if unknown.
-     * @return The new data for the <em>current</em> entry.
-     * @throws IOException If ZipInputStream.read() fails.
-     */
-    private byte[] readZipData(ZipInputStream zis, int entrySize) throws IOException {
-        int block_size = 1024;
-        int data_size = entrySize < 1 ? block_size : entrySize; 
-        int offset = 0;
-        byte[] data = new byte[data_size];
-        
-        while(zis.available() != 0) {
-            int count = zis.read(data, offset, data_size - offset);
-            if (count < 0) {  // read data is done
-                break;
-            }
-            offset += count;
-            
-            if (entrySize >= 1 && offset >= entrySize) {  // we know the size and we're done
-                break;
-            }
-
-            // if we don't know the entry size and we're not done reading,
-            // expand the data buffer some more.
-            if (offset >= data_size) {
-                byte[] temp = new byte[data_size + block_size];
-                System.arraycopy(data, 0, temp, 0, data_size);
-                data_size += block_size;
-                data = temp;
-                block_size *= 2;
-            }
-        }
-        
-        if (offset < data_size) {
-            // buffer was allocated too large, trim it
-            byte[] temp = new byte[offset];
-            if (offset > 0) {
-                System.arraycopy(data, 0, temp, 0, offset);
-            }
-            data = temp;
-        }
-        
-        return data;
-    }
-
-    /**
-     * Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name.
-     * @param className the fully-qualified name of the class to return.
-     * @throws ClassNotFoundException
-     */
-    public IClassDescriptor getClass(String className) throws ClassNotFoundException {
-        try {
-            return new ClassWrapper(loadClass(className));
-        } catch (ClassNotFoundException e) {
-            throw e;  // useful for debugging
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetData.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetData.java
deleted file mode 100644
index abd7cf8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetData.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.menu.descriptors.MenuDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.xml.descriptors.XmlDescriptors;
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.layoutlib.api.ILayoutBridge;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.Map;
-
-/**
- * This class contains the data of an Android Target as loaded from the SDK.
- */
-public class AndroidTargetData {
-
-    public final static int DESCRIPTOR_MANIFEST = 1;
-    public final static int DESCRIPTOR_LAYOUT = 2;
-    public final static int DESCRIPTOR_MENU = 3;
-    public final static int DESCRIPTOR_XML = 4;
-    public final static int DESCRIPTOR_RESOURCES = 5;
-    public final static int DESCRIPTOR_SEARCHABLE = 6;
-    public final static int DESCRIPTOR_PREFERENCES = 7;
-    public final static int DESCRIPTOR_APPWIDGET_PROVIDER = 8;
-
-    public final static class LayoutBridge {
-        /** Link to the layout bridge */
-        public ILayoutBridge bridge;
-
-        public LoadStatus status = LoadStatus.LOADING;
-
-        public ClassLoader classLoader;
-
-        public int apiLevel;
-    }
-
-    private final IAndroidTarget mTarget;
-
-    private DexWrapper mDexWrapper;
-
-    /**
-     * mAttributeValues is a map { key => list [ values ] }.
-     * The key for the map is "(element-xml-name,attribute-namespace:attribute-xml-local-name)".
-     * The attribute namespace prefix must be:
-     * - "android" for AndroidConstants.NS_RESOURCES
-     * - "xmlns" for the XMLNS URI.
-     *
-     * This is used for attributes that do not have a unique name, but still need to be populated
-     * with values in the UI. Uniquely named attributes have their values in {@link #mEnumValueMap}.
-     */
-    private Hashtable<String, String[]> mAttributeValues = new Hashtable<String, String[]>();
-
-    private IResourceRepository mSystemResourceRepository;
-
-    private AndroidManifestDescriptors mManifestDescriptors;
-    private LayoutDescriptors mLayoutDescriptors;
-    private MenuDescriptors mMenuDescriptors;
-    private XmlDescriptors mXmlDescriptors;
-
-    private Map<String, Map<String, Integer>> mEnumValueMap;
-
-    private ProjectResources mFrameworkResources;
-    private LayoutBridge mLayoutBridge;
-
-    private boolean mLayoutBridgeInit = false;
-
-    AndroidTargetData(IAndroidTarget androidTarget) {
-        mTarget = androidTarget;
-    }
-
-    void setDexWrapper(DexWrapper wrapper) {
-        mDexWrapper = wrapper;
-    }
-
-    /**
-     * Creates an AndroidTargetData object.
-     * @param platformLibraries
-     * @param optionalLibraries
-     */
-    void setExtraData(IResourceRepository systemResourceRepository,
-            AndroidManifestDescriptors manifestDescriptors,
-            LayoutDescriptors layoutDescriptors,
-            MenuDescriptors menuDescriptors,
-            XmlDescriptors xmlDescriptors,
-            Map<String, Map<String, Integer>> enumValueMap,
-            String[] permissionValues,
-            String[] activityIntentActionValues,
-            String[] broadcastIntentActionValues,
-            String[] serviceIntentActionValues,
-            String[] intentCategoryValues,
-            String[] platformLibraries,
-            IOptionalLibrary[] optionalLibraries,
-            ProjectResources resources,
-            LayoutBridge layoutBridge) {
-
-        mSystemResourceRepository = systemResourceRepository;
-        mManifestDescriptors = manifestDescriptors;
-        mLayoutDescriptors = layoutDescriptors;
-        mMenuDescriptors = menuDescriptors;
-        mXmlDescriptors = xmlDescriptors;
-        mEnumValueMap = enumValueMap;
-        mFrameworkResources = resources;
-        mLayoutBridge = layoutBridge;
-
-        setPermissions(permissionValues);
-        setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues,
-                serviceIntentActionValues, intentCategoryValues);
-        setOptionalLibraries(platformLibraries, optionalLibraries);
-    }
-
-    public DexWrapper getDexWrapper() {
-        return mDexWrapper;
-    }
-
-    public IResourceRepository getSystemResources() {
-        return mSystemResourceRepository;
-    }
-
-    /**
-     * Returns an {@link IDescriptorProvider} from a given Id.
-     * The Id can be one of {@link #DESCRIPTOR_MANIFEST}, {@link #DESCRIPTOR_LAYOUT},
-     * {@link #DESCRIPTOR_MENU}, or {@link #DESCRIPTOR_XML}.
-     * All other values will throw an {@link IllegalArgumentException}.
-     */
-    public IDescriptorProvider getDescriptorProvider(int descriptorId) {
-        switch (descriptorId) {
-            case DESCRIPTOR_MANIFEST:
-                return mManifestDescriptors;
-            case DESCRIPTOR_LAYOUT:
-                return mLayoutDescriptors;
-            case DESCRIPTOR_MENU:
-                return mMenuDescriptors;
-            case DESCRIPTOR_XML:
-                return mXmlDescriptors;
-            case DESCRIPTOR_RESOURCES:
-                // FIXME: since it's hard-coded the Resources Descriptors are not platform dependent.
-                return ResourcesDescriptors.getInstance();
-            case DESCRIPTOR_PREFERENCES:
-                return mXmlDescriptors.getPreferencesProvider();
-            case DESCRIPTOR_APPWIDGET_PROVIDER:
-                return mXmlDescriptors.getAppWidgetProvider();
-            case DESCRIPTOR_SEARCHABLE:
-                return mXmlDescriptors.getSearchableProvider();
-            default :
-                 throw new IllegalArgumentException();
-        }
-    }
-
-    /**
-     * Returns the manifest descriptors.
-     */
-    public AndroidManifestDescriptors getManifestDescriptors() {
-        return mManifestDescriptors;
-    }
-
-    /**
-     * Returns the layout Descriptors.
-     */
-    public LayoutDescriptors getLayoutDescriptors() {
-        return mLayoutDescriptors;
-    }
-
-    /**
-     * Returns the menu descriptors.
-     */
-    public MenuDescriptors getMenuDescriptors() {
-        return mMenuDescriptors;
-    }
-
-    /**
-     * Returns the XML descriptors
-     */
-    public XmlDescriptors getXmlDescriptors() {
-        return mXmlDescriptors;
-    }
-
-    /**
-     * Returns this list of possible values for an XML attribute.
-     * <p/>This should only be called for attributes for which possible values depend on the
-     * parent element node.
-     * <p/>For attributes that have the same values no matter the parent node, use
-     * {@link #getEnumValueMap()}.
-     * @param elementName the name of the element containing the attribute.
-     * @param attributeName the name of the attribute
-     * @return an array of String with the possible values, or <code>null</code> if no values were
-     * found.
-     */
-    public String[] getAttributeValues(String elementName, String attributeName) {
-        String key = String.format("(%1$s,%2$s)", elementName, attributeName); //$NON-NLS-1$
-        return mAttributeValues.get(key);
-    }
-
-    /**
-     * Returns this list of possible values for an XML attribute.
-     * <p/>This should only be called for attributes for which possible values depend on the
-     * parent and great-grand-parent element node.
-     * <p/>The typical example of this is for the 'name' attribute under
-     * activity/intent-filter/action
-     * <p/>For attributes that have the same values no matter the parent node, use
-     * {@link #getEnumValueMap()}.
-     * @param elementName the name of the element containing the attribute.
-     * @param attributeName the name of the attribute
-     * @param greatGrandParentElementName the great-grand-parent node.
-     * @return an array of String with the possible values, or <code>null</code> if no values were
-     * found.
-     */
-    public String[] getAttributeValues(String elementName, String attributeName,
-            String greatGrandParentElementName) {
-        if (greatGrandParentElementName != null) {
-            String key = String.format("(%1$s,%2$s,%3$s)", //$NON-NLS-1$
-                    greatGrandParentElementName, elementName, attributeName);
-            String[] values = mAttributeValues.get(key);
-            if (values != null) {
-                return values;
-            }
-        }
-
-        return getAttributeValues(elementName, attributeName);
-    }
-
-    /**
-     * Returns the enum values map.
-     * <p/>The map defines the possible values for XML attributes. The key is the attribute name
-     * and the value is a map of (string, integer) in which the key (string) is the name of
-     * the value, and the Integer is the numerical value in the compiled binary XML files.
-     */
-    public Map<String, Map<String, Integer>> getEnumValueMap() {
-        return mEnumValueMap;
-    }
-
-    /**
-     * Returns the {@link ProjectResources} containing the Framework Resources.
-     */
-    public ProjectResources getFrameworkResources() {
-        return mFrameworkResources;
-    }
-
-    /**
-     * Returns a {@link LayoutBridge} object possibly containing a {@link ILayoutBridge} object.
-     * <p/>If {@link LayoutBridge#bridge} is <code>null</code>, {@link LayoutBridge#status} will
-     * contain the reason (either {@link LoadStatus#LOADING} or {@link LoadStatus#FAILED}).
-     * <p/>Valid {@link ILayoutBridge} objects are always initialized before being returned.
-     */
-    public synchronized LayoutBridge getLayoutBridge() {
-        if (mLayoutBridgeInit == false && mLayoutBridge.bridge != null) {
-            mLayoutBridge.bridge.init(mTarget.getPath(IAndroidTarget.FONTS),
-                    getEnumValueMap());
-            mLayoutBridgeInit = true;
-        }
-        return mLayoutBridge;
-    }
-
-    /**
-     * Sets the permission values
-     * @param permissionValues the list of permissions
-     */
-    private void setPermissions(String[] permissionValues) {
-        setValues("(uses-permission,android:name)", permissionValues);   //$NON-NLS-1$
-        setValues("(application,android:permission)", permissionValues); //$NON-NLS-1$
-        setValues("(activity,android:permission)", permissionValues);    //$NON-NLS-1$
-        setValues("(receiver,android:permission)", permissionValues);    //$NON-NLS-1$
-        setValues("(service,android:permission)", permissionValues);     //$NON-NLS-1$
-        setValues("(provider,android:permission)", permissionValues);    //$NON-NLS-1$
-    }
-
-    private void setIntentFilterActionsAndCategories(String[] activityIntentActions,
-            String[] broadcastIntentActions, String[] serviceIntentActions,
-            String[] intentCategoryValues) {
-        setValues("(activity,action,android:name)", activityIntentActions);  //$NON-NLS-1$
-        setValues("(receiver,action,android:name)", broadcastIntentActions); //$NON-NLS-1$
-        setValues("(service,action,android:name)", serviceIntentActions);    //$NON-NLS-1$
-        setValues("(category,android:name)", intentCategoryValues);          //$NON-NLS-1$
-    }
-
-    private void setOptionalLibraries(String[] platformLibraries,
-            IOptionalLibrary[] optionalLibraries) {
-
-        ArrayList<String> libs = new ArrayList<String>();
-
-        if (platformLibraries != null) {
-            for (String name : platformLibraries) {
-                libs.add(name);
-            }
-        }
-
-        if (optionalLibraries != null) {
-            for (int i = 0; i < optionalLibraries.length; i++) {
-                libs.add(optionalLibraries[i].getName());
-            }
-        }
-        setValues("(uses-library,android:name)",  libs.toArray(new String[libs.size()]));
-    }
-
-    /**
-     * Sets a (name, values) pair in the hash map.
-     * <p/>
-     * If the name is already present in the map, it is first removed.
-     * @param name the name associated with the values.
-     * @param values The values to add.
-     */
-    private void setValues(String name, String[] values) {
-        mAttributeValues.remove(name);
-        mAttributeValues.put(name, values);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java
deleted file mode 100644
index a499137..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.menu.descriptors.MenuDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.xml.descriptors.XmlDescriptors;
-import com.android.ide.eclipse.adt.internal.resources.AttrsXmlParser;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
-import com.android.layoutlib.api.ILayoutBridge;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubMonitor;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.management.InvalidAttributeValueException;
-
-/**
- * Parser for the platform data in an SDK.
- * <p/>
- * This gather the following information:
- * <ul>
- * <li>Resource ID from <code>android.R</code></li>
- * <li>The list of permissions values from <code>android.Manifest$permission</code></li>
- * <li></li>
- * </ul>
- */
-public final class AndroidTargetParser {
-
-    private static final String TAG = "Framework Resource Parser";
-    private final IAndroidTarget mAndroidTarget;
-
-    /**
-     * Creates a platform data parser.
-     */
-    public AndroidTargetParser(IAndroidTarget platformTarget) {
-        mAndroidTarget = platformTarget;
-    }
-
-    /**
-     * Parses the framework, collects all interesting information and stores them in the
-     * {@link IAndroidTarget} given to the constructor.
-     *
-     * @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
-     * @return True if the SDK path was valid and parsing has been attempted.
-     */
-    public IStatus run(IProgressMonitor monitor) {
-        try {
-            SubMonitor progress = SubMonitor.convert(monitor,
-                    String.format("Parsing SDK %1$s", mAndroidTarget.getName()),
-                    14);
-
-            AndroidTargetData targetData = new AndroidTargetData(mAndroidTarget);
-
-            // load DX.
-            DexWrapper dexWrapper = new DexWrapper();
-            IStatus res = dexWrapper.loadDex(mAndroidTarget.getPath(IAndroidTarget.DX_JAR));
-            if (res != Status.OK_STATUS) {
-                return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                        String.format("dx.jar loading failed for target '%1$s'",
-                                mAndroidTarget.getFullName()));
-            }
-
-            // we have loaded dx.
-            targetData.setDexWrapper(dexWrapper);
-            progress.worked(1);
-
-            // parse the rest of the data.
-
-            AndroidJarLoader classLoader =
-                new AndroidJarLoader(mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR));
-
-            preload(classLoader, progress.newChild(40, SubMonitor.SUPPRESS_NONE));
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            // get the resource Ids.
-            progress.subTask("Resource IDs");
-            IResourceRepository frameworkRepository = collectResourceIds(classLoader);
-            progress.worked(1);
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            // get the permissions
-            progress.subTask("Permissions");
-            String[] permissionValues = collectPermissions(classLoader);
-            progress.worked(1);
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            // get the action and category values for the Intents.
-            progress.subTask("Intents");
-            ArrayList<String> activity_actions = new ArrayList<String>();
-            ArrayList<String> broadcast_actions = new ArrayList<String>();
-            ArrayList<String> service_actions = new ArrayList<String>();
-            ArrayList<String> categories = new ArrayList<String>();
-            collectIntentFilterActionsAndCategories(activity_actions, broadcast_actions,
-                    service_actions, categories);
-            progress.worked(1);
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            // gather the attribute definition
-            progress.subTask("Attributes definitions");
-            AttrsXmlParser attrsXmlParser = new AttrsXmlParser(
-                    mAndroidTarget.getPath(IAndroidTarget.ATTRIBUTES));
-            attrsXmlParser.preload();
-            progress.worked(1);
-
-            progress.subTask("Manifest definitions");
-            AttrsXmlParser attrsManifestXmlParser = new AttrsXmlParser(
-                    mAndroidTarget.getPath(IAndroidTarget.MANIFEST_ATTRIBUTES),
-                    attrsXmlParser);
-            attrsManifestXmlParser.preload();
-            progress.worked(1);
-
-            Collection<ViewClassInfo> mainList = new ArrayList<ViewClassInfo>();
-            Collection<ViewClassInfo> groupList = new ArrayList<ViewClassInfo>();
-
-            // collect the layout/widgets classes
-            progress.subTask("Widgets and layouts");
-            collectLayoutClasses(classLoader, attrsXmlParser, mainList, groupList,
-                    progress.newChild(1));
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            ViewClassInfo[] layoutViewsInfo = mainList.toArray(new ViewClassInfo[mainList.size()]);
-            ViewClassInfo[] layoutGroupsInfo = groupList.toArray(
-                    new ViewClassInfo[groupList.size()]);
-
-            // collect the preferences classes.
-            mainList.clear();
-            groupList.clear();
-            collectPreferenceClasses(classLoader, attrsXmlParser, mainList, groupList,
-                    progress.newChild(1));
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            ViewClassInfo[] preferencesInfo = mainList.toArray(new ViewClassInfo[mainList.size()]);
-            ViewClassInfo[] preferenceGroupsInfo = groupList.toArray(
-                    new ViewClassInfo[groupList.size()]);
-
-            Map<String, DeclareStyleableInfo> xmlMenuMap = collectMenuDefinitions(attrsXmlParser);
-            Map<String, DeclareStyleableInfo> xmlSearchableMap = collectSearchableDefinitions(
-                    attrsXmlParser);
-            Map<String, DeclareStyleableInfo> manifestMap = collectManifestDefinitions(
-                                                                            attrsManifestXmlParser);
-            Map<String, Map<String, Integer>> enumValueMap = attrsXmlParser.getEnumFlagValues();
-
-            Map<String, DeclareStyleableInfo> xmlAppWidgetMap = null;
-            if (mAndroidTarget.getVersion().getApiLevel() >= 3) {
-                xmlAppWidgetMap = collectAppWidgetDefinitions(attrsXmlParser);
-            }
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            // From the information that was collected, create the pieces that will be put in
-            // the PlatformData object.
-            AndroidManifestDescriptors manifestDescriptors = new AndroidManifestDescriptors();
-            manifestDescriptors.updateDescriptors(manifestMap);
-            progress.worked(1);
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            LayoutDescriptors layoutDescriptors = new LayoutDescriptors();
-            layoutDescriptors.updateDescriptors(layoutViewsInfo, layoutGroupsInfo);
-            progress.worked(1);
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            MenuDescriptors menuDescriptors = new MenuDescriptors();
-            menuDescriptors.updateDescriptors(xmlMenuMap);
-            progress.worked(1);
-
-            if (progress.isCanceled()) {
-                return Status.CANCEL_STATUS;
-            }
-
-            XmlDescriptors xmlDescriptors = new XmlDescriptors();
-            xmlDescriptors.updateDescriptors(
-                    xmlSearchableMap,
-                    xmlAppWidgetMap,
-                    preferencesInfo,
-                    preferenceGroupsInfo);
-            progress.worked(1);
-
-            // load the framework resources.
-            ProjectResources resources = ResourceManager.getInstance().loadFrameworkResources(
-                    mAndroidTarget);
-            progress.worked(1);
-
-            // now load the layout lib bridge
-            LayoutBridge layoutBridge = loadLayoutBridge();
-            progress.worked(1);
-
-            // and finally create the PlatformData with all that we loaded.
-            targetData.setExtraData(frameworkRepository,
-                    manifestDescriptors,
-                    layoutDescriptors,
-                    menuDescriptors,
-                    xmlDescriptors,
-                    enumValueMap,
-                    permissionValues,
-                    activity_actions.toArray(new String[activity_actions.size()]),
-                    broadcast_actions.toArray(new String[broadcast_actions.size()]),
-                    service_actions.toArray(new String[service_actions.size()]),
-                    categories.toArray(new String[categories.size()]),
-                    mAndroidTarget.getPlatformLibraries(),
-                    mAndroidTarget.getOptionalLibraries(),
-                    resources,
-                    layoutBridge);
-
-            Sdk.getCurrent().setTargetData(mAndroidTarget, targetData);
-
-            return Status.OK_STATUS;
-        } catch (Exception e) {
-            AdtPlugin.logAndPrintError(e, TAG, "SDK parser failed"); //$NON-NLS-1$
-            AdtPlugin.printToConsole("SDK parser failed", e.getMessage());
-            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "SDK parser failed", e);
-        }
-    }
-
-    /**
-     * Preloads all "interesting" classes from the framework SDK jar.
-     * <p/>
-     * Currently this preloads all classes from the framework jar
-     *
-     * @param classLoader The framework SDK jar classloader
-     * @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
-     */
-    private void preload(AndroidJarLoader classLoader, IProgressMonitor monitor) {
-        try {
-            classLoader.preLoadClasses("" /* all classes */,        //$NON-NLS-1$
-                    mAndroidTarget.getName(),                       // monitor task label
-                    monitor);
-        } catch (InvalidAttributeValueException e) {
-            AdtPlugin.log(e, "Problem preloading classes"); //$NON-NLS-1$
-        } catch (IOException e) {
-            AdtPlugin.log(e, "Problem preloading classes"); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Creates an IResourceRepository for the framework resources.
-     *
-     * @param classLoader The framework SDK jar classloader
-     * @return a map of the resources, or null if it failed.
-     */
-    private IResourceRepository collectResourceIds(
-            AndroidJarLoader classLoader) {
-        try {
-            Class<?> r = classLoader.loadClass(AndroidConstants.CLASS_R);
-
-            if (r != null) {
-                Map<ResourceType, List<ResourceItem>> map = parseRClass(r);
-                if (map != null) {
-                    return new FrameworkResourceRepository(map);
-                }
-            }
-        } catch (ClassNotFoundException e) {
-            AdtPlugin.logAndPrintError(e, TAG,
-                    "Collect resource IDs failed, class %1$s not found in %2$s", //$NON-NLS-1$
-                    AndroidConstants.CLASS_R,
-                    mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR));
-        }
-
-        return null;
-    }
-
-    /**
-     * Parse the R class and build the resource map.
-     *
-     * @param rClass the Class object representing the Resources.
-     * @return a map of the resource or null
-     */
-    private Map<ResourceType, List<ResourceItem>> parseRClass(Class<?> rClass) {
-        // get the sub classes.
-        Class<?>[] classes = rClass.getClasses();
-
-        if (classes.length > 0) {
-            HashMap<ResourceType, List<ResourceItem>> map =
-                new HashMap<ResourceType, List<ResourceItem>>();
-
-            // get the fields of each class.
-            for (int c = 0 ; c < classes.length ; c++) {
-                Class<?> subClass = classes[c];
-                String name = subClass.getSimpleName();
-
-                // get the matching ResourceType
-                ResourceType type = ResourceType.getEnum(name);
-                if (type != null) {
-                    List<ResourceItem> list = new ArrayList<ResourceItem>();
-                    map.put(type, list);
-
-                    Field[] fields = subClass.getFields();
-
-                    for (Field f : fields) {
-                        list.add(new ResourceItem(f.getName()));
-                    }
-                }
-            }
-
-            return map;
-        }
-
-        return null;
-    }
-
-    /**
-     * Loads, collects and returns the list of default permissions from the framework.
-     *
-     * @param classLoader The framework SDK jar classloader
-     * @return a non null (but possibly empty) array containing the permission values.
-     */
-    private String[] collectPermissions(AndroidJarLoader classLoader) {
-        try {
-            Class<?> permissionClass =
-                classLoader.loadClass(AndroidConstants.CLASS_MANIFEST_PERMISSION);
-
-            if (permissionClass != null) {
-                ArrayList<String> list = new ArrayList<String>();
-
-                Field[] fields = permissionClass.getFields();
-
-                for (Field f : fields) {
-                    int modifiers = f.getModifiers();
-                    if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers) &&
-                            Modifier.isPublic(modifiers)) {
-                        try {
-                            Object value = f.get(null);
-                            if (value instanceof String) {
-                                list.add((String)value);
-                            }
-                        } catch (IllegalArgumentException e) {
-                            // since we provide null this should not happen
-                        } catch (IllegalAccessException e) {
-                            // if the field is inaccessible we ignore it.
-                        } catch (NullPointerException npe) {
-                            // looks like this is not a static field. we can ignore.
-                        } catch (ExceptionInInitializerError  eiie) {
-                            // lets just ignore the field again
-                        }
-                    }
-                }
-
-                return list.toArray(new String[list.size()]);
-            }
-        } catch (ClassNotFoundException e) {
-            AdtPlugin.logAndPrintError(e, TAG,
-                    "Collect permissions failed, class %1$s not found in %2$s", //$NON-NLS-1$
-                    AndroidConstants.CLASS_MANIFEST_PERMISSION,
-                    mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR));
-        }
-
-        return new String[0];
-    }
-
-    /**
-     * Loads and collects the action and category default values from the framework.
-     * The values are added to the <code>actions</code> and <code>categories</code> lists.
-     *
-     * @param activityActions the list which will receive the activity action values.
-     * @param broadcastActions the list which will receive the broadcast action values.
-     * @param serviceActions the list which will receive the service action values.
-     * @param categories the list which will receive the category values.
-     */
-    private void collectIntentFilterActionsAndCategories(ArrayList<String> activityActions,
-            ArrayList<String> broadcastActions,
-            ArrayList<String> serviceActions, ArrayList<String> categories)  {
-        collectValues(mAndroidTarget.getPath(IAndroidTarget.ACTIONS_ACTIVITY),
-                activityActions);
-        collectValues(mAndroidTarget.getPath(IAndroidTarget.ACTIONS_BROADCAST),
-                broadcastActions);
-        collectValues(mAndroidTarget.getPath(IAndroidTarget.ACTIONS_SERVICE),
-                serviceActions);
-        collectValues(mAndroidTarget.getPath(IAndroidTarget.CATEGORIES),
-                categories);
-    }
-
-    /**
-     * Collects values from a text file located in the SDK
-     * @param osFilePath The path to the text file.
-     * @param values the {@link ArrayList} to fill with the values.
-     */
-    private void collectValues(String osFilePath, ArrayList<String> values) {
-        FileReader fr = null;
-        BufferedReader reader = null;
-        try {
-            fr = new FileReader(osFilePath);
-            reader = new BufferedReader(fr);
-
-            String line;
-            while ((line = reader.readLine()) != null) {
-                line = line.trim();
-                if (line.length() > 0 && line.startsWith("#") == false) { //$NON-NLS-1$
-                    values.add(line);
-                }
-            }
-        } catch (IOException e) {
-            AdtPlugin.log(e, "Failed to read SDK values"); //$NON-NLS-1$
-        } finally {
-            try {
-                if (reader != null) {
-                    reader.close();
-                }
-            } catch (IOException e) {
-                AdtPlugin.log(e, "Failed to read SDK values"); //$NON-NLS-1$
-            }
-
-            try {
-                if (fr != null) {
-                    fr.close();
-                }
-            } catch (IOException e) {
-                AdtPlugin.log(e, "Failed to read SDK values"); //$NON-NLS-1$
-            }
-        }
-    }
-
-    /**
-     * Collects all layout classes information from the class loader and the
-     * attrs.xml and sets the corresponding structures in the resource manager.
-     *
-     * @param classLoader The framework SDK jar classloader in case we cannot get the widget from
-     * the platform directly
-     * @param attrsXmlParser The parser of the attrs.xml file
-     * @param mainList the Collection to receive the main list of {@link ViewClassInfo}.
-     * @param groupList the Collection to receive the group list of {@link ViewClassInfo}.
-     * @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
-     */
-    private void collectLayoutClasses(AndroidJarLoader classLoader,
-            AttrsXmlParser attrsXmlParser,
-            Collection<ViewClassInfo> mainList, Collection<ViewClassInfo> groupList,
-            IProgressMonitor monitor) {
-        LayoutParamsParser ldp = null;
-        try {
-            WidgetClassLoader loader = new WidgetClassLoader(
-                    mAndroidTarget.getPath(IAndroidTarget.WIDGETS));
-            if (loader.parseWidgetList(monitor)) {
-                ldp = new LayoutParamsParser(loader, attrsXmlParser);
-            }
-            // if the parsing failed, we'll use the old loader below.
-        } catch (FileNotFoundException e) {
-            AdtPlugin.log(e, "Android Framework Parser"); //$NON-NLS-1$
-            // the file does not exist, we'll use the old loader below.
-        }
-
-        if (ldp == null) {
-            ldp = new LayoutParamsParser(classLoader, attrsXmlParser);
-        }
-        ldp.parseLayoutClasses(monitor);
-
-        List<ViewClassInfo> views = ldp.getViews();
-        List<ViewClassInfo> groups = ldp.getGroups();
-
-        if (views != null && groups != null) {
-            mainList.addAll(views);
-            groupList.addAll(groups);
-        }
-    }
-
-    /**
-     * Collects all preferences definition information from the attrs.xml and
-     * sets the corresponding structures in the resource manager.
-     *
-     * @param classLoader The framework SDK jar classloader
-     * @param attrsXmlParser The parser of the attrs.xml file
-     * @param mainList the Collection to receive the main list of {@link ViewClassInfo}.
-     * @param groupList the Collection to receive the group list of {@link ViewClassInfo}.
-     * @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
-     */
-    private void collectPreferenceClasses(AndroidJarLoader classLoader,
-            AttrsXmlParser attrsXmlParser, Collection<ViewClassInfo> mainList,
-            Collection<ViewClassInfo> groupList, IProgressMonitor monitor) {
-        LayoutParamsParser ldp = new LayoutParamsParser(classLoader, attrsXmlParser);
-
-        try {
-            ldp.parsePreferencesClasses(monitor);
-
-            List<ViewClassInfo> prefs = ldp.getViews();
-            List<ViewClassInfo> groups = ldp.getGroups();
-
-            if (prefs != null && groups != null) {
-                mainList.addAll(prefs);
-                groupList.addAll(groups);
-            }
-        } catch (NoClassDefFoundError e) {
-            AdtPlugin.logAndPrintError(e, TAG,
-                    "Collect preferences failed, class %1$s not found in %2$s",
-                    e.getMessage(),
-                    classLoader.getSource());
-        } catch (Throwable e) {
-            AdtPlugin.log(e, "Android Framework Parser: failed to collect preference classes"); //$NON-NLS-1$
-            AdtPlugin.printErrorToConsole("Android Framework Parser",
-                    "failed to collect preference classes");
-        }
-    }
-
-    /**
-     * Collects all menu definition information from the attrs.xml and returns it.
-     *
-     * @param attrsXmlParser The parser of the attrs.xml file
-     */
-    private Map<String, DeclareStyleableInfo> collectMenuDefinitions(
-            AttrsXmlParser attrsXmlParser) {
-        Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
-        Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
-        for (String key : new String[] { "Menu",        //$NON-NLS-1$
-                                         "MenuItem",        //$NON-NLS-1$
-                                         "MenuGroup" }) {   //$NON-NLS-1$
-            if (map.containsKey(key)) {
-                map2.put(key, map.get(key));
-            } else {
-                AdtPlugin.log(IStatus.WARNING,
-                        "Menu declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
-                        key, attrsXmlParser.getOsAttrsXmlPath());
-                AdtPlugin.printErrorToConsole("Android Framework Parser",
-                        String.format("Menu declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
-                        key, attrsXmlParser.getOsAttrsXmlPath()));
-            }
-        }
-
-        return Collections.unmodifiableMap(map2);
-    }
-
-    /**
-     * Collects all searchable definition information from the attrs.xml and returns it.
-     *
-     * @param attrsXmlParser The parser of the attrs.xml file
-     */
-    private Map<String, DeclareStyleableInfo> collectSearchableDefinitions(
-            AttrsXmlParser attrsXmlParser) {
-        Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
-        Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
-        for (String key : new String[] { "Searchable",              //$NON-NLS-1$
-                                         "SearchableActionKey" }) { //$NON-NLS-1$
-            if (map.containsKey(key)) {
-                map2.put(key, map.get(key));
-            } else {
-                AdtPlugin.log(IStatus.WARNING,
-                        "Searchable declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
-                        key, attrsXmlParser.getOsAttrsXmlPath());
-                AdtPlugin.printErrorToConsole("Android Framework Parser",
-                        String.format("Searchable declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
-                        key, attrsXmlParser.getOsAttrsXmlPath()));
-            }
-        }
-
-        return Collections.unmodifiableMap(map2);
-    }
-
-    /**
-     * Collects all appWidgetProviderInfo definition information from the attrs.xml and returns it.
-     *
-     * @param attrsXmlParser The parser of the attrs.xml file
-     */
-    private Map<String, DeclareStyleableInfo> collectAppWidgetDefinitions(
-            AttrsXmlParser attrsXmlParser) {
-        Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
-        Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
-        for (String key : new String[] { "AppWidgetProviderInfo" }) {  //$NON-NLS-1$
-            if (map.containsKey(key)) {
-                map2.put(key, map.get(key));
-            } else {
-                AdtPlugin.log(IStatus.WARNING,
-                        "AppWidget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
-                        key, attrsXmlParser.getOsAttrsXmlPath());
-                AdtPlugin.printErrorToConsole("Android Framework Parser",
-                        String.format("AppWidget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
-                        key, attrsXmlParser.getOsAttrsXmlPath()));
-            }
-        }
-
-        return Collections.unmodifiableMap(map2);
-    }
-
-    /**
-     * Collects all manifest definition information from the attrs_manifest.xml and returns it.
-     */
-    private Map<String, DeclareStyleableInfo> collectManifestDefinitions(
-            AttrsXmlParser attrsXmlParser) {
-
-        return attrsXmlParser.getDeclareStyleableList();
-    }
-
-    /**
-     * Loads the layout bridge from the dynamically loaded layoutlib.jar
-     */
-    private LayoutBridge loadLayoutBridge() {
-        LayoutBridge layoutBridge = new LayoutBridge();
-
-        try {
-            // get the URL for the file.
-            File f = new File(mAndroidTarget.getPath(IAndroidTarget.LAYOUT_LIB));
-            if (f.isFile() == false) {
-                AdtPlugin.log(IStatus.ERROR, "layoutlib.jar is missing!"); //$NON-NLS-1$
-            } else {
-                URL url = f.toURL();
-
-                // create a class loader. Because this jar reference interfaces
-                // that are in the editors plugin, it's important to provide
-                // a parent class loader.
-                layoutBridge.classLoader = new URLClassLoader(new URL[] { url },
-                        this.getClass().getClassLoader());
-
-                // load the class
-                Class<?> clazz = layoutBridge.classLoader.loadClass(AndroidConstants.CLASS_BRIDGE);
-                if (clazz != null) {
-                    // instantiate an object of the class.
-                    Constructor<?> constructor = clazz.getConstructor();
-                    if (constructor != null) {
-                        Object bridge = constructor.newInstance();
-                        if (bridge instanceof ILayoutBridge) {
-                            layoutBridge.bridge = (ILayoutBridge)bridge;
-                        }
-                    }
-                }
-
-                if (layoutBridge.bridge == null) {
-                    layoutBridge.status = LoadStatus.FAILED;
-                    AdtPlugin.log(IStatus.ERROR, "Failed to load " + AndroidConstants.CLASS_BRIDGE); //$NON-NLS-1$
-                } else {
-                    // get the api level
-                    try {
-                        layoutBridge.apiLevel = layoutBridge.bridge.getApiLevel();
-                    } catch (AbstractMethodError e) {
-                        // the first version of the api did not have this method
-                        layoutBridge.apiLevel = 1;
-                    }
-
-                    // and mark the lib as loaded.
-                    layoutBridge.status = LoadStatus.LOADED;
-                }
-            }
-        } catch (Throwable t) {
-            layoutBridge.status = LoadStatus.FAILED;
-            // log the error.
-            AdtPlugin.log(t, "Failed to load the LayoutLib");
-        }
-
-        return layoutBridge;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/DexWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/DexWrapper.java
deleted file mode 100644
index 9981b14..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/DexWrapper.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.Messages;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-/**
- * Wrapper to access dex.jar through reflection.
- * <p/>Since there is no proper api to call the method in the dex library, this wrapper is going
- * to access it through reflection.
- */
-public final class DexWrapper {
-    
-    private final static String DEX_MAIN = "com.android.dx.command.dexer.Main"; //$NON-NLS-1$
-    private final static String DEX_CONSOLE = "com.android.dx.command.DxConsole"; //$NON-NLS-1$
-    private final static String DEX_ARGS = "com.android.dx.command.dexer.Main$Arguments"; //$NON-NLS-1$
-    
-    private final static String MAIN_RUN = "run"; //$NON-NLS-1$
-    
-    private Method mRunMethod;
-
-    private Constructor<?> mArgConstructor;
-    private Field mArgOutName;
-    private Field mArgVerbose;
-    private Field mArgJarOutput;
-    private Field mArgFileNames;
-
-    private Field mConsoleOut;
-    private Field mConsoleErr;
-    
-    /**
-     * Loads the dex library from a file path.
-     * 
-     * The loaded library can be used via
-     * {@link DexWrapper#run(String, String[], boolean, PrintStream, PrintStream)}.
-     * 
-     * @param osFilepath the location of the dex.jar file.
-     * @return an IStatus indicating the result of the load.
-     */
-    public synchronized IStatus loadDex(String osFilepath) {
-        try {
-            File f = new File(osFilepath);
-            if (f.isFile() == false) {
-                return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, String.format(
-                        Messages.DexWrapper_s_does_not_exists, osFilepath));
-            }
-            URL url = f.toURL();
-    
-            URLClassLoader loader = new URLClassLoader(new URL[] { url },
-                    DexWrapper.class.getClassLoader());
-            
-            // get the classes.
-            Class<?> mainClass = loader.loadClass(DEX_MAIN);
-            Class<?> consoleClass = loader.loadClass(DEX_CONSOLE);
-            Class<?> argClass = loader.loadClass(DEX_ARGS);
-            
-            try {
-                // now get the fields/methods we need
-                mRunMethod = mainClass.getMethod(MAIN_RUN, argClass);
-                
-                mArgConstructor = argClass.getConstructor();
-                mArgOutName = argClass.getField("outName"); //$NON-NLS-1$
-                mArgJarOutput = argClass.getField("jarOutput"); //$NON-NLS-1$
-                mArgFileNames = argClass.getField("fileNames"); //$NON-NLS-1$
-                mArgVerbose = argClass.getField("verbose"); //$NON-NLS-1$
-                
-                mConsoleOut = consoleClass.getField("out"); //$NON-NLS-1$
-                mConsoleErr = consoleClass.getField("err"); //$NON-NLS-1$
-                
-            } catch (SecurityException e) {
-                return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_API, e);
-            } catch (NoSuchMethodException e) {
-                return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_Method, e);
-            } catch (NoSuchFieldException e) {
-                return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_Field, e);
-            }
-
-            return Status.OK_STATUS;
-        } catch (MalformedURLException e) {
-            // really this should not happen.
-            return createErrorStatus(
-                    String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
-        } catch (ClassNotFoundException e) {
-            return createErrorStatus(
-                    String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
-        }
-    }
-    
-    /**
-     * Runs the dex command.
-     * @param osOutFilePath the OS path to the outputfile (classes.dex
-     * @param osFilenames list of input source files (.class and .jar files)
-     * @param verbose verbose mode.
-     * @param outStream the stdout console
-     * @param errStream the stderr console
-     * @return the integer return code of com.android.dx.command.dexer.Main.run()
-     * @throws CoreException
-     */
-    public synchronized int run(String osOutFilePath, String[] osFilenames,
-            boolean verbose, PrintStream outStream, PrintStream errStream) throws CoreException {
-        
-        try {
-            // set the stream
-            mConsoleErr.set(null /* obj: static field */, errStream);
-            mConsoleOut.set(null /* obj: static field */, outStream);
-            
-            // create the Arguments object.
-            Object args = mArgConstructor.newInstance();
-            mArgOutName.set(args, osOutFilePath);
-            mArgFileNames.set(args, osFilenames);
-            mArgJarOutput.set(args, false);
-            mArgVerbose.set(args, verbose);
-            
-            // call the run method
-            Object res = mRunMethod.invoke(null /* obj: static method */, args);
-            
-            if (res instanceof Integer) {
-                return ((Integer)res).intValue();
-            }
-        
-            return -1;
-        } catch (IllegalAccessException e) {
-            throw new CoreException(createErrorStatus(
-                    String.format(Messages.DexWrapper_Unable_To_Execute_Dex_s, e.getMessage()), e));
-        } catch (InstantiationException e) {
-            throw new CoreException(createErrorStatus(
-                    String.format(Messages.DexWrapper_Unable_To_Execute_Dex_s, e.getMessage()), e));
-        } catch (InvocationTargetException e) {
-            throw new CoreException(createErrorStatus(
-                    String.format(Messages.DexWrapper_Unable_To_Execute_Dex_s, e.getMessage()), e));
-        }
-    }
-    
-    private static IStatus createErrorStatus(String message, Exception e) {
-        AdtPlugin.log(e, message);
-        AdtPlugin.printErrorToConsole(Messages.DexWrapper_Dex_Loader, message);
-        
-        return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, message, e);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/FrameworkResourceRepository.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/FrameworkResourceRepository.java
deleted file mode 100644
index 91b0082..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/FrameworkResourceRepository.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Implementation of the {@link IResourceRepository} interface to hold the system resource Ids
- * parsed by {@link AndroidTargetParser}. 
- */
-final class FrameworkResourceRepository implements IResourceRepository {
-    
-    private Map<ResourceType, List<ResourceItem>> mResourcesMap; 
-    
-    public FrameworkResourceRepository(Map<ResourceType, List<ResourceItem>> systemResourcesMap) {
-        mResourcesMap = systemResourcesMap;
-    }
-
-    public ResourceType[] getAvailableResourceTypes() {
-        if (mResourcesMap != null) {
-            Set<ResourceType> types = mResourcesMap.keySet();
-
-            if (types != null) {
-                return types.toArray(new ResourceType[types.size()]);
-            }
-        }
-
-        return null;
-    }
-
-    public ResourceItem[] getResources(ResourceType type) {
-        if (mResourcesMap != null) {
-            List<ResourceItem> items = mResourcesMap.get(type);
-
-            if (items != null) {
-                return items.toArray(new ResourceItem[items.size()]);
-            }
-        }
-
-        return null;
-    }
-
-    public boolean hasResources(ResourceType type) {
-        if (mResourcesMap != null) {
-            List<ResourceItem> items = mResourcesMap.get(type);
-
-            return (items != null && items.size() > 0);
-        }
-
-        return false;
-    }
-
-    public boolean isSystemRepository() {
-        return true;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/IAndroidClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/IAndroidClassLoader.java
deleted file mode 100644
index c1cd3a3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/IAndroidClassLoader.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import javax.management.InvalidAttributeValueException;
-
-/**
- * Classes which implements this interface provide methods to access framework resource
- * data loaded from the SDK.
- */
-public interface IAndroidClassLoader {
-    
-    /**
-     * Classes which implement this interface provide methods to describe a class.
-     */
-    public interface IClassDescriptor {
-
-        String getCanonicalName();
-
-        IClassDescriptor getSuperclass();
-
-        String getSimpleName();
-
-        IClassDescriptor getEnclosingClass();
-
-        IClassDescriptor[] getDeclaredClasses();
-        
-        boolean isInstantiable();
-    }
-
-    /**
-     * Finds and loads all classes that derive from a given set of super classes.
-     * 
-     * @param rootPackage Root package of classes to find. Use an empty string to find everyting.
-     * @param superClasses The super classes of all the classes to find. 
-     * @return An hash map which keys are the super classes looked for and which values are
-     *         ArrayList of the classes found. The array lists are always created for all the
-     *         valid keys, they are simply empty if no deriving class is found for a given
-     *         super class. 
-     * @throws IOException
-     * @throws InvalidAttributeValueException
-     * @throws ClassFormatError
-     */
-    public HashMap<String, ArrayList<IClassDescriptor>> findClassesDerivingFrom(
-            String rootPackage, String[] superClasses)
-        throws IOException, InvalidAttributeValueException, ClassFormatError;
-
-    /**
-     * Returns a {@link IClassDescriptor} by its fully-qualified name.
-     * @param className the fully-qualified name of the class to return.
-     * @throws ClassNotFoundException
-     */
-    public IClassDescriptor getClass(String className) throws ClassNotFoundException;
-
-    /**
-     * Returns a string indicating the source of the classes, typically for debugging
-     * or in error messages. This would typically be a JAR file name or some kind of
-     * identifier that would mean something to the user when looking at error messages.
-     * 
-     * @return An informal string representing the source of the classes.
-     */
-    public String getSource();
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java
deleted file mode 100644
index 9e80103..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Class representing a layout device.
- *
- * A Layout device is a collection of {@link FolderConfiguration} that can be used to render Android
- * layout files.
- *
- * It also contains a single xdpi/ydpi that is independent of the {@link FolderConfiguration}.
- *
- * If the device is meant to represent a true device, then most of the FolderConfigurations' content
- * should be identical, with only a few qualifiers (orientation, keyboard state) that would differ.
- * However it is simpler to reuse the FolderConfiguration class (with the non changing qualifiers
- * duplicated in each configuration) as it's what's being used by the rendering library.
- *
- * To create, edit and delete LayoutDevice objects, see {@link LayoutDeviceManager}.
- * The class is not technically immutable but behaves as such outside of its package.
- */
-public class LayoutDevice {
-
-    private final String mName;
-
-    /** editable map of the config */
-    private Map<String, FolderConfiguration> mEditMap = new HashMap<String, FolderConfiguration>();
-    /** unmodifiable map returned by {@link #getConfigs()}. */
-    private Map<String, FolderConfiguration> mMap;
-    private float mXDpi = Float.NaN;
-    private float mYDpi = Float.NaN;
-
-    LayoutDevice(String name) {
-        mName = name;
-    }
-
-    /**
-     * Saves the Layout Device into a document under a given node
-     * @param doc the document.
-     * @param parentNode the parent node.
-     */
-    void saveTo(Document doc, Element parentNode) {
-        // create the device node
-        Element deviceNode = createNode(doc, parentNode, LayoutDevicesXsd.NODE_DEVICE);
-
-        // create the name attribute (no namespace on this one).
-        deviceNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, mName);
-
-        // create a default with the x/y dpi
-        Element defaultNode = createNode(doc, deviceNode, LayoutDevicesXsd.NODE_DEFAULT);
-        if (Float.isNaN(mXDpi) == false) {
-            Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_XDPI);
-            xdpiNode.setTextContent(Float.toString(mXDpi));
-        }
-        if (Float.isNaN(mYDpi) == false) {
-            Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_YDPI);
-            xdpiNode.setTextContent(Float.toString(mYDpi));
-        }
-
-        // then save all the configs.
-        for (Entry<String, FolderConfiguration> entry : mEditMap.entrySet()) {
-            saveConfigTo(doc, deviceNode, entry.getKey(), entry.getValue());
-        }
-    }
-
-    /**
-     * Creates and returns a new NS-enabled node.
-     * @param doc the {@link Document}
-     * @param parentNode the parent node. The new node is appended to this one as a child.
-     * @param name the name of the node.
-     * @return the newly created node.
-     */
-    private Element createNode(Document doc, Element parentNode, String name) {
-        Element newNode = doc.createElementNS(
-                LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD, name);
-        newNode.setPrefix(doc.lookupPrefix(LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD));
-        parentNode.appendChild(newNode);
-
-        return newNode;
-    }
-
-    /**
-     * Saves a {@link FolderConfiguration} in a {@link Document}.
-     * @param doc the Document in which to save
-     * @param parent the parent node
-     * @param configName the name of the config
-     * @param config the config to save
-     */
-    private void saveConfigTo(Document doc, Element parent, String configName,
-            FolderConfiguration config) {
-        Element configNode = createNode(doc, parent, LayoutDevicesXsd.NODE_CONFIG);
-
-        // create the name attribute (no namespace on this one).
-        configNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, configName);
-
-        // now do the qualifiers
-        CountryCodeQualifier ccq = config.getCountryCodeQualifier();
-        if (ccq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_COUNTRY_CODE);
-            node.setTextContent(Integer.toString(ccq.getCode()));
-        }
-
-        NetworkCodeQualifier ncq = config.getNetworkCodeQualifier();
-        if (ncq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NETWORK_CODE);
-            node.setTextContent(Integer.toString(ncq.getCode()));
-        }
-
-        ScreenSizeQualifier ssq = config.getScreenSizeQualifier();
-        if (ssq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_SIZE);
-            node.setTextContent(ssq.getFolderSegment(null));
-        }
-
-        ScreenRatioQualifier srq = config.getScreenRatioQualifier();
-        if (srq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_RATIO);
-            node.setTextContent(srq.getFolderSegment(null));
-        }
-
-        ScreenOrientationQualifier soq = config.getScreenOrientationQualifier();
-        if (soq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_ORIENTATION);
-            node.setTextContent(soq.getFolderSegment(null));
-        }
-
-        PixelDensityQualifier pdq = config.getPixelDensityQualifier();
-        if (pdq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_PIXEL_DENSITY);
-            node.setTextContent(pdq.getFolderSegment(null));
-        }
-
-        TouchScreenQualifier ttq = config.getTouchTypeQualifier();
-        if (ttq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TOUCH_TYPE);
-            node.setTextContent(ttq.getFolderSegment(null));
-        }
-
-        KeyboardStateQualifier ksq = config.getKeyboardStateQualifier();
-        if (ksq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_KEYBOARD_STATE);
-            node.setTextContent(ksq.getFolderSegment(null));
-        }
-
-        TextInputMethodQualifier timq = config.getTextInputMethodQualifier();
-        if (timq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD);
-            node.setTextContent(timq.getFolderSegment(null));
-        }
-
-        NavigationMethodQualifier nmq = config.getNavigationMethodQualifier();
-        if (nmq != null) {
-            Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NAV_METHOD);
-            node.setTextContent(nmq.getFolderSegment(null));
-        }
-
-        ScreenDimensionQualifier sdq = config.getScreenDimensionQualifier();
-        if (sdq != null) {
-            Element sizeNode = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_DIMENSION);
-
-            Element node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE);
-            node.setTextContent(Integer.toString(sdq.getValue1()));
-
-            node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE);
-            node.setTextContent(Integer.toString(sdq.getValue2()));
-        }
-    }
-
-    void addConfig(String name, FolderConfiguration config) {
-        mEditMap.put(name, config);
-        _seal();
-    }
-
-    void addConfigs(Map<String, FolderConfiguration> configs) {
-        mEditMap.putAll(configs);
-        _seal();
-    }
-
-    void removeConfig(String name) {
-        mEditMap.remove(name);
-        _seal();
-    }
-
-    /**
-     * Adds config to the LayoutDevice. This is to be used to add plenty of configurations.
-     * It must be followed by {@link #_seal()}.
-     * @param name the name of the config
-     * @param config the config.
-     */
-    void _addConfig(String name, FolderConfiguration config) {
-        mEditMap.put(name, config);
-    }
-
-    void _seal() {
-        mMap = Collections.unmodifiableMap(mEditMap);
-    }
-
-    void setXDpi(float xdpi) {
-        mXDpi = xdpi;
-    }
-
-    void setYDpi(float ydpi) {
-        mYDpi = ydpi;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public Map<String, FolderConfiguration> getConfigs() {
-        return mMap;
-    }
-
-    /**
-     * Returns the dpi of the Device screen in X.
-     * @return the dpi of screen or {@link Float#NaN} if it's not set.
-     */
-    public float getXDpi() {
-        return mXDpi;
-    }
-
-    /**
-     * Returns the dpi of the Device screen in Y.
-     * @return the dpi of screen or {@link Float#NaN} if it's not set.
-     */
-    public float getYDpi() {
-        return mYDpi;
-    }
- }
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java
deleted file mode 100644
index 7ad4e5d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@link DefaultHandler} implementation to parse Layout Device XML file.
- * @see LayoutDevicesXsd
- * @see Layout-configs.xsd
- */
-class LayoutDeviceHandler extends DefaultHandler {
-    /*
-     * The handler does most of the work in startElement and endElement.
-     * In startElement, it'll create DeviceConfiguration on <device>, as well as
-     * FolderConfiguration instances on <default> and <config>.
-     * Those objects are then filled as new nodes are discovered.
-     *
-     * For the qualifier values, the qualifier is created and added to the current config
-     * on the endElement, by using the content found in characters().
-     */
-
-    private List<LayoutDevice> mDevices = new ArrayList<LayoutDevice>();
-
-    private LayoutDevice mCurrentDevice;
-    private FolderConfiguration mDefaultConfig;
-    private FolderConfiguration mCurrentConfig;
-    private final StringBuilder mStringAccumulator = new StringBuilder();
-
-    private String mSize1, mSize2;
-
-    public List<LayoutDevice> getDevices() {
-        return mDevices;
-    }
-
-    @Override
-    public void startElement(String uri, String localName, String name, Attributes attributes)
-            throws SAXException {
-        if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) {
-            // get the deviceName, will not be null since we validated the XML.
-            String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME);
-
-            // create a device and add it to the list
-            mCurrentDevice = new LayoutDevice(deviceName);
-            mDevices.add(mCurrentDevice);
-        } else if (LayoutDevicesXsd.NODE_DEFAULT.equals(localName)) {
-            // create a new default config
-            mDefaultConfig = mCurrentConfig = new FolderConfiguration();
-        } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) {
-            // create a new config
-            mCurrentConfig = new FolderConfiguration();
-
-            // init with default config if applicable
-            if (mDefaultConfig != null) {
-                mCurrentConfig.set(mDefaultConfig);
-            }
-
-            // get the name of the config
-            String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME);
-
-            // give it to the current device.
-            mCurrentDevice.addConfig(deviceName, mCurrentConfig);
-        } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) {
-            mSize1 = mSize2 = null;
-        }
-
-        mStringAccumulator.setLength(0);
-    }
-
-    @Override
-    public void characters(char[] ch, int start, int length) throws SAXException {
-        mStringAccumulator.append(ch, start, length);
-    }
-
-    @Override
-    public void endElement(String uri, String localName, String name) throws SAXException {
-        if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) {
-            mCurrentDevice = null;
-            mDefaultConfig = null;
-        } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) {
-            mCurrentConfig = null;
-        } else if (LayoutDevicesXsd.NODE_COUNTRY_CODE.equals(localName)) {
-            CountryCodeQualifier ccq = new CountryCodeQualifier(
-                    Integer.parseInt(mStringAccumulator.toString()));
-            mCurrentConfig.setCountryCodeQualifier(ccq);
-        } else if (LayoutDevicesXsd.NODE_NETWORK_CODE.equals(localName)) {
-            NetworkCodeQualifier ncq = new NetworkCodeQualifier(
-                    Integer.parseInt(mStringAccumulator.toString()));
-            mCurrentConfig.setNetworkCodeQualifier(ncq);
-        } else if (LayoutDevicesXsd.NODE_SCREEN_SIZE.equals(localName)) {
-            ScreenSizeQualifier ssq = new ScreenSizeQualifier(
-                    ScreenSize.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setScreenSizeQualifier(ssq);
-        } else if (LayoutDevicesXsd.NODE_SCREEN_RATIO.equals(localName)) {
-            ScreenRatioQualifier srq = new ScreenRatioQualifier(
-                    ScreenRatio.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setScreenRatioQualifier(srq);
-        } else if (LayoutDevicesXsd.NODE_SCREEN_ORIENTATION.equals(localName)) {
-            ScreenOrientationQualifier soq = new ScreenOrientationQualifier(
-                    ScreenOrientation.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setScreenOrientationQualifier(soq);
-        } else if (LayoutDevicesXsd.NODE_PIXEL_DENSITY.equals(localName)) {
-            PixelDensityQualifier pdq = new PixelDensityQualifier(
-                    Density.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setPixelDensityQualifier(pdq);
-        } else if (LayoutDevicesXsd.NODE_TOUCH_TYPE.equals(localName)) {
-            TouchScreenQualifier tsq = new TouchScreenQualifier(
-                    TouchScreenType.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setTouchTypeQualifier(tsq);
-        } else if (LayoutDevicesXsd.NODE_KEYBOARD_STATE.equals(localName)) {
-            KeyboardStateQualifier ksq = new KeyboardStateQualifier(
-                    KeyboardState.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setKeyboardStateQualifier(ksq);
-        } else if (LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) {
-            TextInputMethodQualifier timq = new TextInputMethodQualifier(
-                    TextInputMethod.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setTextInputMethodQualifier(timq);
-        } else if (LayoutDevicesXsd.NODE_NAV_METHOD.equals(localName)) {
-            NavigationMethodQualifier nmq = new NavigationMethodQualifier(
-                    NavigationMethod.getEnum(mStringAccumulator.toString()));
-            mCurrentConfig.setNavigationMethodQualifier(nmq);
-        } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) {
-            ScreenDimensionQualifier qual = ScreenDimensionQualifier.getQualifier(mSize1, mSize2);
-            if (qual != null) {
-                mCurrentConfig.setScreenDimensionQualifier(qual);
-            }
-        } else if (LayoutDevicesXsd.NODE_XDPI.equals(localName)) {
-            mCurrentDevice.setXDpi(Float.parseFloat(mStringAccumulator.toString()));
-        } else if (LayoutDevicesXsd.NODE_YDPI.equals(localName)) {
-            mCurrentDevice.setYDpi(Float.parseFloat(mStringAccumulator.toString()));
-        } else if (LayoutDevicesXsd.NODE_SIZE.equals(localName)) {
-            if (mSize1 == null) {
-                mSize1 = mStringAccumulator.toString();
-            } else if (mSize2 == null) {
-                mSize2 = mStringAccumulator.toString();
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java
deleted file mode 100644
index 3b19f17..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.SdkConstants;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Validator;
-
-/**
- * Manages the layout devices.
- * They can come from 3 sources: built-in, add-ons, user.
- */
-public class LayoutDeviceManager {
-
-    /**
-     * A SAX error handler that captures the errors and warnings.
-     * This allows us to capture *all* errors and just not get an exception on the first one.
-     */
-    private static class CaptureErrorHandler implements ErrorHandler {
-
-        private final String mSourceLocation;
-
-        private boolean mFoundError = false;
-
-        CaptureErrorHandler(String sourceLocation) {
-            mSourceLocation = sourceLocation;
-        }
-
-        public boolean foundError() {
-            return mFoundError;
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void error(SAXParseException ex) throws SAXException {
-            mFoundError = true;
-            AdtPlugin.log(ex, "Error validating %1$s", mSourceLocation);
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void fatalError(SAXParseException ex) throws SAXException {
-            mFoundError = true;
-            AdtPlugin.log(ex, "Error validating %1$s", mSourceLocation);
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void warning(SAXParseException ex) throws SAXException {
-            // ignore those for now.
-        }
-    }
-
-    private final SAXParserFactory mParserFactory;
-
-    private List<LayoutDevice> mDefaultLayoutDevices =
-        new ArrayList<LayoutDevice>();
-    private List<LayoutDevice> mAddOnLayoutDevices =
-        new ArrayList<LayoutDevice>();
-    private final List<LayoutDevice> mUserLayoutDevices =
-        new ArrayList<LayoutDevice>();
-    private List<LayoutDevice> mLayoutDevices;
-
-    LayoutDeviceManager() {
-        mParserFactory = SAXParserFactory.newInstance();
-        mParserFactory.setNamespaceAware(true);
-    }
-
-    public List<LayoutDevice> getCombinedList() {
-        return mLayoutDevices;
-    }
-
-    public List<LayoutDevice> getDefaultLayoutDevices() {
-        return mDefaultLayoutDevices;
-    }
-
-    public List<LayoutDevice> getAddOnLayoutDevice() {
-        return mAddOnLayoutDevices;
-    }
-
-    public List<LayoutDevice> getUserLayoutDevices() {
-        return mUserLayoutDevices;
-    }
-
-    public LayoutDevice getUserLayoutDevice(String name) {
-        for (LayoutDevice d : mUserLayoutDevices) {
-            if (d.getName().equals(name)) {
-                return d;
-            }
-        }
-
-        return null;
-    }
-
-    public LayoutDevice addUserDevice(String name, float xdpi, float ydpi) {
-        LayoutDevice d = new LayoutDevice(name);
-        d.setXDpi(xdpi);
-        d.setYDpi(ydpi);
-        mUserLayoutDevices.add(d);
-        combineLayoutDevices();
-
-        return d;
-    }
-
-    public void removeUserDevice(LayoutDevice device) {
-        if (mUserLayoutDevices.remove(device)) {
-            combineLayoutDevices();
-        }
-    }
-
-    /**
-     * Replaces a device with a new one with new name and/or x/y dpi, and return the new device.
-     * If the name and dpi values are identical the given device is returned an nothing is done
-     * @param device the {@link LayoutDevice} to replace
-     * @param newName the new name.
-     * @param newXDpi the new X dpi value
-     * @param newYDpi the new Y dpi value.
-     * @return the new LayoutDevice
-     */
-    public LayoutDevice replaceUserDevice(LayoutDevice device, String newName,
-            float newXDpi, float newYDpi) {
-        if (device.getName().equals(newName) && device.getXDpi() == newXDpi &&
-                device.getYDpi() == newYDpi) {
-            return device;
-        }
-
-        // else create a new device
-        LayoutDevice newDevice = new LayoutDevice(newName);
-        newDevice.setXDpi(newXDpi);
-        newDevice.setYDpi(newYDpi);
-
-        // and get the Folderconfiguration
-        Map<String, FolderConfiguration> configs = device.getConfigs();
-        newDevice.addConfigs(configs);
-
-        // replace the old device with the new
-        mUserLayoutDevices.remove(device);
-        mUserLayoutDevices.add(newDevice);
-        combineLayoutDevices();
-
-        return newDevice;
-    }
-
-
-    /**
-     * Adds or replaces a configuration in a given {@link LayoutDevice}.
-     * @param device the device to modify
-     * @param configName the configuration name to add or replace
-     * @param config the configuration to set
-     */
-    public void addUserConfiguration(LayoutDevice device, String configName,
-            FolderConfiguration config) {
-        // check that the device does belong to the user list.
-        // the main goal is to make sure that this does not belong to the default/addon list.
-        if (mUserLayoutDevices.contains(device)) {
-            device.addConfig(configName, config);
-        }
-    }
-
-    /**
-     * Replaces a configuration in a given {@link LayoutDevice}.
-     * @param device the device to modify
-     * @param oldConfigName the name of the config to replace. If null, the new config is simply
-     * added.
-     * @param newConfigName the configuration name to add or replace
-     * @param config the configuration to set
-     */
-    public void replaceUserConfiguration(LayoutDevice device, String oldConfigName,
-            String newConfigName, FolderConfiguration config) {
-        // check that the device does belong to the user list.
-        // the main goal is to make sure that this does not belong to the default/addon list.
-        if (mUserLayoutDevices.contains(device)) {
-            // if the old and new config name are different, remove the old one
-            if (oldConfigName != null && oldConfigName.equals(newConfigName) == false) {
-                device.removeConfig(oldConfigName);
-            }
-
-            // and then add the new one
-            device.addConfig(newConfigName, config);
-        }
-    }
-
-    /**
-     * Removes a configuration from a given user {@link LayoutDevice}
-     * @param device the device to modify
-     * @param configName the name of the config to remove
-     */
-    public void removeUserConfiguration(LayoutDevice device, String configName) {
-        // check that the device does belong to the user list.
-        // the main goal is to make sure that this does not belong to the default/addon list.
-        if (mUserLayoutDevices.contains(device)) {
-            device.removeConfig(configName);
-        }
-    }
-
-    /**
-     * Saves the user-made {@link LayoutDevice}s to disk.
-     */
-    public void save() {
-        try {
-            String userFolder = AndroidLocation.getFolder();
-            File deviceXml = new File(userFolder, SdkConstants.FN_DEVICES_XML);
-            if (deviceXml.isDirectory() == false) {
-                write(deviceXml, mUserLayoutDevices);
-            }
-        } catch (AndroidLocationException e) {
-            // no user folder? simply don't save the user layout device.
-            // we could display the error, but it's likely something else did before, as
-            // nothing will work w/o it.
-            AdtPlugin.log(e, "Unable to find user directory");
-        }
-    }
-
-    /**
-     * Loads the default built-in and user created Layout Devices.
-     * @param sdkOsLocation location of the SDK.
-     */
-    void loadDefaultAndUserDevices(String sdkOsLocation) {
-        // load the default devices
-        loadDefaultLayoutDevices(sdkOsLocation);
-
-        // load the user devices;
-        try {
-            String userFolder = AndroidLocation.getFolder();
-            File deviceXml = new File(userFolder, SdkConstants.FN_DEVICES_XML);
-            if (deviceXml.isFile()) {
-                parseLayoutDevices(deviceXml, mUserLayoutDevices);
-            }
-        } catch (AndroidLocationException e) {
-            // no user folder? simply don't load the user layout device
-            AdtPlugin.log(e, "Unable to find user directory");
-        }
-    }
-
-    void parseAddOnLayoutDevice(File deviceXml) {
-        parseLayoutDevices(deviceXml, mAddOnLayoutDevices);
-    }
-
-    void sealAddonLayoutDevices() {
-        mAddOnLayoutDevices = Collections.unmodifiableList(mAddOnLayoutDevices);
-
-        combineLayoutDevices();
-    }
-
-    /**
-     * Does the actual parsing of a devices.xml file.
-     * @param deviceXml the {@link File} to load/parse. This must be an existing file.
-     * @param list the list in which to write the parsed {@link LayoutDevice}.
-     */
-    private void parseLayoutDevices(File deviceXml, List<LayoutDevice> list) {
-        // first we validate the XML
-        try {
-            Source source = new StreamSource(new FileReader(deviceXml));
-
-            CaptureErrorHandler errorHandler = new CaptureErrorHandler(deviceXml.getAbsolutePath());
-
-            Validator validator = LayoutDevicesXsd.getValidator(errorHandler);
-            validator.validate(source);
-
-            if (errorHandler.foundError() == false) {
-                // do the actual parsing
-                LayoutDeviceHandler handler = new LayoutDeviceHandler();
-
-                SAXParser parser = mParserFactory.newSAXParser();
-                parser.parse(new InputSource(new FileInputStream(deviceXml)), handler);
-
-                // get the parsed devices
-                list.addAll(handler.getDevices());
-            }
-        } catch (SAXException e) {
-            AdtPlugin.log(e, "Error parsing %1$s", deviceXml.getAbsoluteFile());
-        } catch (FileNotFoundException e) {
-            // this shouldn't happen as we check above.
-        } catch (IOException e) {
-            AdtPlugin.log(e, "Error reading %1$s", deviceXml.getAbsoluteFile());
-        } catch (ParserConfigurationException e) {
-            AdtPlugin.log(e, "Error parsing %1$s", deviceXml.getAbsoluteFile());
-        }
-    }
-
-    /**
-     * Creates some built-it layout devices.
-     */
-    private void loadDefaultLayoutDevices(String sdkOsLocation) {
-        ArrayList<LayoutDevice> list = new ArrayList<LayoutDevice>();
-        File toolsFolder = new File(sdkOsLocation, SdkConstants.OS_SDK_TOOLS_LIB_FOLDER);
-        if (toolsFolder.isDirectory()) {
-            File deviceXml = new File(toolsFolder, SdkConstants.FN_DEVICES_XML);
-            if (deviceXml.isFile()) {
-                parseLayoutDevices(deviceXml, list);
-            }
-        }
-        mDefaultLayoutDevices = Collections.unmodifiableList(list);
-    }
-
-    private void combineLayoutDevices() {
-        ArrayList<LayoutDevice> list = new ArrayList<LayoutDevice>();
-        list.addAll(mDefaultLayoutDevices);
-        list.addAll(mAddOnLayoutDevices);
-        list.addAll(mUserLayoutDevices);
-
-        mLayoutDevices = Collections.unmodifiableList(list);
-    }
-
-    /**
-     * Writes the given {@link LayoutDevice}s into the given file.
-     * @param deviceXml the file to write.
-     * @param deviceList the LayoutDevice to write into the file.
-     */
-    private void write(File deviceXml, List<LayoutDevice> deviceList) {
-        try {
-            // create a new document
-            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
-            docFactory.setNamespaceAware(true);
-            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
-            Document doc = docBuilder.newDocument();
-
-            // create a base node
-            Element baseNode = doc.createElementNS(
-                    LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD,
-                    LayoutDevicesXsd.NODE_LAYOUT_DEVICES);
-            // create the prefix for the namespace
-            baseNode.setPrefix("d");
-            doc.appendChild(baseNode);
-
-            // fill it with the layout devices.
-            for (LayoutDevice device : deviceList) {
-                device.saveTo(doc, baseNode);
-            }
-
-            // save the document to disk
-            // Prepare the DOM document for writing
-            Source source = new DOMSource(doc);
-
-            // Prepare the output file
-            File file = new File(deviceXml.getAbsolutePath());
-            Result result = new StreamResult(file);
-
-            // Write the DOM document to the file
-            Transformer xformer = TransformerFactory.newInstance().newTransformer();
-            xformer.transform(source, result);
-        } catch (Exception e) {
-            AdtPlugin.log(e, "Failed to write %s", deviceXml.getAbsolutePath());
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java
deleted file mode 100755
index 67e9718..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-
-import java.io.InputStream;
-
-import javax.xml.XMLConstants;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-
-/**
- * Public constants for the layout device description XML Schema.
- */
-public class LayoutDevicesXsd {
-
-    /** The XML namespace of the layout-configs XML. */
-    public static final String NS_LAYOUT_DEVICE_XSD =
-        "http://schemas.android.com/sdk/android/layout-devices/1";                  //$NON-NLS-1$
-
-    /**
-     * The "layout-devices" element is the root element of this schema.
-     *
-     * It must contain one or more "device" elements that each define the configurations
-     * available for a given device.
-     *
-     * These definitions are used in the Graphical Layout Editor in the
-     * Android Development Tools (ADT) plugin for Eclipse.
-     */
-    public static final String NODE_LAYOUT_DEVICES = "layout-devices";              //$NON-NLS-1$
-
-    /**
-     * A device element must contain at most one "default" element followed
-     * by one or more ""config" elements.
-     *
-     * The "default" element defines all the default parameters inherited
-     * by the following "config" elements. Each "config" element can override
-     * the default values, if any.
-     *
-     * A "device" element also has a required "name" attribute that represents
-     * the user-interface name of this device.
-     */
-    public static final String NODE_DEVICE = "device";                              //$NON-NLS-1$
-
-    /**
-     * The "default" element contains zero or more of all the parameter elements
-     * listed below. It defines all the parameters that are common to all
-     * declared "config" elements.
-     */
-    public static final String NODE_DEFAULT = "default";                            //$NON-NLS-1$
-
-    /**
-     * The "config" element contains zero or more of all the parameter elements
-     * listed below. The parameters from the "default" element (if present) are
-     * automatically inherited and can be overridden.
-     */
-    public static final String NODE_CONFIG = "config";                              //$NON-NLS-1$
-
-
-    public static final String NODE_COUNTRY_CODE = "country-code";                  //$NON-NLS-1$
-
-    public static final String NODE_NETWORK_CODE = "network-code";                  //$NON-NLS-1$
-
-    public static final String NODE_SCREEN_SIZE = "screen-size";                    //$NON-NLS-1$
-
-    public static final String NODE_SCREEN_RATIO = "screen-ratio";                  //$NON-NLS-1$
-
-    public static final String NODE_SCREEN_ORIENTATION = "screen-orientation";      //$NON-NLS-1$
-
-    public static final String NODE_PIXEL_DENSITY = "pixel-density";                //$NON-NLS-1$
-
-    public static final String NODE_TOUCH_TYPE = "touch-type";                      //$NON-NLS-1$
-
-    public static final String NODE_KEYBOARD_STATE = "keyboard-state";              //$NON-NLS-1$
-
-    public static final String NODE_TEXT_INPUT_METHOD = "text-input-method";        //$NON-NLS-1$
-
-    public static final String NODE_NAV_METHOD = "nav-method";                      //$NON-NLS-1$
-
-    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_XDPI = "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.
-     */
-    public static final String ATTR_NAME = "name";                                  //$NON-NLS-1$
-
-    /**
-     * Helper to get an input stream of the layout config XML schema.
-     */
-    public static InputStream getXsdStream() {
-        return LayoutDevicesXsd.class.getResourceAsStream("layout-devices.xsd");    //$NON-NLS-1$
-    }
-
-    /** Helper method that returns a {@link Validator} for our XSD */
-    public static Validator getValidator(ErrorHandler handler) throws SAXException {
-        InputStream xsdStream = getXsdStream();
-        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        Schema schema = factory.newSchema(new StreamSource(xsdStream));
-        Validator validator = schema.newValidator();
-        if (handler != null) {
-            validator.setErrorHandler(handler);
-        }
-
-        return validator;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java
deleted file mode 100644
index 5d26acb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.resources.AttrsXmlParser;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo.LayoutParamsInfo;
-import com.android.ide.eclipse.adt.internal.sdk.IAndroidClassLoader.IClassDescriptor;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubMonitor;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import javax.management.InvalidAttributeValueException;
-
-/*
- * TODO: refactor this. Could use some cleanup.
- */
-
-/**
- * Parser for the framework library.
- * <p/>
- * This gather the following information:
- * <ul>
- * <li>Resource ID from <code>android.R</code></li>
- * <li>The list of permissions values from <code>android.Manifest$permission</code></li>
- * <li></li>
- * </ul> 
- */
-public class LayoutParamsParser {
-    
-    /**
-     * Class extending {@link ViewClassInfo} by adding the notion of instantiability.
-     * {@link LayoutParamsParser#getViews()} and {@link LayoutParamsParser#getGroups()} should
-     * only return classes that can be instantiated.
-     */
-    final static class ExtViewClassInfo extends ViewClassInfo {
-
-        private boolean mIsInstantiable;
-
-        ExtViewClassInfo(boolean instantiable, boolean isLayout, String canonicalClassName,
-                String shortClassName) {
-            super(isLayout, canonicalClassName, shortClassName);
-            mIsInstantiable = instantiable;
-        }
-        
-        boolean isInstantiable() {
-            return mIsInstantiable;
-        }
-    }
-    
-    /* Note: protected members/methods are overridden in unit tests */
-    
-    /** Reference to android.view.View */
-    protected IClassDescriptor mTopViewClass;
-    /** Reference to android.view.ViewGroup */
-    protected IClassDescriptor mTopGroupClass;
-    /** Reference to android.view.ViewGroup$LayoutParams */
-    protected IClassDescriptor mTopLayoutParamsClass;
-    
-    /** Input list of all classes deriving from android.view.View */
-    protected ArrayList<IClassDescriptor> mViewList;
-    /** Input list of all classes deriving from android.view.ViewGroup */
-    protected ArrayList<IClassDescriptor> mGroupList;
-    
-    /** Output map of FQCN => info on View classes */
-    protected TreeMap<String, ExtViewClassInfo> mViewMap;
-    /** Output map of FQCN => info on ViewGroup classes */
-    protected TreeMap<String, ExtViewClassInfo> mGroupMap;
-    /** Output map of FQCN => info on LayoutParams classes */
-    protected HashMap<String, LayoutParamsInfo> mLayoutParamsMap;
-    
-    /** The attrs.xml parser */
-    protected AttrsXmlParser mAttrsXmlParser;
-
-    /** The android.jar class loader */
-    protected IAndroidClassLoader mClassLoader;
-
-    /**
-     * Instantiate a new LayoutParamsParser.
-     * @param classLoader The android.jar class loader
-     * @param attrsXmlParser The parser of the attrs.xml file
-     */
-    public LayoutParamsParser(IAndroidClassLoader classLoader,
-            AttrsXmlParser attrsXmlParser) {
-        mClassLoader = classLoader;
-        mAttrsXmlParser = attrsXmlParser;
-    }
-    
-    /** Returns the map of FQCN => info on View classes */
-    public List<ViewClassInfo> getViews() {
-        return getInstantiables(mViewMap);
-    }
-
-    /** Returns the map of FQCN => info on ViewGroup classes */
-    public List<ViewClassInfo> getGroups() {
-        return getInstantiables(mGroupMap);
-    }
-    
-    /**
-     * TODO: doc here.
-     * <p/>
-     * Note: on output we should have NO dependency on {@link IClassDescriptor},
-     * otherwise we wouldn't be able to unload the class loader later.
-     * <p/>
-     * Note on Vocabulary: FQCN=Fully Qualified Class Name (e.g. "my.package.class$innerClass")
-     * @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
-     */
-    public void parseLayoutClasses(IProgressMonitor monitor) {
-        parseClasses(monitor,
-                AndroidConstants.CLASS_VIEW,
-                AndroidConstants.CLASS_VIEWGROUP,
-                AndroidConstants.CLASS_VIEWGROUP_LAYOUTPARAMS);
-    }
-
-    public void parsePreferencesClasses(IProgressMonitor monitor) {
-        parseClasses(monitor,
-                AndroidConstants.CLASS_PREFERENCE,
-                AndroidConstants.CLASS_PREFERENCEGROUP,
-                null /* paramsClassName */ );
-    }
-    
-    private void parseClasses(IProgressMonitor monitor,
-            String rootClassName,
-            String groupClassName,
-            String paramsClassName) {
-        try {
-            SubMonitor progress = SubMonitor.convert(monitor, 100);
-
-            String[] superClasses = new String[2 + (paramsClassName == null ? 0 : 1)];
-            superClasses[0] = groupClassName;
-            superClasses[1] = rootClassName;
-            if (paramsClassName != null) {
-                superClasses[2] = paramsClassName;
-            }
-            HashMap<String, ArrayList<IClassDescriptor>> found =
-                    mClassLoader.findClassesDerivingFrom("android.", superClasses);  //$NON-NLS-1$
-            mTopViewClass = mClassLoader.getClass(rootClassName);
-            mTopGroupClass = mClassLoader.getClass(groupClassName);
-            if (paramsClassName != null) {
-                mTopLayoutParamsClass = mClassLoader.getClass(paramsClassName);
-            }
-
-            mViewList = found.get(rootClassName);
-            mGroupList = found.get(groupClassName);
-
-            mViewMap = new TreeMap<String, ExtViewClassInfo>();
-            mGroupMap = new TreeMap<String, ExtViewClassInfo>();
-            if (mTopLayoutParamsClass != null) {
-                mLayoutParamsMap = new HashMap<String, LayoutParamsInfo>();
-            }
-            
-            // Add top classes to the maps since by design they are not listed in classes deriving
-            // from themselves.
-            addGroup(mTopGroupClass);
-            addView(mTopViewClass);
-
-            // ViewGroup derives from View
-            mGroupMap.get(groupClassName).setSuperClass(mViewMap.get(rootClassName));
-
-            progress.setWorkRemaining(mGroupList.size() + mViewList.size());
-            
-            for (IClassDescriptor groupChild : mGroupList) {
-                addGroup(groupChild);
-                progress.worked(1);
-            }
-
-            for (IClassDescriptor viewChild : mViewList) {
-                if (viewChild != mTopGroupClass) {
-                    addView(viewChild);
-                }
-                progress.worked(1);
-            }
-        } catch (ClassNotFoundException e) {
-            AdtPlugin.log(e, "Problem loading class %1$s or %2$s",  //$NON-NLS-1$
-                    rootClassName, groupClassName);
-        } catch (InvalidAttributeValueException e) {
-            AdtPlugin.log(e, "Problem loading classes"); //$NON-NLS-1$
-        } catch (ClassFormatError e) {
-            AdtPlugin.log(e, "Problem loading classes"); //$NON-NLS-1$
-        } catch (IOException e) {
-            AdtPlugin.log(e, "Problem loading classes"); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Parses a View class and adds a ExtViewClassInfo for it in mViewMap.
-     * It calls itself recursively to handle super classes which are also Views.
-     */
-    private ExtViewClassInfo addView(IClassDescriptor viewClass) {
-        String fqcn = viewClass.getCanonicalName();
-        if (mViewMap.containsKey(fqcn)) {
-            return mViewMap.get(fqcn);
-        } else if (mGroupMap.containsKey(fqcn)) {
-            return mGroupMap.get(fqcn);
-        }
-
-        ExtViewClassInfo info = new ExtViewClassInfo(viewClass.isInstantiable(),
-                false /* layout */, fqcn, viewClass.getSimpleName());
-        mViewMap.put(fqcn, info);
-
-        // All view classes derive from mTopViewClass by design.
-        // Do not lookup the super class for mTopViewClass itself.
-        if (viewClass.equals(mTopViewClass) == false) {
-            IClassDescriptor superClass = viewClass.getSuperclass(); 
-            ExtViewClassInfo superClassInfo = addView(superClass);
-            info.setSuperClass(superClassInfo);
-        }
-
-        mAttrsXmlParser.loadViewAttributes(info);
-        return info;
-    }
-
-    /**
-     * Parses a ViewGroup class and adds a ExtViewClassInfo for it in mGroupMap.
-     * It calls itself recursively to handle super classes which are also ViewGroups.
-     */
-    private ExtViewClassInfo addGroup(IClassDescriptor groupClass) {
-        String fqcn = groupClass.getCanonicalName();
-        if (mGroupMap.containsKey(fqcn)) {
-            return mGroupMap.get(fqcn);
-        }
-
-        ExtViewClassInfo info = new ExtViewClassInfo(groupClass.isInstantiable(),
-                true /* layout */, fqcn, groupClass.getSimpleName());
-        mGroupMap.put(fqcn, info);
-
-        // All groups derive from android.view.ViewGroup, which in turns derives from
-        // android.view.View (i.e. mTopViewClass here). So the only group that can have View as
-        // its super class is the ViewGroup base class and we don't try to resolve it since groups
-        // are loaded before views.
-        IClassDescriptor superClass = groupClass.getSuperclass(); 
-        
-        // Assertion: at this point, we should have
-        //   superClass != mTopViewClass || fqcn.equals(AndroidConstants.CLASS_VIEWGROUP);
-
-        if (superClass != null && superClass.equals(mTopViewClass) == false) {
-            ExtViewClassInfo superClassInfo = addGroup(superClass);
-            
-            // Assertion: we should have superClassInfo != null && superClassInfo != info;
-            if (superClassInfo != null && superClassInfo != info) {
-                info.setSuperClass(superClassInfo);
-            }
-        }
-
-        mAttrsXmlParser.loadViewAttributes(info);
-        if (mTopLayoutParamsClass != null) {
-            info.setLayoutParams(addLayoutParams(groupClass));
-        }
-        return info;
-    }
-    
-    /**
-     * Parses a ViewGroup class and returns an info object on its inner LayoutParams.
-     * 
-     * @return The {@link LayoutParamsInfo} for the ViewGroup class or null.
-     */
-    private LayoutParamsInfo addLayoutParams(IClassDescriptor groupClass) {
-
-        // Is there a LayoutParams in this group class?
-        IClassDescriptor layoutParamsClass = findLayoutParams(groupClass);
-
-        // if there's no layout data in the group class, link to the one from the
-        // super class.
-        if (layoutParamsClass == null) {
-            for (IClassDescriptor superClass = groupClass.getSuperclass();
-                    layoutParamsClass == null &&
-                        superClass != null &&
-                        superClass.equals(mTopViewClass) == false;
-                    superClass = superClass.getSuperclass()) {
-                layoutParamsClass = findLayoutParams(superClass);
-            }
-        }
-
-        if (layoutParamsClass != null) {
-            return getLayoutParamsInfo(layoutParamsClass);
-        }
-        
-        return null;
-    }
-
-    /**
-     * Parses a LayoutParams class and returns a LayoutParamsInfo object for it.
-     * It calls itself recursively to handle the super class of the LayoutParams.
-     */
-    private LayoutParamsInfo getLayoutParamsInfo(IClassDescriptor layoutParamsClass) {
-        String fqcn = layoutParamsClass.getCanonicalName();
-        LayoutParamsInfo layoutParamsInfo = mLayoutParamsMap.get(fqcn);
-
-        if (layoutParamsInfo != null) {
-            return layoutParamsInfo;
-        }
-        
-        // Find the link on the LayoutParams super class 
-        LayoutParamsInfo superClassInfo = null;
-        if (layoutParamsClass.equals(mTopLayoutParamsClass) == false) {
-            IClassDescriptor superClass = layoutParamsClass.getSuperclass(); 
-            superClassInfo = getLayoutParamsInfo(superClass);
-        }
-        
-        // Find the link on the enclosing ViewGroup
-        ExtViewClassInfo enclosingGroupInfo = addGroup(layoutParamsClass.getEnclosingClass());
-
-        layoutParamsInfo = new ExtViewClassInfo.LayoutParamsInfo(
-                enclosingGroupInfo, layoutParamsClass.getSimpleName(), superClassInfo);
-        mLayoutParamsMap.put(fqcn, layoutParamsInfo);
-
-        mAttrsXmlParser.loadLayoutParamsAttributes(layoutParamsInfo);
-
-        return layoutParamsInfo;
-    }
-
-    /**
-     * Given a ViewGroup-derived class, looks for an inner class named LayoutParams
-     * and if found returns its class definition.
-     * <p/>
-     * This uses the actual defined inner classes and does not look at inherited classes.
-     *  
-     * @param groupClass The ViewGroup derived class
-     * @return The Class of the inner LayoutParams or null if none is declared.
-     */
-    private IClassDescriptor findLayoutParams(IClassDescriptor groupClass) {
-        IClassDescriptor[] innerClasses = groupClass.getDeclaredClasses();
-        for (IClassDescriptor innerClass : innerClasses) {
-            if (innerClass.getSimpleName().equals(AndroidConstants.CLASS_NAME_LAYOUTPARAMS)) {
-                return innerClass;
-            }
-        }
-        return null;
-    }
-    
-    /**
-     * Computes and return a list of ViewClassInfo from a map by filtering out the class that
-     * cannot be instantiated.
-     */
-    private List<ViewClassInfo> getInstantiables(SortedMap<String, ExtViewClassInfo> map) {
-        Collection<ExtViewClassInfo> values = map.values();
-        ArrayList<ViewClassInfo> list = new ArrayList<ViewClassInfo>();
-        
-        for (ExtViewClassInfo info : values) {
-            if (info.isInstantiable()) {
-                list.add(info);
-            }
-        }
-        
-        return list;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LoadStatus.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LoadStatus.java
deleted file mode 100644
index e334d97..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LoadStatus.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-/**
- * Enum for loading status of various SDK parts.
- */
-public enum LoadStatus {
-    LOADING, LOADED, FAILED;
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
deleted file mode 100644
index 45ff31f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IProjectListener;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.project.ApkConfigurationHelper;
-import com.android.sdklib.internal.project.ApkSettings;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Central point to load, manipulate and deal with the Android SDK. Only one SDK can be used
- * at the same time.
- *
- * To start using an SDK, call {@link #loadSdk(String)} which returns the instance of
- * the Sdk object.
- *
- * To get the list of platforms or add-ons present in the SDK, call {@link #getTargets()}.
- */
-public class Sdk implements IProjectListener {
-    private static Sdk sCurrentSdk = null;
-
-    private final SdkManager mManager;
-    private final AvdManager mAvdManager;
-
-    private final HashMap<IProject, IAndroidTarget> mProjectTargetMap =
-            new HashMap<IProject, IAndroidTarget>();
-    private final HashMap<IAndroidTarget, AndroidTargetData> mTargetDataMap =
-            new HashMap<IAndroidTarget, AndroidTargetData>();
-    private final HashMap<IProject, ApkSettings> mApkSettingsMap =
-            new HashMap<IProject, ApkSettings>();
-    private final String mDocBaseUrl;
-
-    private final LayoutDeviceManager mLayoutDeviceManager = new LayoutDeviceManager();
-
-    /**
-     * Classes implementing this interface will receive notification when targets are changed.
-     */
-    public interface ITargetChangeListener {
-        /**
-         * Sent when project has its target changed.
-         */
-        void onProjectTargetChange(IProject changedProject);
-
-        /**
-         * Called when the targets are loaded (either the SDK finished loading when Eclipse starts,
-         * or the SDK is changed).
-         */
-        void onTargetsLoaded();
-    }
-
-    /**
-     * Loads an SDK and returns an {@link Sdk} object if success.
-     * @param sdkLocation the OS path to the SDK.
-     */
-    public static Sdk loadSdk(String sdkLocation) {
-        if (sCurrentSdk != null) {
-            sCurrentSdk.dispose();
-            sCurrentSdk = null;
-        }
-
-        final ArrayList<String> logMessages = new ArrayList<String>();
-        ISdkLog log = new ISdkLog() {
-            public void error(Throwable throwable, String errorFormat, Object... arg) {
-                if (errorFormat != null) {
-                    logMessages.add(String.format("Error: " + errorFormat, arg));
-                }
-
-                if (throwable != null) {
-                    logMessages.add(throwable.getMessage());
-                }
-            }
-
-            public void warning(String warningFormat, Object... arg) {
-                logMessages.add(String.format("Warning: " + warningFormat, arg));
-            }
-
-            public void printf(String msgFormat, Object... arg) {
-                logMessages.add(String.format(msgFormat, arg));
-            }
-        };
-
-        // get an SdkManager object for the location
-        SdkManager manager = SdkManager.createManager(sdkLocation, log);
-        if (manager != null) {
-            AvdManager avdManager = null;
-            try {
-                avdManager = new AvdManager(manager, log);
-            } catch (AndroidLocationException e) {
-                log.error(e, "Error parsing the AVDs");
-            }
-            sCurrentSdk = new Sdk(manager, avdManager);
-            return sCurrentSdk;
-        } else {
-            StringBuilder sb = new StringBuilder("Error Loading the SDK:\n");
-            for (String msg : logMessages) {
-                sb.append('\n');
-                sb.append(msg);
-            }
-            AdtPlugin.displayError("Android SDK", sb.toString());
-        }
-        return null;
-    }
-
-    /**
-     * Returns the current {@link Sdk} object.
-     */
-    public static Sdk getCurrent() {
-        return sCurrentSdk;
-    }
-
-    /**
-     * Returns the location (OS path) of the current SDK.
-     */
-    public String getSdkLocation() {
-        return mManager.getLocation();
-    }
-
-    /**
-     * Returns the URL to the local documentation.
-     * Can return null if no documentation is found in the current SDK.
-     *
-     * @return A file:// URL on the local documentation folder if it exists or null.
-     */
-    public String getDocumentationBaseUrl() {
-        return mDocBaseUrl;
-    }
-
-    /**
-     * Returns the list of targets that are available in the SDK.
-     */
-    public IAndroidTarget[] getTargets() {
-        return mManager.getTargets();
-    }
-
-    /**
-     * Returns a target from a hash that was generated by {@link IAndroidTarget#hashString()}.
-     *
-     * @param hash the {@link IAndroidTarget} hash string.
-     * @return The matching {@link IAndroidTarget} or null.
-     */
-    public IAndroidTarget getTargetFromHashString(String hash) {
-        return mManager.getTargetFromHashString(hash);
-    }
-
-    /**
-     * Sets a new target and a new list of Apk configuration for a given project.
-     *
-     * @param project the project to receive the new apk configurations
-     * @param target The new target to set, or <code>null</code> to not change the current target.
-     * @param apkConfigMap a map of apk configurations. The map contains (name, filter) where name
-     * is the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of
-     * resource configuration to include in the apk (see aapt -c). Can be <code>null</code> if the
-     * apk configurations should not be updated.
-     */
-    public void setProject(IProject project, IAndroidTarget target,
-            ApkSettings settings) {
-        synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-            boolean resolveProject = false;
-
-            ProjectProperties properties = ProjectProperties.load(
-                    project.getLocation().toOSString(), PropertyType.DEFAULT);
-            if (properties == null) {
-                // doesn't exist yet? we create it.
-                properties = ProjectProperties.create(project.getLocation().toOSString(),
-                        PropertyType.DEFAULT);
-            }
-
-            if (target != null) {
-                // look for the current target of the project
-                IAndroidTarget previousTarget = mProjectTargetMap.get(project);
-
-                if (target != previousTarget) {
-                    // save the target hash string in the project persistent property
-                    properties.setAndroidTarget(target);
-
-                    // put it in a local map for easy access.
-                    mProjectTargetMap.put(project, target);
-
-                    resolveProject = true;
-                }
-            }
-
-            // if there's no settings, force default values (to reset possibly changed
-            // values in a previous call.
-            if (settings == null) {
-                settings = new ApkSettings();
-            }
-
-            // save the project settings into the project persistent property
-            ApkConfigurationHelper.setProperties(properties, settings);
-
-            // put it in a local map for easy access.
-            mApkSettingsMap.put(project, settings);
-
-            // we are done with the modification. Save the property file.
-            try {
-                properties.save();
-            } catch (IOException e) {
-                AdtPlugin.log(e, "Failed to save default.properties for project '%s'",
-                        project.getName());
-            }
-
-            if (resolveProject) {
-                // force a resolve of the project by updating the classpath container.
-                // This will also force a recompile.
-                IJavaProject javaProject = JavaCore.create(project);
-                AndroidClasspathContainerInitializer.updateProjects(
-                        new IJavaProject[] { javaProject });
-            } else {
-                // always do a full clean/build.
-                try {
-                    project.build(IncrementalProjectBuilder.CLEAN_BUILD, null);
-                } catch (CoreException e) {
-                    // failed to build? force resolve instead.
-                    IJavaProject javaProject = JavaCore.create(project);
-                    AndroidClasspathContainerInitializer.updateProjects(
-                            new IJavaProject[] { javaProject });
-                }
-            }
-
-            // finally, update the opened editors.
-            if (resolveProject) {
-                AdtPlugin.getDefault().updateTargetListener(project);
-            }
-        }
-    }
-
-    /**
-     * Returns the {@link IAndroidTarget} object associated with the given {@link IProject}.
-     */
-    public IAndroidTarget getTarget(IProject project) {
-        synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-            IAndroidTarget target = mProjectTargetMap.get(project);
-            if (target == null) {
-                // get the value from the project persistent property.
-                String targetHashString = loadProjectProperties(project, this);
-
-                if (targetHashString != null) {
-                    target = mManager.getTargetFromHashString(targetHashString);
-                }
-            }
-
-            return target;
-        }
-    }
-
-
-    /**
-     * Parses the project properties and returns the hash string uniquely identifying the
-     * target of the given project.
-     * <p/>
-     * This methods reads the content of the <code>default.properties</code> file present in
-     * the root folder of the project.
-     * <p/>The returned string is equivalent to the return of {@link IAndroidTarget#hashString()}.
-     * @param project The project for which to return the target hash string.
-     * @param sdkStorage The sdk in which to store the Apk Configs. Can be null.
-     * @return the hash string or null if the project does not have a target set.
-     */
-    private static String loadProjectProperties(IProject project, Sdk sdkStorage) {
-        // load the default.properties from the project folder.
-        IPath location = project.getLocation();
-        if (location == null) {  // can return null when the project is being deleted.
-            // do nothing and return null;
-            return null;
-        }
-        ProjectProperties properties = ProjectProperties.load(location.toOSString(),
-                PropertyType.DEFAULT);
-        if (properties == null) {
-            AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'",
-                    project.getName());
-            return null;
-        }
-
-        if (sdkStorage != null) {
-            synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-                ApkSettings settings = ApkConfigurationHelper.getSettings(properties);
-
-                if (settings != null) {
-                    sdkStorage.mApkSettingsMap.put(project, settings);
-                }
-            }
-        }
-
-        return properties.getProperty(ProjectProperties.PROPERTY_TARGET);
-    }
-
-    /**
-     * Returns the hash string uniquely identifying the target of a project.
-     * <p/>
-     * This methods reads the content of the <code>default.properties</code> file present in
-     * the root folder of the project.
-     * <p/>The string is equivalent to the return of {@link IAndroidTarget#hashString()}.
-     * @param project The project for which to return the target hash string.
-     * @return the hash string or null if the project does not have a target set.
-     */
-    public static String getProjectTargetHashString(IProject project) {
-        return loadProjectProperties(project, null /*storeConfigs*/);
-    }
-
-    /**
-     * Sets a target hash string in given project's <code>default.properties</code> file.
-     * @param project The project in which to save the hash string.
-     * @param targetHashString The target hash string to save. This must be the result from
-     * {@link IAndroidTarget#hashString()}.
-     */
-    public static void setProjectTargetHashString(IProject project, String targetHashString) {
-        // because we don't want to erase other properties from default.properties, we first load
-        // them
-        ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(),
-                PropertyType.DEFAULT);
-        if (properties == null) {
-            // doesn't exist yet? we create it.
-            properties = ProjectProperties.create(project.getLocation().toOSString(),
-                    PropertyType.DEFAULT);
-        }
-
-        // add/change the target hash string.
-        properties.setProperty(ProjectProperties.PROPERTY_TARGET, targetHashString);
-
-        // and rewrite the file.
-        try {
-            properties.save();
-        } catch (IOException e) {
-            AdtPlugin.log(e, "Failed to save default.properties for project '%s'",
-                    project.getName());
-        }
-    }
-    /**
-     * Return the {@link AndroidTargetData} for a given {@link IAndroidTarget}.
-     */
-    public AndroidTargetData getTargetData(IAndroidTarget target) {
-        synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-            return mTargetDataMap.get(target);
-        }
-    }
-
-    /**
-     * Return the {@link AndroidTargetData} for a given {@link IProject}.
-     */
-    public AndroidTargetData getTargetData(IProject project) {
-        synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-            IAndroidTarget target = getTarget(project);
-            if (target != null) {
-                return getTargetData(target);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the APK settings for a given project.
-     */
-    public ApkSettings getApkSettings(IProject project) {
-        synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-            return mApkSettingsMap.get(project);
-        }
-    }
-
-    /**
-     * Returns the {@link AvdManager}. If the AvdManager failed to parse the AVD folder, this could
-     * be <code>null</code>.
-     */
-    public AvdManager getAvdManager() {
-        return mAvdManager;
-    }
-
-    public static AndroidVersion getDeviceVersion(IDevice device) {
-        try {
-            Map<String, String> props = device.getProperties();
-            String apiLevel = props.get(IDevice.PROP_BUILD_API_LEVEL);
-            if (apiLevel == null) {
-                return null;
-            }
-
-            return new AndroidVersion(Integer.parseInt(apiLevel),
-                    props.get((IDevice.PROP_BUILD_CODENAME)));
-        } catch (NumberFormatException e) {
-            return null;
-        }
-    }
-
-    public LayoutDeviceManager getLayoutDeviceManager() {
-        return mLayoutDeviceManager;
-    }
-
-    private Sdk(SdkManager manager, AvdManager avdManager) {
-        mManager = manager;
-        mAvdManager = avdManager;
-
-        // listen to projects closing
-        ResourceMonitor monitor = ResourceMonitor.getMonitor();
-        monitor.addProjectListener(this);
-
-        // pre-compute some paths
-        mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
-                SdkConstants.OS_SDK_DOCS_FOLDER);
-
-        // load the built-in and user layout devices
-        mLayoutDeviceManager.loadDefaultAndUserDevices(mManager.getLocation());
-        // and the ones from the add-on
-        loadLayoutDevices();
-    }
-
-    /**
-     *  Cleans and unloads the SDK.
-     */
-    private void dispose() {
-        ResourceMonitor.getMonitor().removeProjectListener(this);
-    }
-
-    void setTargetData(IAndroidTarget target, AndroidTargetData data) {
-        synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-            mTargetDataMap.put(target, data);
-        }
-    }
-
-    /**
-     * Returns the URL to the local documentation.
-     * Can return null if no documentation is found in the current SDK.
-     *
-     * @param osDocsPath Path to the documentation folder in the current SDK.
-     *  The folder may not actually exist.
-     * @return A file:// URL on the local documentation folder if it exists or null.
-     */
-    private String getDocumentationBaseUrl(String osDocsPath) {
-        File f = new File(osDocsPath);
-
-        if (f.isDirectory()) {
-            try {
-                // Note: to create a file:// URL, one would typically use something like
-                // f.toURI().toURL().toString(). However this generates a broken path on
-                // Windows, namely "C:\\foo" is converted to "file:/C:/foo" instead of
-                // "file:///C:/foo" (i.e. there should be 3 / after "file:"). So we'll
-                // do the correct thing manually.
-
-                String path = f.getAbsolutePath();
-                if (File.separatorChar != '/') {
-                    path = path.replace(File.separatorChar, '/');
-                }
-
-                // For some reason the URL class doesn't add the mandatory "//" after
-                // the "file:" protocol name, so it has to be hacked into the path.
-                URL url = new URL("file", null, "//" + path);  //$NON-NLS-1$ //$NON-NLS-2$
-                String result = url.toString();
-                return result;
-            } catch (MalformedURLException e) {
-                // ignore malformed URLs
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Parses the SDK add-ons to look for files called {@link SdkConstants#FN_DEVICES_XML} to
-     * load {@link LayoutDevice} from them.
-     */
-    private void loadLayoutDevices() {
-        IAndroidTarget[] targets = mManager.getTargets();
-        for (IAndroidTarget target : targets) {
-            if (target.isPlatform() == false) {
-                File deviceXml = new File(target.getLocation(), SdkConstants.FN_DEVICES_XML);
-                if (deviceXml.isFile()) {
-                    mLayoutDeviceManager.parseAddOnLayoutDevice(deviceXml);
-                }
-            }
-        }
-
-        mLayoutDeviceManager.sealAddonLayoutDevices();
-    }
-
-    public void projectClosed(IProject project) {
-        // get the target project
-        synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
-            IAndroidTarget target = mProjectTargetMap.get(project);
-            if (target != null) {
-                // get the bridge for the target, and clear the cache for this project.
-                AndroidTargetData data = mTargetDataMap.get(target);
-                if (data != null) {
-                    LayoutBridge bridge = data.getLayoutBridge();
-                    if (bridge != null && bridge.status == LoadStatus.LOADED) {
-                        bridge.bridge.clearCaches(project);
-                    }
-                }
-            }
-
-            // now remove the project for the maps.
-            mProjectTargetMap.remove(project);
-            mApkSettingsMap.remove(project);
-        }
-    }
-
-    public void projectDeleted(IProject project) {
-        projectClosed(project);
-    }
-
-    public void projectOpened(IProject project) {
-        // ignore this. The project will be added to the map the first time the target needs
-        // to be resolved.
-    }
-
-    public void projectOpenedWithWorkspace(IProject project) {
-        // ignore this. The project will be added to the map the first time the target needs
-        // to be resolved.
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java
deleted file mode 100644
index 321c236..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.management.InvalidAttributeValueException;
-
-/**
- * Parser for the text file containing the list of widgets, layouts and layout params.
- * <p/>
- * The file is a straight text file containing one class per line.<br>
- * Each line is in the following format<br>
- * <code>[code][class name] [super class name] [super class name]...</code>
- * where code is a single letter (W for widget, L for layout, P for layout params), and class names
- * are the fully qualified name of the classes.
- */
-public final class WidgetClassLoader implements IAndroidClassLoader {
-    
-    /**
-     * Basic class containing the class descriptions found in the text file. 
-     */
-    private final static class ClassDescriptor implements IClassDescriptor {
-        
-        private String mName;
-        private String mSimpleName;
-        private ClassDescriptor mSuperClass;
-        private ClassDescriptor mEnclosingClass;
-        private final ArrayList<IClassDescriptor> mDeclaredClasses =
-                new ArrayList<IClassDescriptor>();
-        private boolean mIsInstantiable = false;
-
-        ClassDescriptor(String fqcn) {
-            mName = fqcn;
-            mSimpleName = getSimpleName(fqcn);
-        }
-
-        public String getCanonicalName() {
-            return mName;
-        }
-
-        public String getSimpleName() {
-            return mSimpleName;
-        }
-
-        public IClassDescriptor[] getDeclaredClasses() {
-            return mDeclaredClasses.toArray(new IClassDescriptor[mDeclaredClasses.size()]);
-        }
-
-        private void addDeclaredClass(ClassDescriptor declaredClass) {
-            mDeclaredClasses.add(declaredClass);
-        }
-
-        public IClassDescriptor getEnclosingClass() {
-            return mEnclosingClass;
-        }
-        
-        void setEnclosingClass(ClassDescriptor enclosingClass) {
-            // set the enclosing class.
-            mEnclosingClass = enclosingClass;
-            
-            // add this to the list of declared class in the enclosing class.
-            mEnclosingClass.addDeclaredClass(this);
-            
-            // finally change the name of declared class to make sure it uses the
-            // convention: package.enclosing$declared instead of package.enclosing.declared
-            mName = enclosingClass.mName + "$" + mName.substring(enclosingClass.mName.length() + 1);
-        }
-
-        public IClassDescriptor getSuperclass() {
-            return mSuperClass;
-        }
-        
-        void setSuperClass(ClassDescriptor superClass) {
-            mSuperClass = superClass;
-        }
-        
-        @Override
-        public boolean equals(Object clazz) {
-            if (clazz instanceof ClassDescriptor) {
-                return mName.equals(((ClassDescriptor)clazz).mName);
-            }
-            return super.equals(clazz);
-        }
-        
-        @Override
-        public int hashCode() {
-            return mName.hashCode();
-        }
-        
-        public boolean isInstantiable() {
-            return mIsInstantiable;
-        }
-        
-        void setInstantiable(boolean state) {
-            mIsInstantiable = state;
-        }
-        
-        private String getSimpleName(String fqcn) {
-            String[] segments = fqcn.split("\\.");
-            return segments[segments.length-1];
-        }
-    }
-
-    private BufferedReader mReader;
-
-    /** Output map of FQCN => descriptor on all classes */
-    private final Map<String, ClassDescriptor> mMap = new TreeMap<String, ClassDescriptor>();
-    /** Output map of FQCN => descriptor on View classes */
-    private final Map<String, ClassDescriptor> mWidgetMap = new TreeMap<String, ClassDescriptor>();
-    /** Output map of FQCN => descriptor on ViewGroup classes */
-    private final Map<String, ClassDescriptor> mLayoutMap = new TreeMap<String, ClassDescriptor>();
-    /** Output map of FQCN => descriptor on LayoutParams classes */
-    private final Map<String, ClassDescriptor> mLayoutParamsMap =
-        new HashMap<String, ClassDescriptor>();
-    /** File path of the source text file */
-    private String mOsFilePath;
-
-    /**
-     * Creates a loader with a given file path.
-     * @param osFilePath the OS path of the file to load.
-     * @throws FileNotFoundException if the file is not found.
-     */
-    WidgetClassLoader(String osFilePath) throws FileNotFoundException {
-        mOsFilePath = osFilePath;
-        mReader = new BufferedReader(new FileReader(osFilePath));
-    }
-
-    public String getSource() {
-        return mOsFilePath;
-    }
-    
-    /**
-     * Parses the text file and return true if the file was successfully parsed.
-     * @param monitor
-     */
-    boolean parseWidgetList(IProgressMonitor monitor) {
-        try {
-            String line;
-            while ((line = mReader.readLine()) != null) {
-                if (line.length() > 0) {
-                    char prefix = line.charAt(0);
-                    String[] classes = null;
-                    ClassDescriptor clazz = null;
-                    switch (prefix) {
-                        case 'W':
-                            classes = line.substring(1).split(" ");
-                            clazz = processClass(classes, 0, null /* map */);
-                            if (clazz != null) {
-                                clazz.setInstantiable(true);
-                                mWidgetMap.put(classes[0], clazz);
-                            }
-                            break;
-                        case 'L':
-                            classes = line.substring(1).split(" ");
-                            clazz = processClass(classes, 0, null /* map */);
-                            if (clazz != null) {
-                                clazz.setInstantiable(true);
-                                mLayoutMap.put(classes[0], clazz);
-                            }
-                            break;
-                        case 'P':
-                            classes = line.substring(1).split(" ");
-                            clazz = processClass(classes, 0, mLayoutParamsMap);
-                            if (clazz != null) {
-                                clazz.setInstantiable(true);
-                            }
-                            break;
-                        case '#':
-                            // comment, do nothing
-                            break;
-                        default:
-                                throw new IllegalArgumentException();
-                    }
-                }
-            }
-            
-            // reconciliate the layout and their layout params
-            postProcess();
-            
-            return true;
-        } catch (IOException e) {
-        } finally {
-            try {
-                mReader.close();
-            } catch (IOException e) {
-            }
-        }
-        
-        return false;
-    }
-    
-    /**
-     * Parses a View class and adds a ViewClassInfo for it in mWidgetMap.
-     * It calls itself recursively to handle super classes which are also Views.
-     * @param classes the inheritance list of the class to process.
-     * @param index the index of the class to process in the <code>classes</code> array.
-     * @param map an optional map in which to put every {@link ClassDescriptor} created.
-     */
-    private ClassDescriptor processClass(String[] classes, int index,
-            Map<String, ClassDescriptor> map) {
-        if (index >= classes.length) {
-            return null;
-        }
-        
-        String fqcn = classes[index];
-        
-        if ("java.lang.Object".equals(fqcn)) { //$NON-NLS-1$
-            return null;
-        }
-
-        // check if the ViewInfoClass has not yet been created.
-        if (mMap.containsKey(fqcn)) {
-            return mMap.get(fqcn);
-        }
-
-        // create the custom class.
-        ClassDescriptor clazz = new ClassDescriptor(fqcn);
-        mMap.put(fqcn, clazz);
-        if (map != null) {
-            map.put(fqcn, clazz);
-        }
-        
-        // get the super class
-        ClassDescriptor superClass = processClass(classes, index+1, map);
-        if (superClass != null) {
-            clazz.setSuperClass(superClass);
-        }
-        
-        return clazz;
-    }
-    
-    /**
-     * Goes through the layout params and look for the enclosed class. If the layout params
-     * has no known enclosed type it is dropped.
-     */
-    private void postProcess() {
-        Collection<ClassDescriptor> params = mLayoutParamsMap.values();
-
-        for (ClassDescriptor param : params) {
-            String fqcn = param.getCanonicalName();
-            
-            // get the enclosed name.
-            String enclosed = getEnclosedName(fqcn);
-            
-            // look for a match in the layouts. We don't use the layout map as it only contains the
-            // end classes, but in this case we also need to process the layout params for the base
-            // layout classes.
-            ClassDescriptor enclosingType = mMap.get(enclosed);
-            if (enclosingType != null) {
-                param.setEnclosingClass(enclosingType);
-                
-                // remove the class from the map, and put it back with the fixed name
-                mMap.remove(fqcn);
-                mMap.put(param.getCanonicalName(), param);
-            }
-        }
-    }
-
-    private String getEnclosedName(String fqcn) {
-        int index = fqcn.lastIndexOf('.');
-        return fqcn.substring(0, index);
-    }
-
-    /**
-     * Finds and loads all classes that derive from a given set of super classes.
-     * 
-     * @param rootPackage Root package of classes to find. Use an empty string to find everyting.
-     * @param superClasses The super classes of all the classes to find. 
-     * @return An hash map which keys are the super classes looked for and which values are
-     *         ArrayList of the classes found. The array lists are always created for all the
-     *         valid keys, they are simply empty if no deriving class is found for a given
-     *         super class. 
-     * @throws IOException
-     * @throws InvalidAttributeValueException
-     * @throws ClassFormatError
-     */
-    public HashMap<String, ArrayList<IClassDescriptor>> findClassesDerivingFrom(String rootPackage,
-            String[] superClasses) throws IOException, InvalidAttributeValueException,
-            ClassFormatError {
-        HashMap<String, ArrayList<IClassDescriptor>> map =
-                new HashMap<String, ArrayList<IClassDescriptor>>();
-        
-        ArrayList<IClassDescriptor> list = new ArrayList<IClassDescriptor>();
-        list.addAll(mWidgetMap.values());
-        map.put(AndroidConstants.CLASS_VIEW, list);
-        
-        list = new ArrayList<IClassDescriptor>();
-        list.addAll(mLayoutMap.values());
-        map.put(AndroidConstants.CLASS_VIEWGROUP, list);
-
-        list = new ArrayList<IClassDescriptor>();
-        list.addAll(mLayoutParamsMap.values());
-        map.put(AndroidConstants.CLASS_VIEWGROUP_LAYOUTPARAMS, list);
-
-        return map;
-    }
-
-    /**
-     * Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name.
-     * @param className the fully-qualified name of the class to return.
-     * @throws ClassNotFoundException
-     */
-    public IClassDescriptor getClass(String className) throws ClassNotFoundException {
-        return mMap.get(className);
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd
deleted file mode 100755
index 8a58560..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd
+++ /dev/null
@@ -1,325 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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.
--->
-<xsd:schema
-    targetNamespace="http://schemas.android.com/sdk/android/layout-devices/1"
-    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-    xmlns:c="http://schemas.android.com/sdk/android/layout-devices/1"
-    elementFormDefault="qualified"
-    attributeFormDefault="unqualified"
-    version="1">
-
-    <xsd:element name="layout-devices">
-        <xsd:annotation>
-            <xsd:documentation xml:lang="en">
-                The "layout-devices" element is the root element of this schema.
-
-                It must contain one or more "device" elements that each define the configurations
-                available for a given device.
-
-                These definitions are used in the Graphical Layout Editor in the
-                Android Development Tools (ADT) plugin for Eclipse.
-            </xsd:documentation>
-        </xsd:annotation>
-
-        <xsd:complexType>
-            <xsd:sequence>
-                <!-- layout-devices defines a sequence of 1..n device elements. -->
-                <xsd:element name="device" minOccurs="1" maxOccurs="unbounded">
-
-                    <xsd:annotation>
-                        <xsd:documentation xml:lang="en">
-                            A device element must contain at most one "default" element
-                            followed by one or more "config" elements.
-
-                            The "default" element defines all the default parameters
-                            inherited by the following "config" elements.
-                            Each "config" element can override the default values, if any.
-
-                            A "device" element also has a required "name" attribute that
-                            represents the user-interface name of this device.
-                        </xsd:documentation>
-                    </xsd:annotation>
-
-                    <xsd:complexType>
-                        <!-- device defines a choice of 0..1 default element
-                        and 1..n config elements. -->
-
-                        <xsd:sequence>
-                            <xsd:element name="default" type="c:parametersType"
-                                         minOccurs="0"  maxOccurs="1" />
-                            <xsd:element name="config"  type="c:configType"
-                                         minOccurs="1"  maxOccurs="unbounded" />
-                        </xsd:sequence>
-
-                        <xsd:attribute name="name" type="xsd:normalizedString" use="required" />
-                    </xsd:complexType>
-
-                </xsd:element>
-            </xsd:sequence>
-        </xsd:complexType>
-    </xsd:element>
-
-    <!-- The type of a device>default element.
-         This is overridden by configType below for the device>config element.
-    -->
-    <xsd:complexType name="parametersType">
-        <xsd:annotation>
-            <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>
-
-        <xsd:all>
-            <!-- parametersType says that 0..1 of each of these elements must be declared. -->
-
-            <xsd:element name="country-code" minOccurs="0">
-                <xsd:annotation>
-                    <xsd:documentation xml:lang="en">
-                        Specifies the configuration is for a particular Mobile Country Code.
-                    </xsd:documentation>
-                </xsd:annotation>
-                <xsd:simpleType>
-                    <xsd:restriction base="xsd:float">
-                        <xsd:minInclusive value="100" />
-                        <xsd:maxInclusive value="999" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </xsd:element>
-
-            <xsd:element name="network-code" minOccurs="0">
-                <xsd:annotation>
-                    <xsd:documentation xml:lang="en">
-                        Specifies the configuration is for a particular Mobile Network Code.
-                    </xsd:documentation>
-                </xsd:annotation>
-                <xsd:simpleType>
-                    <xsd:restriction base="xsd:float">
-                        <xsd:minExclusive value="0" />
-                        <xsd:maxExclusive value="1000" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </xsd:element>
-
-            <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" />
-                        <xsd:enumeration value="normal" />
-                        <xsd:enumeration value="large" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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" />
-                        <xsd:enumeration value="notlong" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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" />
-                        <xsd:enumeration value="land" />
-                        <xsd:enumeration value="square" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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" />
-                        <xsd:enumeration value="mdpi" />
-                        <xsd:enumeration value="hdpi" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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" />
-                        <xsd:enumeration value="stylus" />
-                        <xsd:enumeration value="finger" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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" />
-                        <xsd:enumeration value="keyshidden" />
-                        <xsd:enumeration value="keyssoft" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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" />
-                        <xsd:enumeration value="qwerty" />
-                        <xsd:enumeration value="12key" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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" />
-                        <xsd:enumeration value="trackball" />
-                        <xsd:enumeration value="wheel" />
-                        <xsd:enumeration value="nonav" />
-                    </xsd:restriction>
-                </xsd:simpleType>
-            </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">
-
-                        <xsd:element name="size">
-                            <xsd:simpleType>
-                                <xsd:restriction base="xsd:positiveInteger" />
-                            </xsd:simpleType>
-                        </xsd:element>
-
-                    </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>
-
-    <!-- The type definition of a device>config element.
-         This type is basically all the element defined by parametersType and an extra
-         required "name" attribute for the user-interface configuration name.
-    -->
-    <xsd:complexType name="configType">
-        <xsd:annotation>
-            <xsd:documentation>
-                The configType defines the content of a "config" element in a "device" element.
-
-                A "config" element can have all the parameters elements defined by
-                "parameterType". It also has a required "name" attribute that indicates the
-                user-interface name for this configuration.
-            </xsd:documentation>
-        </xsd:annotation>
-
-        <xsd:complexContent>
-            <xsd:extension base="c:parametersType">
-                <xsd:attribute name="name" type="xsd:normalizedString" use="required" />
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-</xsd:schema>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java
deleted file mode 100644
index c11f4b8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java
+++ /dev/null
@@ -1,1513 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.VersionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.FocusAdapter;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * Custom UI widget to let user build a Folder configuration.
- * <p/>
- * To use this, instantiate somewhere in the UI and then:
- * <ul>
- * <li>Use {@link #setConfiguration(String)} or {@link #setConfiguration(FolderConfiguration)}.
- * <li>Retrieve the configuration using {@link #getConfiguration(FolderConfiguration)}.
- * </ul>
- */
-public class ConfigurationSelector extends Composite {
-
-    public static final int WIDTH_HINT = 600;
-    public static final int HEIGHT_HINT = 250;
-
-    private Runnable mOnChangeListener;
-
-    private TableViewer mFullTableViewer;
-    private TableViewer mSelectionTableViewer;
-    private Button mAddButton;
-    private Button mRemoveButton;
-    private StackLayout mStackLayout;
-
-    private boolean mOnRefresh = false;
-
-    private final FolderConfiguration mBaseConfiguration = new FolderConfiguration();
-    private final FolderConfiguration mSelectedConfiguration = new FolderConfiguration();
-
-    private final HashMap<Class<? extends ResourceQualifier>, QualifierEditBase> mUiMap =
-        new HashMap<Class<? extends ResourceQualifier>, QualifierEditBase>();
-    private final boolean mDeviceMode;
-    private Composite mQualifierEditParent;
-    private IQualifierFilter mQualifierFilter;
-
-    /**
-     * Basic of {@link VerifyListener} to only accept digits.
-     */
-    private static class DigitVerifier implements VerifyListener {
-        public void verifyText(VerifyEvent e) {
-            // check for digit only.
-            for (int i = 0 ; i < e.text.length(); i++) {
-                char letter = e.text.charAt(i);
-                if (letter < '0' || letter > '9') {
-                    e.doit = false;
-                    return;
-                }
-            }
-        }
-    }
-
-    /**
-     * Implementation of {@link VerifyListener} for Country Code qualifiers.
-     */
-    public static class MobileCodeVerifier extends DigitVerifier {
-        @Override
-        public void verifyText(VerifyEvent e) {
-            super.verifyText(e);
-
-            // basic tests passed?
-            if (e.doit) {
-                // check the max 3 digits.
-                if (e.text.length() - e.end + e.start +
-                        ((Text)e.getSource()).getText().length() > 3) {
-                    e.doit = false;
-                }
-            }
-        }
-    }
-
-    /**
-     * Implementation of {@link VerifyListener} for the Language and Region qualifiers.
-     */
-    public static class LanguageRegionVerifier implements VerifyListener {
-        public void verifyText(VerifyEvent e) {
-            // check for length
-            if (e.text.length() - e.end + e.start + ((Combo)e.getSource()).getText().length() > 2) {
-                e.doit = false;
-                return;
-            }
-
-            // check for lower case only.
-            for (int i = 0 ; i < e.text.length(); i++) {
-                char letter = e.text.charAt(i);
-                if ((letter < 'a' || letter > 'z') && (letter < 'A' || letter > 'Z')) {
-                    e.doit = false;
-                    return;
-                }
-            }
-        }
-    }
-
-    /**
-     * Implementation of {@link VerifyListener} for the Pixel Density qualifier.
-     */
-    public static class DensityVerifier extends DigitVerifier { }
-
-    /**
-     * Implementation of {@link VerifyListener} for the Screen Dimension qualifier.
-     */
-    public static class DimensionVerifier extends DigitVerifier { }
-
-    /**
-     * Enum for the state of the configuration being created.
-     */
-    public enum ConfigurationState {
-        OK, INVALID_CONFIG, REGION_WITHOUT_LANGUAGE;
-    }
-
-    /**
-     * A filter for {@link ResourceQualifier}.
-     * @see ConfigurationSelector#setQualifierFilter(IQualifierFilter)
-     */
-    public interface IQualifierFilter {
-        /**
-         * Returns true of the qualifier is accepted.
-         */
-        boolean accept(ResourceQualifier qualifier);
-    }
-
-    /**
-     * Creates the selector.
-     *
-     * If the device mode is <code>true</code> then the configuration selector only
-     * allows to create configuration that are valid on a device (as opposed to resource
-     * configuration).
-     * For instance {@link Density#NODPI} is a valid qualifier for a resource configuration but
-     * this is not valid on a device.
-     * @param parent the composite parent.
-     * @param deviceMode the device mode.
-     */
-    public ConfigurationSelector(Composite parent, boolean deviceMode) {
-        super(parent, SWT.NONE);
-        mDeviceMode  = deviceMode;
-
-        mBaseConfiguration.createDefault();
-
-        GridLayout gl = new GridLayout(4, false);
-        gl.marginWidth = gl.marginHeight = 0;
-        setLayout(gl);
-
-        // first column is the first table
-        final Table fullTable = new Table(this, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER);
-        fullTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        fullTable.setHeaderVisible(true);
-        fullTable.setLinesVisible(true);
-
-        // create the column
-        final TableColumn fullTableColumn = new TableColumn(fullTable, SWT.LEFT);
-        // set the header
-        fullTableColumn.setText("Available Qualifiers");
-
-        fullTable.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Rectangle r = fullTable.getClientArea();
-                fullTableColumn.setWidth(r.width);
-            }
-        });
-
-        mFullTableViewer = new TableViewer(fullTable);
-        mFullTableViewer.setContentProvider(new QualifierContentProvider());
-        mFullTableViewer.setLabelProvider(new QualifierLabelProvider(
-                false /* showQualifierValue */));
-        mFullTableViewer.setInput(mBaseConfiguration);
-        mFullTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                ISelection selection = event.getSelection();
-                if (selection instanceof IStructuredSelection) {
-                    IStructuredSelection structSelection = (IStructuredSelection)selection;
-                    Object first = structSelection.getFirstElement();
-
-                    if (first instanceof ResourceQualifier) {
-                        mAddButton.setEnabled(true);
-                        return;
-                    }
-                }
-
-                mAddButton.setEnabled(false);
-            }
-        });
-
-        // 2nd column is the left/right arrow button
-        Composite buttonComposite = new Composite(this, SWT.NONE);
-        gl = new GridLayout(1, false);
-        gl.marginWidth = gl.marginHeight = 0;
-        buttonComposite.setLayout(gl);
-        buttonComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-
-        new Composite(buttonComposite, SWT.NONE);
-        mAddButton = new Button(buttonComposite, SWT.BORDER | SWT.PUSH);
-        mAddButton.setText("->");
-        mAddButton.setEnabled(false);
-        mAddButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                IStructuredSelection selection =
-                    (IStructuredSelection)mFullTableViewer.getSelection();
-
-                Object first = selection.getFirstElement();
-                if (first instanceof ResourceQualifier) {
-                    ResourceQualifier qualifier = (ResourceQualifier)first;
-
-                    mBaseConfiguration.removeQualifier(qualifier);
-                    mSelectedConfiguration.addQualifier(qualifier);
-
-                    mFullTableViewer.refresh();
-                    mSelectionTableViewer.refresh();
-                    mSelectionTableViewer.setSelection(new StructuredSelection(qualifier), true);
-
-                    onChange(false /* keepSelection */);
-                }
-            }
-        });
-
-        mRemoveButton = new Button(buttonComposite, SWT.BORDER | SWT.PUSH);
-        mRemoveButton.setText("<-");
-        mRemoveButton.setEnabled(false);
-        mRemoveButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                IStructuredSelection selection =
-                    (IStructuredSelection)mSelectionTableViewer.getSelection();
-
-                Object first = selection.getFirstElement();
-                if (first instanceof ResourceQualifier) {
-                    ResourceQualifier qualifier = (ResourceQualifier)first;
-
-                    mSelectedConfiguration.removeQualifier(qualifier);
-                    mBaseConfiguration.addQualifier(qualifier);
-
-                    mFullTableViewer.refresh();
-                    mSelectionTableViewer.refresh();
-
-                    onChange(false /* keepSelection */);
-                }
-            }
-        });
-
-        // 3rd column is the selected config table
-        final Table selectionTable = new Table(this, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER);
-        selectionTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-        selectionTable.setHeaderVisible(true);
-        selectionTable.setLinesVisible(true);
-
-        // create the column
-        final TableColumn selectionTableColumn = new TableColumn(selectionTable, SWT.LEFT);
-        // set the header
-        selectionTableColumn.setText("Chosen Qualifiers");
-
-        selectionTable.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Rectangle r = selectionTable.getClientArea();
-                selectionTableColumn.setWidth(r.width);
-            }
-        });
-        mSelectionTableViewer = new TableViewer(selectionTable);
-        mSelectionTableViewer.setContentProvider(new QualifierContentProvider());
-        mSelectionTableViewer.setLabelProvider(new QualifierLabelProvider(
-                true /* showQualifierValue */));
-        mSelectionTableViewer.setInput(mSelectedConfiguration);
-        mSelectionTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                // ignore selection changes during resfreshes in some cases.
-                if (mOnRefresh) {
-                    return;
-                }
-
-                ISelection selection = event.getSelection();
-                if (selection instanceof IStructuredSelection) {
-                    IStructuredSelection structSelection = (IStructuredSelection)selection;
-
-                    if (structSelection.isEmpty() == false) {
-                        Object first = structSelection.getFirstElement();
-
-                        if (first instanceof ResourceQualifier) {
-                            mRemoveButton.setEnabled(true);
-
-                            QualifierEditBase composite = mUiMap.get(first.getClass());
-
-                            if (composite != null) {
-                                composite.setQualifier((ResourceQualifier)first);
-                            }
-
-                            mStackLayout.topControl = composite;
-                            mQualifierEditParent.layout();
-
-                            return;
-                        }
-                    } else {
-                        mStackLayout.topControl = null;
-                        mQualifierEditParent.layout();
-                    }
-                }
-
-                mRemoveButton.setEnabled(false);
-            }
-        });
-
-        // 4th column is the detail of the selected qualifier
-        mQualifierEditParent = new Composite(this, SWT.NONE);
-        mQualifierEditParent.setLayout(mStackLayout = new StackLayout());
-        mQualifierEditParent.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-
-        // create the UI for all the qualifiers, and associate them to the ResourceQualifer class.
-        mUiMap.put(CountryCodeQualifier.class, new MCCEdit(mQualifierEditParent));
-        mUiMap.put(NetworkCodeQualifier.class, new MNCEdit(mQualifierEditParent));
-        mUiMap.put(LanguageQualifier.class, new LanguageEdit(mQualifierEditParent));
-        mUiMap.put(RegionQualifier.class, new RegionEdit(mQualifierEditParent));
-        mUiMap.put(ScreenSizeQualifier.class, new ScreenSizeEdit(mQualifierEditParent));
-        mUiMap.put(ScreenRatioQualifier.class, new ScreenRatioEdit(mQualifierEditParent));
-        mUiMap.put(ScreenOrientationQualifier.class, new OrientationEdit(mQualifierEditParent));
-        mUiMap.put(PixelDensityQualifier.class, new PixelDensityEdit(mQualifierEditParent));
-        mUiMap.put(TouchScreenQualifier.class, new TouchEdit(mQualifierEditParent));
-        mUiMap.put(KeyboardStateQualifier.class, new KeyboardEdit(mQualifierEditParent));
-        mUiMap.put(TextInputMethodQualifier.class, new TextInputEdit(mQualifierEditParent));
-        mUiMap.put(NavigationMethodQualifier.class, new NavigationEdit(mQualifierEditParent));
-        mUiMap.put(ScreenDimensionQualifier.class, new ScreenDimensionEdit(mQualifierEditParent));
-        mUiMap.put(VersionQualifier.class, new VersionEdit(mQualifierEditParent));
-    }
-
-    /**
-     * Sets a {@link IQualifierFilter}. If non null, this will restrict the qualifiers that
-     * can be chosen.
-     * @param filter the filter to set.
-     */
-    public void setQualifierFilter(IQualifierFilter filter) {
-        mQualifierFilter = filter;
-    }
-
-    /**
-     * Sets a listener to be notified when the configuration changes.
-     * @param listener A {@link Runnable} whose <code>run()</code> method is called when the
-     * configuration is changed. The method is called from the UI thread.
-     */
-    public void setOnChangeListener(Runnable listener) {
-        mOnChangeListener = listener;
-    }
-
-    /**
-     * Initialize the UI with a given {@link FolderConfiguration}. This must
-     * be called from the UI thread.
-     * @param config The configuration.
-     */
-    public void setConfiguration(FolderConfiguration config) {
-        mSelectedConfiguration.set(config);
-        mSelectionTableViewer.refresh();
-
-        // create the base config, which is the default config minus the qualifiers
-        // in SelectedConfiguration
-        mBaseConfiguration.substract(mSelectedConfiguration);
-        mFullTableViewer.refresh();
-    }
-
-    /**
-     * Initialize the UI with the configuration represented by a resource folder name.
-     * This must be called from the UI thread.
-     *
-     * @param folderSegments the segments of the folder name,
-     *                       split using {@link FolderConfiguration#QUALIFIER_SEP}.
-     * @return true if success, or false if the folder name is not a valid name.
-     */
-    public boolean setConfiguration(String[] folderSegments) {
-        FolderConfiguration config = ResourceManager.getInstance().getConfig(folderSegments);
-
-        if (config == null) {
-            return false;
-        }
-
-        setConfiguration(config);
-
-        return true;
-    }
-
-    /**
-     * Initialize the UI with the configuration represented by a resource folder name.
-     * This must be called from the UI thread.
-     * @param folderName the name of the folder.
-     * @return true if success, or false if the folder name is not a valid name.
-     */
-    public boolean setConfiguration(String folderName) {
-        // split the name of the folder in segments.
-        String[] folderSegments = folderName.split(FolderConfiguration.QUALIFIER_SEP);
-
-        return setConfiguration(folderSegments);
-    }
-
-    /**
-     * Gets the configuration as setup by the widget.
-     * @param config the {@link FolderConfiguration} object to be filled with the information
-     * from the UI.
-     */
-    public void getConfiguration(FolderConfiguration config) {
-        config.set(mSelectedConfiguration);
-    }
-
-    /**
-     * Returns the state of the configuration being edited/created.
-     */
-    public ConfigurationState getState() {
-        if (mSelectedConfiguration.getInvalidQualifier() != null) {
-            return ConfigurationState.INVALID_CONFIG;
-        }
-
-        if (mSelectedConfiguration.checkRegion() == false) {
-            return ConfigurationState.REGION_WITHOUT_LANGUAGE;
-        }
-
-        return ConfigurationState.OK;
-    }
-
-    /**
-     * Returns the first invalid qualifier of the configuration being edited/created,
-     * or <code>null<code> if they are all valid (or if none exists).
-     * <p/>If {@link #getState()} return {@link ConfigurationState#INVALID_CONFIG} then this will
-     * not return <code>null</code>.
-     */
-    public ResourceQualifier getInvalidQualifier() {
-        return mSelectedConfiguration.getInvalidQualifier();
-    }
-
-    /**
-     * Handle changes in the configuration.
-     * @param keepSelection if <code>true</code> attemps to avoid triggering selection change in
-     * {@link #mSelectedConfiguration}.
-     */
-    private void onChange(boolean keepSelection) {
-        ISelection selection = null;
-        if (keepSelection) {
-            mOnRefresh = true;
-            selection = mSelectionTableViewer.getSelection();
-        }
-
-        mSelectionTableViewer.refresh(true);
-
-        if (keepSelection) {
-            mSelectionTableViewer.setSelection(selection);
-            mOnRefresh = false;
-        }
-
-        if (mOnChangeListener != null) {
-            mOnChangeListener.run();
-        }
-    }
-
-    /**
-     * Content provider around a {@link FolderConfiguration}.
-     */
-    private class QualifierContentProvider implements IStructuredContentProvider {
-
-        private FolderConfiguration mInput;
-
-        public QualifierContentProvider() {
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public Object[] getElements(Object inputElement) {
-            // default easy case
-            if (mQualifierFilter == null) {
-                return mInput.getQualifiers();
-            }
-
-            // in this case we have to compute the list
-            ArrayList<ResourceQualifier> list = new ArrayList<ResourceQualifier>();
-            for (ResourceQualifier qual : mInput.getQualifiers()) {
-                if (mQualifierFilter.accept(qual)) {
-                    list.add(qual);
-                }
-            }
-
-            return list.toArray();
-        }
-
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            mInput = null;
-            if (newInput instanceof FolderConfiguration) {
-                mInput = (FolderConfiguration)newInput;
-            }
-        }
-    }
-
-    /**
-     * Label provider for {@link ResourceQualifier} objects.
-     */
-    private static class QualifierLabelProvider implements ITableLabelProvider {
-
-        private final boolean mShowQualifierValue;
-
-        public QualifierLabelProvider(boolean showQualifierValue) {
-            mShowQualifierValue = showQualifierValue;
-        }
-
-        public String getColumnText(Object element, int columnIndex) {
-            // only one column, so we can ignore columnIndex
-            if (element instanceof ResourceQualifier) {
-                if (mShowQualifierValue) {
-                    String value = ((ResourceQualifier)element).getStringValue();
-                    if (value.length() == 0) {
-                        return String.format("%1$s (?)",
-                                ((ResourceQualifier)element).getShortName());
-                    } else {
-                        return value;
-                    }
-
-                } else {
-                    return ((ResourceQualifier)element).getShortName();
-                }
-            }
-
-            return null;
-        }
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            // only one column, so we can ignore columnIndex
-            if (element instanceof ResourceQualifier) {
-                return ((ResourceQualifier)element).getIcon();
-            }
-
-            return null;
-        }
-
-        public void addListener(ILabelProviderListener listener) {
-            // pass
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public boolean isLabelProperty(Object element, String property) {
-            // pass
-            return false;
-        }
-
-        public void removeListener(ILabelProviderListener listener) {
-            // pass
-        }
-    }
-
-    /**
-     * Base class for Edit widget for {@link ResourceQualifier}.
-     */
-    private abstract static class QualifierEditBase extends Composite {
-
-        public QualifierEditBase(Composite parent, String title) {
-            super(parent, SWT.NONE);
-            setLayout(new GridLayout(1, false));
-
-            new Label(this, SWT.NONE).setText(title);
-        }
-
-        public abstract void setQualifier(ResourceQualifier qualifier);
-    }
-
-    /**
-     * Edit widget for {@link CountryCodeQualifier}.
-     */
-    private class MCCEdit extends QualifierEditBase {
-
-        private Text mText;
-
-        public MCCEdit(Composite parent) {
-            super(parent, CountryCodeQualifier.NAME);
-
-            mText = new Text(this, SWT.BORDER);
-            mText.addVerifyListener(new MobileCodeVerifier());
-            mText.addModifyListener(new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onTextChange();
-                }
-            });
-
-            mText.addFocusListener(new FocusAdapter() {
-                @Override
-                public void focusLost(FocusEvent e) {
-                    onTextChange();
-                }
-            });
-
-            new Label(this, SWT.NONE).setText("(3 digit code)");
-        }
-
-        private void onTextChange() {
-            String value = mText.getText();
-
-            if (value.length() == 0) {
-                // empty string, means a qualifier with no value.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setCountryCodeQualifier(new CountryCodeQualifier());
-            } else {
-                try {
-                    CountryCodeQualifier qualifier = CountryCodeQualifier.getQualifier(
-                            CountryCodeQualifier.getFolderSegment(Integer.parseInt(value)));
-                    if (qualifier != null) {
-                        mSelectedConfiguration.setCountryCodeQualifier(qualifier);
-                    } else {
-                        // Failure! Looks like the value is wrong
-                        // (for instance not exactly 3 digits).
-                        mSelectedConfiguration.setCountryCodeQualifier(new CountryCodeQualifier());
-                    }
-                } catch (NumberFormatException nfe) {
-                    // Looks like the code is not a number. This should not happen since the text
-                    // field has a VerifyListener that prevents it.
-                    mSelectedConfiguration.setCountryCodeQualifier(new CountryCodeQualifier());
-                }
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            CountryCodeQualifier q = (CountryCodeQualifier)qualifier;
-
-            mText.setText(Integer.toString(q.getCode()));
-        }
-    }
-
-    /**
-     * Edit widget for {@link NetworkCodeQualifier}.
-     */
-    private class MNCEdit extends QualifierEditBase {
-        private Text mText;
-
-        public MNCEdit(Composite parent) {
-            super(parent, NetworkCodeQualifier.NAME);
-
-            mText = new Text(this, SWT.BORDER);
-            mText.addVerifyListener(new MobileCodeVerifier());
-            mText.addModifyListener(new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onTextChange();
-                }
-            });
-            mText.addFocusListener(new FocusAdapter() {
-                @Override
-                public void focusLost(FocusEvent e) {
-                    onTextChange();
-                }
-            });
-
-            new Label(this, SWT.NONE).setText("(1-3 digit code)");
-        }
-
-        private void onTextChange() {
-            String value = mText.getText();
-
-            if (value.length() == 0) {
-                // empty string, means a qualifier with no value.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setNetworkCodeQualifier(new NetworkCodeQualifier());
-            } else {
-                try {
-                    NetworkCodeQualifier qualifier = NetworkCodeQualifier.getQualifier(
-                            NetworkCodeQualifier.getFolderSegment(Integer.parseInt(value)));
-                    if (qualifier != null) {
-                        mSelectedConfiguration.setNetworkCodeQualifier(qualifier);
-                    } else {
-                        // Failure! Looks like the value is wrong
-                        // (for instance not exactly 3 digits).
-                        mSelectedConfiguration.setNetworkCodeQualifier(new NetworkCodeQualifier());
-                    }
-                } catch (NumberFormatException nfe) {
-                    // Looks like the code is not a number. This should not happen since the text
-                    // field has a VerifyListener that prevents it.
-                    mSelectedConfiguration.setNetworkCodeQualifier(new NetworkCodeQualifier());
-                }
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            NetworkCodeQualifier q = (NetworkCodeQualifier)qualifier;
-
-            mText.setText(Integer.toString(q.getCode()));
-        }
-    }
-
-    /**
-     * Edit widget for {@link LanguageQualifier}.
-     */
-    private class LanguageEdit extends QualifierEditBase {
-        private Combo mLanguage;
-
-        public LanguageEdit(Composite parent) {
-            super(parent, LanguageQualifier.NAME);
-
-            mLanguage = new Combo(this, SWT.DROP_DOWN);
-            mLanguage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mLanguage.addVerifyListener(new LanguageRegionVerifier());
-            mLanguage.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onLanguageChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onLanguageChange();
-                }
-            });
-            mLanguage.addModifyListener(new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onLanguageChange();
-                }
-            });
-
-            new Label(this, SWT.NONE).setText("(2 letter code)");
-        }
-
-        private void onLanguageChange() {
-            // update the current config
-            String value = mLanguage.getText();
-
-            if (value.length() == 0) {
-                // empty string, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setLanguageQualifier(new LanguageQualifier());
-            } else {
-                LanguageQualifier qualifier = null;
-                String segment = LanguageQualifier.getFolderSegment(value);
-                if (segment != null) {
-                    qualifier = LanguageQualifier.getQualifier(segment);
-                }
-
-                if (qualifier != null) {
-                    mSelectedConfiguration.setLanguageQualifier(qualifier);
-                } else {
-                    // Failure! Looks like the value is wrong (for instance a one letter string).
-                    mSelectedConfiguration.setLanguageQualifier(new LanguageQualifier());
-                }
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            LanguageQualifier q = (LanguageQualifier)qualifier;
-
-            String value = q.getValue();
-            if (value != null) {
-                mLanguage.setText(value);
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link RegionQualifier}.
-     */
-    private class RegionEdit extends QualifierEditBase {
-        private Combo mRegion;
-
-        public RegionEdit(Composite parent) {
-            super(parent, RegionQualifier.NAME);
-
-            mRegion = new Combo(this, SWT.DROP_DOWN);
-            mRegion.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mRegion.addVerifyListener(new LanguageRegionVerifier());
-            mRegion.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onRegionChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onRegionChange();
-                }
-            });
-            mRegion.addModifyListener(new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onRegionChange();
-                }
-            });
-
-            new Label(this, SWT.NONE).setText("(2 letter code)");
-        }
-
-        private void onRegionChange() {
-            // update the current config
-            String value = mRegion.getText();
-
-            if (value.length() == 0) {
-                // empty string, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setRegionQualifier(new RegionQualifier());
-            } else {
-                RegionQualifier qualifier = null;
-                String segment = RegionQualifier.getFolderSegment(value);
-                if (segment != null) {
-                    qualifier = RegionQualifier.getQualifier(segment);
-                }
-
-                if (qualifier != null) {
-                    mSelectedConfiguration.setRegionQualifier(qualifier);
-                } else {
-                    // Failure! Looks like the value is wrong (for instance a one letter string).
-                    mSelectedConfiguration.setRegionQualifier(new RegionQualifier());
-                }
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            RegionQualifier q = (RegionQualifier)qualifier;
-
-            String value = q.getValue();
-            if (value != null) {
-                mRegion.setText(q.getValue());
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link ScreenSizeQualifier}.
-     */
-    private class ScreenSizeEdit extends QualifierEditBase {
-
-        private Combo mSize;
-
-        public ScreenSizeEdit(Composite parent) {
-            super(parent, ScreenSizeQualifier.NAME);
-
-            mSize = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            ScreenSize[] ssValues = ScreenSize.values();
-            for (ScreenSize value : ssValues) {
-                mSize.add(value.getDisplayValue());
-            }
-
-            mSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mSize.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onScreenSizeChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onScreenSizeChange();
-                }
-            });
-        }
-
-        protected void onScreenSizeChange() {
-            // update the current config
-            int index = mSize.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setScreenSizeQualifier(new ScreenSizeQualifier(
-                    ScreenSize.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setScreenSizeQualifier(
-                        new ScreenSizeQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            ScreenSizeQualifier q = (ScreenSizeQualifier)qualifier;
-
-            ScreenSize value = q.getValue();
-            if (value == null) {
-                mSize.clearSelection();
-            } else {
-                mSize.select(ScreenSize.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link ScreenRatioQualifier}.
-     */
-    private class ScreenRatioEdit extends QualifierEditBase {
-
-        private Combo mSize;
-
-        public ScreenRatioEdit(Composite parent) {
-            super(parent, ScreenRatioQualifier.NAME);
-
-            mSize = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            ScreenRatio[] srValues = ScreenRatio.values();
-            for (ScreenRatio value : srValues) {
-                mSize.add(value.getDisplayValue());
-            }
-
-            mSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mSize.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onScreenRatioChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onScreenRatioChange();
-                }
-            });
-        }
-
-        protected void onScreenRatioChange() {
-            // update the current config
-            int index = mSize.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setScreenRatioQualifier(new ScreenRatioQualifier(
-                        ScreenRatio.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setScreenRatioQualifier(
-                        new ScreenRatioQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            ScreenRatioQualifier q = (ScreenRatioQualifier)qualifier;
-
-            ScreenRatio value = q.getValue();
-            if (value == null) {
-                mSize.clearSelection();
-            } else {
-                mSize.select(ScreenRatio.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link ScreenOrientationQualifier}.
-     */
-    private class OrientationEdit extends QualifierEditBase {
-
-        private Combo mOrientation;
-
-        public OrientationEdit(Composite parent) {
-            super(parent, ScreenOrientationQualifier.NAME);
-
-            mOrientation = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            ScreenOrientation[] soValues = ScreenOrientation.values();
-            for (ScreenOrientation value : soValues) {
-                mOrientation.add(value.getDisplayValue());
-            }
-
-            mOrientation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mOrientation.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onOrientationChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onOrientationChange();
-                }
-            });
-        }
-
-        protected void onOrientationChange() {
-            // update the current config
-            int index = mOrientation.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setScreenOrientationQualifier(new ScreenOrientationQualifier(
-                    ScreenOrientation.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setScreenOrientationQualifier(
-                        new ScreenOrientationQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            ScreenOrientationQualifier q = (ScreenOrientationQualifier)qualifier;
-
-            ScreenOrientation value = q.getValue();
-            if (value == null) {
-                mOrientation.clearSelection();
-            } else {
-                mOrientation.select(ScreenOrientation.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link PixelDensityQualifier}.
-     */
-    private class PixelDensityEdit extends QualifierEditBase {
-        private Combo mDensity;
-
-        public PixelDensityEdit(Composite parent) {
-            super(parent, PixelDensityQualifier.NAME);
-
-            mDensity = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            Density[] soValues = Density.values();
-            for (Density value : soValues) {
-                if (mDeviceMode == false || value != Density.NODPI) {
-                    mDensity.add(value.getDisplayValue());
-                }
-            }
-
-            mDensity.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mDensity.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onDensityChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onDensityChange();
-                }
-            });
-        }
-
-        private void onDensityChange() {
-            // update the current config
-            int index = mDensity.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setPixelDensityQualifier(new PixelDensityQualifier(
-                    Density.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setPixelDensityQualifier(
-                        new PixelDensityQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            PixelDensityQualifier q = (PixelDensityQualifier)qualifier;
-
-            Density value = q.getValue();
-            if (value == null) {
-                mDensity.clearSelection();
-            } else {
-                mDensity.select(Density.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link TouchScreenQualifier}.
-     */
-    private class TouchEdit extends QualifierEditBase {
-
-        private Combo mTouchScreen;
-
-        public TouchEdit(Composite parent) {
-            super(parent, TouchScreenQualifier.NAME);
-
-            mTouchScreen = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            TouchScreenType[] tstValues = TouchScreenType.values();
-            for (TouchScreenType value : tstValues) {
-                mTouchScreen.add(value.getDisplayValue());
-            }
-
-            mTouchScreen.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mTouchScreen.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onTouchChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onTouchChange();
-                }
-            });
-        }
-
-        protected void onTouchChange() {
-            // update the current config
-            int index = mTouchScreen.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setTouchTypeQualifier(new TouchScreenQualifier(
-                        TouchScreenType.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setTouchTypeQualifier(new TouchScreenQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            TouchScreenQualifier q = (TouchScreenQualifier)qualifier;
-
-            TouchScreenType value = q.getValue();
-            if (value == null) {
-                mTouchScreen.clearSelection();
-            } else {
-                mTouchScreen.select(TouchScreenType.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link KeyboardStateQualifier}.
-     */
-    private class KeyboardEdit extends QualifierEditBase {
-
-        private Combo mKeyboard;
-
-        public KeyboardEdit(Composite parent) {
-            super(parent, KeyboardStateQualifier.NAME);
-
-            mKeyboard = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            KeyboardState[] ksValues = KeyboardState.values();
-            for (KeyboardState value : ksValues) {
-                mKeyboard.add(value.getDisplayValue());
-            }
-
-            mKeyboard.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mKeyboard.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onKeyboardChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onKeyboardChange();
-                }
-            });
-        }
-
-        protected void onKeyboardChange() {
-            // update the current config
-            int index = mKeyboard.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setKeyboardStateQualifier(new KeyboardStateQualifier(
-                        KeyboardState.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setKeyboardStateQualifier(
-                        new KeyboardStateQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            KeyboardStateQualifier q = (KeyboardStateQualifier)qualifier;
-
-            KeyboardState value = q.getValue();
-            if (value == null) {
-                mKeyboard.clearSelection();
-            } else {
-                mKeyboard.select(KeyboardState.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link TextInputMethodQualifier}.
-     */
-    private class TextInputEdit extends QualifierEditBase {
-
-        private Combo mTextInput;
-
-        public TextInputEdit(Composite parent) {
-            super(parent, TextInputMethodQualifier.NAME);
-
-            mTextInput = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            TextInputMethod[] timValues = TextInputMethod.values();
-            for (TextInputMethod value : timValues) {
-                mTextInput.add(value.getDisplayValue());
-            }
-
-            mTextInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mTextInput.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onTextInputChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onTextInputChange();
-                }
-            });
-        }
-
-        protected void onTextInputChange() {
-            // update the current config
-            int index = mTextInput.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setTextInputMethodQualifier(new TextInputMethodQualifier(
-                        TextInputMethod.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setTextInputMethodQualifier(
-                        new TextInputMethodQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            TextInputMethodQualifier q = (TextInputMethodQualifier)qualifier;
-
-            TextInputMethod value = q.getValue();
-            if (value == null) {
-                mTextInput.clearSelection();
-            } else {
-                mTextInput.select(TextInputMethod.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link NavigationMethodQualifier}.
-     */
-    private class NavigationEdit extends QualifierEditBase {
-
-        private Combo mNavigation;
-
-        public NavigationEdit(Composite parent) {
-            super(parent, NavigationMethodQualifier.NAME);
-
-            mNavigation = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
-            NavigationMethod[] nmValues = NavigationMethod.values();
-            for (NavigationMethod value : nmValues) {
-                mNavigation.add(value.getDisplayValue());
-            }
-
-            mNavigation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mNavigation.addSelectionListener(new SelectionListener() {
-                public void widgetDefaultSelected(SelectionEvent e) {
-                    onNavigationChange();
-                }
-                public void widgetSelected(SelectionEvent e) {
-                    onNavigationChange();
-                }
-            });
-        }
-
-        protected void onNavigationChange() {
-            // update the current config
-            int index = mNavigation.getSelectionIndex();
-
-            if (index != -1) {
-                mSelectedConfiguration.setNavigationMethodQualifier(new NavigationMethodQualifier(
-                        NavigationMethod.getByIndex(index)));
-            } else {
-                // empty selection, means no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setNavigationMethodQualifier(
-                        new NavigationMethodQualifier());
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            NavigationMethodQualifier q = (NavigationMethodQualifier)qualifier;
-
-            NavigationMethod value = q.getValue();
-            if (value == null) {
-                mNavigation.clearSelection();
-            } else {
-                mNavigation.select(NavigationMethod.getIndex(value));
-            }
-        }
-    }
-
-    /**
-     * Edit widget for {@link ScreenDimensionQualifier}.
-     */
-    private class ScreenDimensionEdit extends QualifierEditBase {
-
-        private Text mSize1;
-        private Text mSize2;
-
-        public ScreenDimensionEdit(Composite parent) {
-            super(parent, ScreenDimensionQualifier.NAME);
-
-            ModifyListener modifyListener = new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onSizeChange();
-                }
-            };
-
-            FocusAdapter focusListener = new FocusAdapter() {
-                @Override
-                public void focusLost(FocusEvent e) {
-                    onSizeChange();
-                }
-            };
-
-            mSize1 = new Text(this, SWT.BORDER);
-            mSize1.addVerifyListener(new DimensionVerifier());
-            mSize1.addModifyListener(modifyListener);
-            mSize1.addFocusListener(focusListener);
-
-            mSize2 = new Text(this, SWT.BORDER);
-            mSize2.addVerifyListener(new DimensionVerifier());
-            mSize2.addModifyListener(modifyListener);
-            mSize2.addFocusListener(focusListener);
-        }
-
-        private void onSizeChange() {
-            // update the current config
-            String size1 = mSize1.getText();
-            String size2 = mSize2.getText();
-
-            if (size1.length() == 0 || size2.length() == 0) {
-                // if one of the strings is empty, reset to no qualifier.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setScreenDimensionQualifier(new ScreenDimensionQualifier());
-            } else {
-                ScreenDimensionQualifier qualifier = ScreenDimensionQualifier.getQualifier(size1,
-                        size2);
-
-                if (qualifier != null) {
-                    mSelectedConfiguration.setScreenDimensionQualifier(qualifier);
-                } else {
-                    // Failure! Looks like the value is wrong, reset the qualifier
-                    // Since the qualifier classes are immutable, and we don't want to
-                    // remove the qualifier from the configuration, we create a new default one.
-                    mSelectedConfiguration.setScreenDimensionQualifier(
-                            new ScreenDimensionQualifier());
-                }
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            ScreenDimensionQualifier q = (ScreenDimensionQualifier)qualifier;
-
-            mSize1.setText(Integer.toString(q.getValue1()));
-            mSize2.setText(Integer.toString(q.getValue2()));
-        }
-    }
-
-    /**
-     * Edit widget for {@link VersionQualifier}.
-     */
-    private class VersionEdit extends QualifierEditBase {
-        private Text mText;
-
-        public VersionEdit(Composite parent) {
-            super(parent, VersionQualifier.NAME);
-
-            mText = new Text(this, SWT.BORDER);
-            mText.addVerifyListener(new MobileCodeVerifier());
-            mText.addModifyListener(new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onVersionChange();
-                }
-            });
-            mText.addFocusListener(new FocusAdapter() {
-                @Override
-                public void focusLost(FocusEvent e) {
-                    onVersionChange();
-                }
-            });
-
-            new Label(this, SWT.NONE).setText("(Platform API level)");
-        }
-
-        private void onVersionChange() {
-            String value = mText.getText();
-
-            if (value.length() == 0) {
-                // empty string, means a qualifier with no value.
-                // Since the qualifier classes are immutable, and we don't want to
-                // remove the qualifier from the configuration, we create a new default one.
-                mSelectedConfiguration.setVersionQualifier(new VersionQualifier());
-            } else {
-                try {
-                    VersionQualifier qualifier = VersionQualifier.getQualifier(
-                            VersionQualifier.getFolderSegment(Integer.parseInt(value)));
-                    if (qualifier != null) {
-                        mSelectedConfiguration.setVersionQualifier(qualifier);
-                    } else {
-                        // Failure! Looks like the value is wrong
-                        mSelectedConfiguration.setVersionQualifier(new VersionQualifier());
-                    }
-                } catch (NumberFormatException nfe) {
-                    // Looks like the code is not a number. This should not happen since the text
-                    // field has a VerifyListener that prevents it.
-                    mSelectedConfiguration.setVersionQualifier(new VersionQualifier());
-                }
-            }
-
-            // notify of change
-            onChange(true /* keepSelection */);
-        }
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            VersionQualifier q = (VersionQualifier)qualifier;
-
-            mText.setText(Integer.toString(q.getVersion()));
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/EclipseUiHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/EclipseUiHelper.java
deleted file mode 100644
index f0fd231..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/EclipseUiHelper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * Helpers for Eclipse UI related stuff.
- */
-public final class EclipseUiHelper {
-
-    /** View Id for the default Eclipse Content Outline view. */
-    public static final String CONTENT_OUTLINE_VIEW_ID = "org.eclipse.ui.views.ContentOutline";
-    /** View Id for the default Eclipse Property Sheet view. */
-    public static final String PROPERTY_SHEET_VIEW_ID  = "org.eclipse.ui.views.PropertySheet";
-    
-    /** This class never gets instantiated. */
-    private EclipseUiHelper() {
-    }
-    
-    /**
-     * Shows the corresponding view.
-     * <p/>
-     * Silently fails in case of error.
-     * 
-     * @param viewId One of {@link #CONTENT_OUTLINE_VIEW_ID}, {@link #PROPERTY_SHEET_VIEW_ID}.
-     * @param activate True to force activate (i.e. takes focus), false to just make visible (i.e.
-     *                 does not steal focus.)
-     */
-    public static void showView(String viewId, boolean activate) {
-        IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-        if (win != null) {
-            IWorkbenchPage page = win.getActivePage();
-            if (page != null) {
-                try {
-                    IViewPart part = page.showView(viewId,
-                            null /* secondaryId */,
-                            activate ? IWorkbenchPage.VIEW_ACTIVATE : IWorkbenchPage.VIEW_VISIBLE);
-                } catch (PartInitException e) {
-                    // ignore
-                }
-            }
-        }
-        
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/IUpdateWizardDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/IUpdateWizardDialog.java
deleted file mode 100755
index 1aa8c2f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/IUpdateWizardDialog.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import org.eclipse.jface.wizard.WizardDialog;
-
-
-/**
- * An interface that enables a client to update {@link WizardDialog} after its creation.
- */
-public interface IUpdateWizardDialog {
-    /**
-     * Invoked after {@link WizardDialog#create()} to let the caller update the dialog.
-     */
-    public void updateWizardDialog(WizardDialogEx dialog);
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ReferenceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ReferenceChooserDialog.java
deleted file mode 100644
index ba4be6a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ReferenceChooserDialog.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringRefactoring;
-import com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringWizard;
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.DialogSettings;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.FilteredTree;
-import org.eclipse.ui.dialogs.PatternFilter;
-import org.eclipse.ui.dialogs.SelectionStatusDialog;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A dialog to let the user choose a reference to a resource.
- *
- */
-public class ReferenceChooserDialog extends SelectionStatusDialog {
-
-    private static Pattern sResourcePattern = Pattern.compile("@(.*)/(.+)"); //$NON-NLS-1$
-    private static Pattern sInlineIdResourcePattern = Pattern.compile("@\\+id/(.+)"); //$NON-NLS-1$
-
-    private static IDialogSettings sDialogSettings = new DialogSettings("");
-    
-    private IResourceRepository mResources;
-    private String mCurrentResource;
-    private FilteredTree mFilteredTree;
-    private Button mNewResButton;
-    private final IProject mProject;
-    private TreeViewer mTreeViewer;
-
-    /**
-     * @param project 
-     * @param parent
-     */
-    public ReferenceChooserDialog(IProject project, IResourceRepository resources, Shell parent) {
-        super(parent);
-        mProject = project;
-        mResources = resources;
-
-        int shellStyle = getShellStyle();
-        setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
-
-        setTitle("Reference Chooser");
-        setMessage(String.format("Choose a resource"));
-        
-        setDialogBoundsSettings(sDialogSettings, getDialogBoundsStrategy());
-    }
-
-    public void setCurrentResource(String resource) {
-        mCurrentResource = resource;
-    }
-    
-    public String getCurrentResource() {
-        return mCurrentResource;
-    }
-
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult()
-     */
-    @Override
-    protected void computeResult() {
-        // get the selection
-        TreePath treeSelection = getSelection();
-        if (treeSelection != null) {
-            if (treeSelection.getSegmentCount() == 2) {
-                // get the resource type and the resource item
-                ResourceType resourceType = (ResourceType)treeSelection.getFirstSegment();
-                ResourceItem resourceItem = (ResourceItem)treeSelection.getLastSegment();
-                
-                mCurrentResource = resourceType.getXmlString(resourceItem, false /* system */); 
-            }
-        }
-    }
-    
-    @Override
-    protected Control createDialogArea(Composite parent) {
-        Composite top = (Composite)super.createDialogArea(parent);
-
-        // create the standard message area
-        createMessageArea(top);
-
-        // create the filtered tree
-        createFilteredTree(top);
-
-        // setup the initial selection
-        setupInitialSelection();
-        
-        // create the "New Resource" button
-        createNewResButtons(top);
-        
-        return top;
-    }
-
-    /**
-     * Creates the "New Resource" button.
-     * @param top the parent composite
-     */
-    private void createNewResButtons(Composite top) {
-        mNewResButton = new Button(top, SWT.NONE);
-        mNewResButton.addSelectionListener(new OnNewResButtonSelected());
-        updateNewResButton();
-    }
-
-    private void createFilteredTree(Composite parent) {
-        mFilteredTree = new FilteredTree(parent, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION,
-                new PatternFilter());
-        
-        GridData data = new GridData();
-        data.widthHint = convertWidthInCharsToPixels(60);
-        data.heightHint = convertHeightInCharsToPixels(18);
-        data.grabExcessVerticalSpace = true;
-        data.grabExcessHorizontalSpace = true;
-        data.horizontalAlignment = GridData.FILL;
-        data.verticalAlignment = GridData.FILL;
-        mFilteredTree.setLayoutData(data);
-        mFilteredTree.setFont(parent.getFont());
-        
-        mTreeViewer = mFilteredTree.getViewer();
-        Tree tree = mTreeViewer.getTree();
-        
-        tree.addSelectionListener(new SelectionListener() {
-            public void widgetDefaultSelected(SelectionEvent e) {
-                handleDoubleClick();
-            }
-
-            public void widgetSelected(SelectionEvent e) {
-                handleSelection();
-            }
-        });
-        
-        mTreeViewer.setLabelProvider(new ResourceLabelProvider());
-        mTreeViewer.setContentProvider(new ResourceContentProvider(false /* fullLevels */));
-        mTreeViewer.setInput(mResources);
-    }
-
-    protected void handleSelection() {
-        validateCurrentSelection();
-        updateNewResButton();
-    }
-
-    protected void handleDoubleClick() {
-        if (validateCurrentSelection()) {
-            buttonPressed(IDialogConstants.OK_ID);
-        }
-    }
-    
-    /**
-     * Returns the selected item in the tree as a {@link TreePath} object.
-     * @return the <code>TreePath</code> object or <code>null</code> if there was no selection.
-     */
-    private TreePath getSelection() {
-        ISelection selection = mFilteredTree.getViewer().getSelection();
-        if (selection instanceof TreeSelection) {
-            TreeSelection treeSelection = (TreeSelection)selection;
-            TreePath[] treePaths = treeSelection.getPaths();
-            
-            // the selection mode is SWT.SINGLE, so we just get the first one.
-            if (treePaths.length > 0) {
-                return treePaths[0];
-            }
-        }
-        
-        return null;
-    }
-    
-    private boolean validateCurrentSelection() {
-        TreePath treeSelection = getSelection();
-        
-        IStatus status;
-        if (treeSelection != null) {
-            if (treeSelection.getSegmentCount() == 2) {
-                status = new Status(IStatus.OK, AdtPlugin.PLUGIN_ID,
-                        IStatus.OK, "", //$NON-NLS-1$
-                        null);
-            } else {
-                status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                        IStatus.ERROR, "You must select a Resource Item",
-                        null);
-            }
-        } else {
-            status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-                    IStatus.ERROR, "", //$NON-NLS-1$
-                    null);
-        }
-        
-        updateStatus(status);
-
-        return status.isOK();
-    }
-
-    /**
-     * Updates the new res button when the list selection changes.
-     * The name of the button changes depending on the resource.
-     */
-    private void updateNewResButton() {
-        ResourceType type = getSelectedResourceType();
-        
-        // We only support adding new strings right now
-        mNewResButton.setEnabled(type == ResourceType.STRING);
-        
-        String title = String.format("New %1$s...",
-                type == null ? "Resource" : type.getDisplayName());
-        mNewResButton.setText(title);
-        mNewResButton.pack();
-    }
-
-    /**
-     * Callback invoked when the mNewResButton is selected by the user.
-     */
-    private class OnNewResButtonSelected extends SelectionAdapter {
-        @Override
-         public void widgetSelected(SelectionEvent e) {
-             super.widgetSelected(e);
-             
-             ResourceType type = getSelectedResourceType();
-
-             // We currently only support strings
-             if (type == ResourceType.STRING) {
-
-                 ExtractStringRefactoring ref = new ExtractStringRefactoring(
-                         mProject, true /*enforceNew*/);
-                 RefactoringWizard wizard = new ExtractStringWizard(ref, mProject);
-                 RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
-                 try {
-                     IWorkbench w = PlatformUI.getWorkbench();
-                     if (op.run(w.getDisplay().getActiveShell(), wizard.getDefaultPageTitle()) ==
-                             IDialogConstants.OK_ID) {
-                         mTreeViewer.refresh();
-                         
-                         // select it if possible
-                         setupInitialSelection(type, ref.getXmlStringId());
-                     }
-                 } catch (InterruptedException ex) {
-                     // Interrupted. Pass.
-                 }
-             }
-         } 
-     }
-
-    /**
-     * Returns the {@link ResourceType} of the selected element, if any.
-     * Returns null if nothing suitable is selected.
-     */
-    private ResourceType getSelectedResourceType() {
-        ResourceType type = null;
-
-        TreePath selection = getSelection();
-        if (selection != null && selection.getSegmentCount() > 0) {
-            Object first = selection.getFirstSegment();
-            if (first instanceof ResourceType) {
-                type = (ResourceType) first;
-            }
-        }
-        return type;
-    }
-    
-    /**
-     * Sets up the initial selection.
-     * <p/>
-     * This parses {@link #mCurrentResource} to find out the resource type and the resource name.
-     */
-    private void setupInitialSelection() {
-        // checks the inline id pattern first as it's more restrictive than the other one.
-        Matcher m = sInlineIdResourcePattern.matcher(mCurrentResource);
-        if (m.matches()) {
-            // get the matching name
-            String resourceName = m.group(1);
-
-            // setup initial selection
-            setupInitialSelection(ResourceType.ID, resourceName);
-        } else {
-            // attempts the inline id pattern
-            m = sResourcePattern.matcher(mCurrentResource);
-            if (m.matches()) {
-                // get the resource type.
-                ResourceType resourceType = ResourceType.getEnum(m.group(1));
-                if (resourceType != null) {
-                    // get the matching name
-                    String resourceName = m.group(2);
-                    
-                    // setup initial selection
-                    setupInitialSelection(resourceType, resourceName);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Sets up the initial selection based on a {@link ResourceType} and a resource name.
-     * @param resourceType the resource type.
-     * @param resourceName the resource name.
-     */
-    private void setupInitialSelection(ResourceType resourceType, String resourceName) {
-        // get all the resources of this type
-        ResourceItem[] resourceItems = mResources.getResources(resourceType);
-        
-        for (ResourceItem resourceItem : resourceItems) {
-            if (resourceName.equals(resourceItem.getName())) {
-                // name of the resource match, we select it,
-                TreePath treePath = new TreePath(new Object[] { resourceType, resourceItem });
-                mFilteredTree.getViewer().setSelection(
-                        new TreeSelection(treePath),
-                        true /*reveal*/);
-                
-                // and we're done.
-                return;
-            }
-        }
-        
-        // if we get here, the resource type is valid, but the resource is missing.
-        // we select and expand the resource type element.
-        TreePath treePath = new TreePath(new Object[] { resourceType });
-        mFilteredTree.getViewer().setSelection(
-                new TreeSelection(treePath),
-                true /*reveal*/);
-        mFilteredTree.getViewer().setExpandedState(resourceType, true /* expanded */);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceChooser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceChooser.java
deleted file mode 100644
index e2b910c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceChooser.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringRefactoring;
-import com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringWizard;
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.AbstractElementListSelectionDialog;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A dialog to let the user select a resource based on a resource type. 
- */
-public class ResourceChooser extends AbstractElementListSelectionDialog {
-
-    private Pattern mProjectResourcePattern;
-
-    private ResourceType mResourceType;
-
-    private IResourceRepository mProjectResources;
-
-    private final static boolean SHOW_SYSTEM_RESOURCE = false;  // TODO re-enable at some point 
-    private Pattern mSystemResourcePattern;
-    private IResourceRepository mSystemResources;
-    private Button mProjectButton;
-    private Button mSystemButton;
-    
-    private String mCurrentResource;
-
-    private final IProject mProject;
-    
-    /**
-     * Creates a Resource Chooser dialog.
-     * @param project Project being worked on
-     * @param type The type of the resource to choose
-     * @param projectResources The repository for the project
-     * @param systemResources The System resource repository
-     * @param parent the parent shell
-     */
-    public ResourceChooser(IProject project, ResourceType type,
-            IResourceRepository projectResources,
-            IResourceRepository systemResources,
-            Shell parent) {
-        super(parent, new ResourceLabelProvider());
-        mProject = project;
-
-        mResourceType = type;
-        mProjectResources = projectResources;
-        
-        mProjectResourcePattern = Pattern.compile(
-                "@" + mResourceType.getName() + "/(.+)"); //$NON-NLS-1$ //$NON-NLS-2$
-
-        if (SHOW_SYSTEM_RESOURCE) {
-            mSystemResources = systemResources;
-            mSystemResourcePattern = Pattern.compile(
-                    "@android:" + mResourceType.getName() + "/(.+)"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        setTitle("Resource Chooser");
-        setMessage(String.format("Choose a %1$s resource",
-                mResourceType.getDisplayName().toLowerCase()));
-    }
-    
-    public void setCurrentResource(String resource) {
-        mCurrentResource = resource;
-    }
-    
-    public String getCurrentResource() {
-        return mCurrentResource;
-    }
-
-    @Override
-    protected void computeResult() {
-        Object[] elements = getSelectedElements();
-        if (elements.length == 1 && elements[0] instanceof ResourceItem) {
-            ResourceItem item = (ResourceItem)elements[0];
-            
-            mCurrentResource = mResourceType.getXmlString(item,
-                    SHOW_SYSTEM_RESOURCE && mSystemButton.getSelection()); 
-        }
-    }
-
-    @Override
-    protected Control createDialogArea(Composite parent) {
-        Composite top = (Composite)super.createDialogArea(parent);
-
-        createMessageArea(top);
-
-        createButtons(top);
-        createFilterText(top);
-        createFilteredList(top);
-        
-        // create the "New Resource" button
-        createNewResButtons(top);
-
-        setupResourceList();
-        selectResourceString(mCurrentResource);
-        
-        return top;
-    }
-
-    /**
-     * Creates the radio button to switch between project and system resources.
-     * @param top the parent composite
-     */
-    private void createButtons(Composite top) {
-        if (!SHOW_SYSTEM_RESOURCE) {
-            return;
-        }
-        mProjectButton = new Button(top, SWT.RADIO);
-        mProjectButton.setText("Project Resources");
-        mProjectButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                if (mProjectButton.getSelection()) {
-                    setListElements(mProjectResources.getResources(mResourceType));
-                }
-            }
-        });
-        mSystemButton = new Button(top, SWT.RADIO);
-        mSystemButton.setText("System Resources");
-        mSystemButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                if (mProjectButton.getSelection()) {
-                    setListElements(mSystemResources.getResources(mResourceType));
-                }
-            }
-        });
-    }
-
-    /**
-     * Creates the "New Resource" button.
-     * @param top the parent composite
-     */
-    private void createNewResButtons(Composite top) {
-        
-        Button newResButton = new Button(top, SWT.NONE);
-
-        String title = String.format("New %1$s...", mResourceType.getDisplayName());
-        newResButton.setText(title);
-
-        // We only support adding new strings right now
-        newResButton.setEnabled(mResourceType == ResourceType.STRING);
-
-        newResButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                
-                if (mResourceType == ResourceType.STRING) {
-                    createNewString();
-                }
-            }
-        });
-    }
-    
-    private void createNewString() {
-        ExtractStringRefactoring ref = new ExtractStringRefactoring(
-                mProject, true /*enforceNew*/);
-        RefactoringWizard wizard = new ExtractStringWizard(ref, mProject);
-        RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
-        try {
-            IWorkbench w = PlatformUI.getWorkbench();
-            if (op.run(w.getDisplay().getActiveShell(), wizard.getDefaultPageTitle()) ==
-                    IDialogConstants.OK_ID) {
-
-                // Recompute the "current resource" to select the new id
-                setupResourceList();
-                
-                // select it if possible
-                selectItemName(ref.getXmlStringId());
-            }
-        } catch (InterruptedException ex) {
-            // Interrupted. Pass.
-        }
-    }
-
-    /**
-     * @return The repository currently selected.
-     */
-    private IResourceRepository getCurrentRepository() {
-        IResourceRepository repo = mProjectResources;
-        
-        if (SHOW_SYSTEM_RESOURCE && mSystemButton.getSelection()) {
-            repo = mSystemResources;
-        }
-        return repo;
-    }
-
-    /**
-     * Setups the current list.
-     */
-    private void setupResourceList() {
-        IResourceRepository repo = getCurrentRepository();
-        setListElements(repo.getResources(mResourceType));
-    }
-    
-    /**
-     * Select an item by its name, if possible.
-     */
-    private void selectItemName(String itemName) {
-        if (itemName == null) {
-            return;
-        }
-
-        IResourceRepository repo = getCurrentRepository();
-
-        ResourceItem[] items = repo.getResources(mResourceType); 
-        
-        for (ResourceItem item : items) {
-            if (itemName.equals(item.getName())) {
-                setSelection(new Object[] { item });
-                break;
-            }
-        }
-    }
-
-    /**
-     * Select an item by its full resource string.
-     * This also selects between project and system repository based on the resource string.
-     */
-    private void selectResourceString(String resourceString) {
-        boolean isSystem = false;
-        String itemName = null;
-        
-        // Is this a system resource?
-        // If not a system resource or if they are not available, this will be a project res.
-        if (SHOW_SYSTEM_RESOURCE) {
-            Matcher m = mSystemResourcePattern.matcher(resourceString);
-            if (m.matches()) {
-                itemName = m.group(1);
-                isSystem = true;
-            }
-        }
-
-        if (!isSystem && itemName == null) {
-            // Try to match project resource name
-            Matcher m = mProjectResourcePattern.matcher(resourceString);
-            if (m.matches()) {
-                itemName = m.group(1);
-            }
-        }
-        
-        // Update the repository selection
-        if (SHOW_SYSTEM_RESOURCE) {
-            mProjectButton.setSelection(!isSystem);
-            mSystemButton.setSelection(isSystem);
-        }
-
-        // Update the list
-        setupResourceList();
-        
-        // If we have a selection name, select it
-        if (itemName != null) {
-            selectItemName(itemName);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceContentProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceContentProvider.java
deleted file mode 100644
index 4442b71..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceContentProvider.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ConfigurableResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile;
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Content provider for the Resource Explorer TreeView.
- * Each level of the tree is represented by a different class.
- * <ul>
- * <li>{@link ResourceType}. This represents the list of existing Resource Type present
- * in the resources. This can be matched to the subclasses inside the class <code>R</code>
- * </li>
- * <ul>
- * <li>{@link ResourceItem}. This represents one resource (which can existing in various alternate
- * versions). This is similar to the resource Ids defined as <code>R.sometype.id</code>.
- * </li>
- * <ul>
- * <li>{@link ResourceFile}. (optional) This represents a particular version of the
- * {@link ResourceItem}. It is displayed as a list of resource qualifier.
- * </li>
- * </ul> 
- * </ul> 
- * </ul> 
- * 
- * @see ResourceLabelProvider
- */
-public class ResourceContentProvider implements ITreeContentProvider {
-
-    /**
-     * The current ProjectResources being displayed.
-     */
-    private IResourceRepository mResources;
-    
-    private boolean mFullLevels;
-    
-   /**
-     * Constructs a new content providers for resource display.
-     * @param fullLevels if <code>true</code> the content provider will suppport all 3 levels. If
-     * <code>false</code>, only two levels are provided.
-     */
-    public ResourceContentProvider(boolean fullLevels) {
-        mFullLevels = fullLevels;
-    }
-
-    public Object[] getChildren(Object parentElement) {
-        if (parentElement instanceof ResourceType) {
-            return mResources.getResources((ResourceType)parentElement);
-        } else if (mFullLevels && parentElement instanceof ConfigurableResourceItem) {
-            return ((ConfigurableResourceItem)parentElement).getSourceFileArray();
-        }
-        return null;
-    }
-
-    public Object getParent(Object element) {
-        // pass
-        return null;
-    }
-
-    public boolean hasChildren(Object element) {
-        if (element instanceof ResourceType) {
-            return mResources.hasResources((ResourceType)element);
-        } else if (mFullLevels && element instanceof ConfigurableResourceItem) {
-            return ((ConfigurableResourceItem)element).hasAlternates();
-        }
-        return false;
-    }
-
-    public Object[] getElements(Object inputElement) {
-        if (inputElement instanceof IResourceRepository) {
-            if ((IResourceRepository)inputElement == mResources) {
-                // get the top level resources.
-                return mResources.getAvailableResourceTypes();
-            }
-        }
-
-        return new Object[0];
-    }
-
-    public void dispose() {
-        // pass
-    }
-
-    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-        if (newInput instanceof IResourceRepository) {
-             mResources = (IResourceRepository)newInput;
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java
deleted file mode 100644
index 23eb1ec..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IResourceEventListener;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.ide.IDE;
-import org.eclipse.ui.part.ViewPart;
-
-import java.util.Iterator;
-
-/**
- * Resource Explorer View.
- * <p/>
- * This contains a basic Tree view, and uses a TreeViewer to handle the data.
- * <p/>
- * The view listener to change in selection in the workbench, and update to show the resource
- * of the project of the current selected item (either item in the package explorer, or of the
- * current editor).
- * 
- * @see ResourceContentProvider
- */
-public class ResourceExplorerView extends ViewPart implements ISelectionListener,
-        IResourceEventListener {
-    
-    // Note: keep using the obsolete AndroidConstants.EDITORS_NAMESPACE (which used
-    // to be the Editors Plugin ID) to keep existing preferences functional.
-    private final static String PREFS_COLUMN_RES =
-        AndroidConstants.EDITORS_NAMESPACE + "ResourceExplorer.Col1"; //$NON-NLS-1$
-    private final static String PREFS_COLUMN_2 =
-        AndroidConstants.EDITORS_NAMESPACE + "ResourceExplorer.Col2"; //$NON-NLS-1$
-
-    private Tree mTree;
-    private TreeViewer mTreeViewer;
-    
-    private IProject mCurrentProject;
-
-    public ResourceExplorerView() {
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mTree = new Tree(parent, SWT.SINGLE | SWT.VIRTUAL);
-        mTree.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mTree.setHeaderVisible(true);
-        mTree.setLinesVisible(true);
-
-        final IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
-
-        // create 2 columns. The main one with the resources, and an "info" column.
-        createTreeColumn(mTree, "Resources", SWT.LEFT,
-                "abcdefghijklmnopqrstuvwxz", -1, PREFS_COLUMN_RES, store); //$NON-NLS-1$
-        createTreeColumn(mTree, "Info", SWT.LEFT,
-                "0123456789", -1, PREFS_COLUMN_2, store); //$NON-NLS-1$
-
-        // create the jface wrapper
-        mTreeViewer = new TreeViewer(mTree);
-        
-        mTreeViewer.setContentProvider(new ResourceContentProvider(true /* fullLevels */));
-        mTreeViewer.setLabelProvider(new ResourceLabelProvider());
-        
-        // listen to selection change in the workbench.
-        IWorkbenchPage page = getSite().getPage();
-        
-        page.addSelectionListener(this);
-        
-        // init with current selection
-        selectionChanged(getSite().getPart(), page.getSelection());
-        
-        // add support for double click.
-        mTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
-            public void doubleClick(DoubleClickEvent event) {
-                ISelection sel = event.getSelection();
-
-                if (sel instanceof IStructuredSelection) {
-                    IStructuredSelection selection = (IStructuredSelection) sel;
-
-                    if (selection.size() == 1) {
-                        Object element = selection.getFirstElement();
-                        
-                        // if it's a resourceFile, we directly open it.
-                        if (element instanceof ResourceFile) {
-                            try {
-                                IDE.openEditor(getSite().getWorkbenchWindow().getActivePage(),
-                                        ((ResourceFile)element).getFile().getIFile());
-                            } catch (PartInitException e) {
-                            }
-                        } else if (element instanceof ProjectResourceItem) {
-                            // if it's a ResourceItem, we open the first file, but only if
-                            // there's no alternate files.
-                            ProjectResourceItem item = (ProjectResourceItem)element;
-                            
-                            if (item.isEditableDirectly()) {
-                                ResourceFile[] files = item.getSourceFileArray();
-                                if (files[0] != null) {
-                                    try {
-                                        IDE.openEditor(
-                                                getSite().getWorkbenchWindow().getActivePage(),
-                                                files[0].getFile().getIFile());
-                                    } catch (PartInitException e) {
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        });
-        
-        // set up the resource manager to send us resource change notification
-        AdtPlugin.getDefault().getResourceMonitor().addResourceEventListener(this);
-    }
-    
-    @Override
-    public void dispose() {
-        AdtPlugin.getDefault().getResourceMonitor().removeResourceEventListener(this);
-
-        super.dispose();
-    }
-
-    @Override
-    public void setFocus() {
-        mTree.setFocus();
-    }
-
-    /**
-     * Processes a new selection.
-     */
-    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
-        // first we test if the part is an editor.
-        if (part instanceof IEditorPart) {
-            // if it is, we check if it's a file editor.
-            IEditorInput input = ((IEditorPart)part).getEditorInput();
-            
-            if (input instanceof IFileEditorInput) {
-                // from the file editor we can get the IFile object, and from it, the IProject.
-                IFile file = ((IFileEditorInput)input).getFile();
-                
-                // get the file project
-                IProject project = file.getProject();
-                
-                handleProjectSelection(project);
-            }
-        } else if (selection instanceof IStructuredSelection) {
-            // if it's not an editor, we look for structured selection.
-            for (Iterator<?> it = ((IStructuredSelection) selection).iterator();
-                    it.hasNext();) {
-                Object element = it.next();
-                IProject project = null;
-                
-                // if we are in the navigator or package explorer, the selection could contain a
-                // IResource object.
-                if (element instanceof IResource) {
-                    project = ((IResource) element).getProject();
-                } else if (element instanceof IJavaElement) {
-                    // if we are in the package explorer on a java element, we handle that too.
-                    IJavaElement javaElement = (IJavaElement)element;
-                    IJavaProject javaProject = javaElement.getJavaProject();
-                    if (javaProject != null) {
-                        project = javaProject.getProject();
-                    }
-                } else if (element instanceof IAdaptable) {
-                    // finally we try to get a project object from IAdaptable.
-                    project = (IProject) ((IAdaptable) element)
-                            .getAdapter(IProject.class);
-                }
-
-                // if we found a project, handle it, and return.
-                if (project != null) {
-                    if (handleProjectSelection(project)) {
-                        return;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Handles a project selection.
-     * @param project the new selected project
-     * @return true if the project could be processed.
-     */
-    private boolean handleProjectSelection(IProject project) {
-        try {
-            // if it's an android project, then we get its resources, and feed them
-            // to the tree viewer.
-            if (project.hasNature(AndroidConstants.NATURE)) {
-                if (mCurrentProject != project) {
-                    ProjectResources projRes = ResourceManager.getInstance().getProjectResources(
-                            project);
-                    if (projRes != null) {
-                        mTreeViewer.setInput(projRes);
-                        mCurrentProject = project;
-                        return true;
-                    }
-                }
-            }
-        } catch (CoreException e) {
-        }
-        
-        return false;
-    }
-    
-    /**
-     * Create a TreeColumn with the specified parameters. If a
-     * <code>PreferenceStore</code> object and a preference entry name String
-     * object are provided then the column will listen to change in its width
-     * and update the preference store accordingly.
-     *
-     * @param parent The Table parent object
-     * @param header The header string
-     * @param style The column style
-     * @param sample_text A sample text to figure out column width if preference
-     *            value is missing
-     * @param fixedSize a fixed size. If != -1 the column is non resizable
-     * @param pref_name The preference entry name for column width
-     * @param prefs The preference store
-     */
-    public void createTreeColumn(Tree parent, String header, int style,
-            String sample_text, int fixedSize, final String pref_name,
-            final IPreferenceStore prefs) {
-
-        // create the column
-        TreeColumn col = new TreeColumn(parent, style);
-        
-        if (fixedSize != -1) {
-            col.setWidth(fixedSize);
-            col.setResizable(false);
-        } else {
-            // if there is no pref store or the entry is missing, we use the sample
-            // text and pack the column.
-            // Otherwise we just read the width from the prefs and apply it.
-            if (prefs == null || prefs.contains(pref_name) == false) {
-                col.setText(sample_text);
-                col.pack();
-    
-                // init the prefs store with the current value
-                if (prefs != null) {
-                    prefs.setValue(pref_name, col.getWidth());
-                }
-            } else {
-                col.setWidth(prefs.getInt(pref_name));
-            }
-    
-            // if there is a pref store and a pref entry name, then we setup a
-            // listener to catch column resize to put the new width value into the store.
-            if (prefs != null && pref_name != null) {
-                col.addControlListener(new ControlListener() {
-                    public void controlMoved(ControlEvent e) {
-                    }
-    
-                    public void controlResized(ControlEvent e) {
-                        // get the new width
-                        int w = ((TreeColumn)e.widget).getWidth();
-    
-                        // store in pref store
-                        prefs.setValue(pref_name, w);
-                    }
-                });
-            }
-        }
-
-        // set the header
-        col.setText(header);
-    }
-
-    /**
-     * Processes a start in a resource event change.
-     */
-    public void resourceChangeEventStart() {
-        // pass
-    }
-
-    /**
-     * Processes the end of a resource change event.
-     */
-    public void resourceChangeEventEnd() {
-        try {
-            mTree.getDisplay().asyncExec(new Runnable() {
-                public void run() {
-                    if (mTree.isDisposed() == false) {
-                        mTreeViewer.refresh();
-                    }
-                }
-            });
-        } catch (SWTException e) {
-            // display is disposed. nothing to do.
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceLabelProvider.java
deleted file mode 100644
index a67fda4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceLabelProvider.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import com.android.ide.eclipse.adt.internal.resources.IIdResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.ResourceType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ConfigurableResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.manager.IdResourceItem;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile;
-
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * Label provider for the Resource Explorer TreeView.
- * Each level of the tree is represented by a different class.
- * <ul>
- * <li>{@link ResourceType}. This represents the list of existing Resource Type present
- * in the resources. This can be matched to the subclasses inside the class <code>R</code>
- * </li>
- * <ul>
- * <li>{@link ResourceItem}. This represents one resource. The actual type can be
- * {@link ConfigurableResourceItem} (which can exist in various alternate versions),
- * or {@link IdResourceItem}.
- * This is similar to the resource Ids defined as <code>R.sometype.id</code>.
- * </li>
- * <ul>
- * <li>{@link ResourceFile}. This represents a particular version of the {@link ResourceItem}.
- * It is displayed as a list of resource qualifier.
- * </li>
- * </ul> 
- * </ul> 
- * </ul> 
- * 
- * @see ResourceContentProvider
- */
-public class ResourceLabelProvider implements ILabelProvider, ITableLabelProvider {
-    private Image mWarningImage;
-    
-    public ResourceLabelProvider() {
-        mWarningImage = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
-                ISharedImages.IMG_OBJS_WARN_TSK).createImage();
-    }
-
-    /**
-     * @see #getColumnImage(Object, int)
-     */
-    public Image getImage(Object element) {
-        // pass
-        return null;
-    }
-
-    /**
-     * @see #getColumnText(Object, int)
-     */
-    public String getText(Object element) {
-        return getColumnText(element, 0);
-    }
-
-    public void addListener(ILabelProviderListener listener) {
-        // pass
-    }
-
-    public void dispose() {
-        mWarningImage.dispose();
-    }
-
-    public boolean isLabelProperty(Object element, String property) {
-        return false;
-    }
-
-    public void removeListener(ILabelProviderListener listener) {
-        // pass
-    }
-
-    public Image getColumnImage(Object element, int columnIndex) {
-        if (columnIndex == 1) {
-            if (element instanceof ConfigurableResourceItem) {
-                ConfigurableResourceItem item = (ConfigurableResourceItem)element;
-                if (item.hasDefault() == false) {
-                    return mWarningImage;
-                }
-            }
-        }
-        return null;
-    }
-
-    public String getColumnText(Object element, int columnIndex) {
-        switch (columnIndex) {
-            case 0:
-                if (element instanceof ResourceType) {
-                    return ((ResourceType)element).getDisplayName();
-                } else if (element instanceof ResourceItem) {
-                    return ((ResourceItem)element).getName();
-                } else if (element instanceof ResourceFile) {
-                    return ((ResourceFile)element).getFolder().getConfiguration().toDisplayString();
-                }
-                break;
-            case 1:
-                if (element instanceof ConfigurableResourceItem) {
-                    ConfigurableResourceItem item = (ConfigurableResourceItem)element;
-                    int count = item.getAlternateCount();
-                    if (count > 0) {
-                        if (item.hasDefault()) {
-                            count++;
-                        }
-                        return String.format("%1$d version(s)", count);
-                    }
-                } else if (element instanceof IIdResourceItem) {
-                    IIdResourceItem idResource = (IIdResourceItem)element;
-                    if (idResource.isDeclaredInline()) {
-                        return "Declared inline";
-                    }
-                }
-                return null;
-        }
-        return null;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/WizardDialogEx.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/WizardDialogEx.java
deleted file mode 100755
index 22141af..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/WizardDialogEx.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.ui;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.wizard.IWizard;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * A {@link WizardDialog} that gives access to some inner controls.
- */
-public final class WizardDialogEx extends WizardDialog {
-
-    /**
-     * @see WizardDialog#WizardDialog(Shell, IWizard)
-     */
-    public WizardDialogEx(Shell parentShell, IWizard newWizard) {
-        super(parentShell, newWizard);
-    }
-
-    /**
-     * Returns the cancel button.
-     * <p/>
-     * Note: there is already a protected, deprecated method that does the same thing.
-     * To avoid overriding a deprecated method, the name as be changed to ...Ex.
-     */
-    public Button getCancelButtonEx() {
-        return getButton(IDialogConstants.CANCEL_ID);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/AvdManagerAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/AvdManagerAction.java
deleted file mode 100755
index edc97fa..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/AvdManagerAction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.actions;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdkuilib.repository.UpdaterWindow;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-
-/**
- * Delegate for the toolbar/menu action "Android AVD Manager".
- * It displays the Android AVD Manager.
- */
-public class AvdManagerAction implements IWorkbenchWindowActionDelegate, IObjectActionDelegate {
-
-    public void dispose() {
-        // nothing to dispose.
-    }
-
-    public void init(IWorkbenchWindow window) {
-        // no init
-    }
-
-    public void run(IAction action) {
-        Sdk sdk = Sdk.getCurrent();
-        if (sdk != null) {
-            UpdaterWindow window = new UpdaterWindow(
-                    AdtPlugin.getDisplay().getActiveShell(),
-                    null /*sdk log*/,
-                    sdk.getSdkLocation(),
-                    false /*userCanChangeSdkRoot*/);
-            window.addListeners(new UpdaterWindow.ISdkListener() {
-                public void onSdkChange() {
-                    AdtPlugin.getDefault().reparseSdk();
-                }
-            });
-            window.open();
-        }
-    }
-
-    public void selectionChanged(IAction action, ISelection selection) {
-        // nothing related to the current selection.
-    }
-
-    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-        // nothing to do.
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java
deleted file mode 100644
index 9093470..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.actions;
-
-import com.android.ide.eclipse.adt.internal.project.ExportHelper;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-
-public class ExportAction implements IObjectActionDelegate {
-
-    private ISelection mSelection;
-
-    /**
-     * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
-     */
-    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-    }
-
-    public void run(IAction action) {
-        if (mSelection instanceof IStructuredSelection) {
-            IStructuredSelection selection = (IStructuredSelection)mSelection;
-            // get the unique selected item.
-            if (selection.size() == 1) {
-                Object element = selection.getFirstElement();
-
-                // get the project object from it.
-                IProject project = null;
-                if (element instanceof IProject) {
-                    project = (IProject) element;
-                } else if (element instanceof IAdaptable) {
-                    project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
-                }
-
-                // and finally do the action
-                if (project != null) {
-                    ExportHelper.exportProject(project);
-                }
-            }
-        }
-    }
-
-    public void selectionChanged(IAction action, ISelection selection) {
-        this.mSelection = selection;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java
deleted file mode 100644
index 8165f97..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.actions;
-
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPart;
-
-public class ExportWizardAction implements IObjectActionDelegate {
-
-    private ISelection mSelection;
-    private IWorkbench mWorkbench;
-
-    /**
-     * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
-     */
-    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-        mWorkbench = targetPart.getSite().getWorkbenchWindow().getWorkbench();
-    }
-
-    public void run(IAction action) {
-        if (mSelection instanceof IStructuredSelection) {
-            IStructuredSelection selection = (IStructuredSelection)mSelection;
-
-            // call the export wizard on the current selection.
-            ExportWizard wizard = new ExportWizard();
-            wizard.init(mWorkbench, selection);
-            WizardDialog dialog = new WizardDialog(mWorkbench.getDisplay().getActiveShell(),
-                    wizard);
-            dialog.open();
-        }
-    }
-
-    public void selectionChanged(IAction action, ISelection selection) {
-        this.mSelection = selection;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java
deleted file mode 100644
index 6bcc479..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.actions;
-
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWizard;
-
-/**
- * Delegate for the toolbar action "Android Project".
- * It displays the Android New Project wizard to create a new Android Project (not a test project).
- *
- * @see NewTestProjectAction
- */
-public class NewProjectAction extends OpenWizardAction {
-
-    @Override
-    protected IWorkbenchWizard instanciateWizard(IAction action) {
-        return new NewProjectWizard();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java
deleted file mode 100755
index c8e45ef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.actions;
-
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWizard;
-
-/**
- * Delegate for the toolbar action "Android Test Project".
- * It displays the Android New Project wizard to create a new Test Project.
- */
-public class NewTestProjectAction extends OpenWizardAction {
-
-    @Override
-    protected IWorkbenchWizard instanciateWizard(IAction action) {
-        return new NewTestProjectWizard();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java
deleted file mode 100644
index ba349c3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.actions;
-
-import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWizard;
-
-/**
- * Delegate for the toolbar action "Android Project" or for the
- * project > Android Project context menu.
- * 
- * It displays the Android New XML file wizard.
- */
-public class NewXmlFileAction extends OpenWizardAction {
-
-    @Override
-    protected IWorkbenchWizard instanciateWizard(IAction action) {
-        return new NewXmlFileWizard();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java
deleted file mode 100644
index 01280cc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.actions;
-
-import com.android.ide.eclipse.adt.internal.ui.IUpdateWizardDialog;
-import com.android.ide.eclipse.adt.internal.ui.WizardDialogEx;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.ui.IWorkbenchWizard;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
-import org.eclipse.ui.internal.LegacyResourceSupport;
-import org.eclipse.ui.internal.actions.NewWizardShortcutAction;
-import org.eclipse.ui.internal.util.Util;
-
-/**
- * An abstract action that displays one of our wizards.
- * Derived classes must provide the actual wizard to display.
- */
-/*package*/ abstract class OpenWizardAction
-    implements IWorkbenchWindowActionDelegate, IObjectActionDelegate {
-
-    /**
-     * The wizard dialog width, extracted from {@link NewWizardShortcutAction}
-     */
-    private static final int SIZING_WIZARD_WIDTH = 500;
-
-    /**
-     * The wizard dialog height, extracted from {@link NewWizardShortcutAction}
-     */
-    private static final int SIZING_WIZARD_HEIGHT = 500;
-
-    /** The wizard that was created by {@link #run(IAction)}. */
-    private IWorkbenchWizard mWizard;
-    /** The result from the dialog */
-    private int mDialogResult;
-
-    private ISelection mSelection;
-    private IWorkbench mWorkbench;
-
-    /** Returns the wizard that was created by {@link #run(IAction)}. */
-    public IWorkbenchWizard getWizard() {
-        return mWizard;
-    }
-
-    /** Returns the result from {@link Dialog#open()}, available after
-     * the completion of {@link #run(IAction)}. */
-    public int getDialogResult() {
-        return mDialogResult;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
-     */
-    public void dispose() {
-        // pass
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
-     */
-    public void init(IWorkbenchWindow window) {
-        // pass
-    }
-
-    /**
-     * Opens and display the Android New Project Wizard.
-     * <p/>
-     * Most of this implementation is extracted from {@link NewWizardShortcutAction#run()}.
-     *
-     * @param action The action that got us here. Can be null when used internally.
-     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
-     */
-    public void run(IAction action) {
-
-        // get the workbench and the current window
-        IWorkbench workbench = mWorkbench != null ? mWorkbench : PlatformUI.getWorkbench();
-        IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
-
-        // This code from NewWizardShortcutAction#run() gets the current window selection
-        // and converts it to a workbench structured selection for the wizard, if possible.
-        ISelection selection = mSelection;
-        if (selection == null) {
-            selection = window.getSelectionService().getSelection();
-        }
-
-        IStructuredSelection selectionToPass = StructuredSelection.EMPTY;
-        if (selection instanceof IStructuredSelection) {
-            selectionToPass = (IStructuredSelection) selection;
-        } else {
-            // Build the selection from the IFile of the editor
-            IWorkbenchPart part = window.getPartService().getActivePart();
-            if (part instanceof IEditorPart) {
-                IEditorInput input = ((IEditorPart) part).getEditorInput();
-                Class<?> fileClass = LegacyResourceSupport.getFileClass();
-                if (input != null && fileClass != null) {
-                    Object file = Util.getAdapter(input, fileClass);
-                    if (file != null) {
-                        selectionToPass = new StructuredSelection(file);
-                    }
-                }
-            }
-        }
-
-        // Create the wizard and initialize it with the selection
-        mWizard = instanciateWizard(action);
-        mWizard.init(workbench, selectionToPass);
-
-        // It's not visible yet until a dialog is created and opened
-        Shell parent = window.getShell();
-        WizardDialogEx dialog = new WizardDialogEx(parent, mWizard);
-        dialog.create();
-
-        if (mWizard instanceof IUpdateWizardDialog) {
-            ((IUpdateWizardDialog) mWizard).updateWizardDialog(dialog);
-        }
-
-        // This code comes straight from NewWizardShortcutAction#run()
-        Point defaultSize = dialog.getShell().getSize();
-        dialog.getShell().setSize(
-                Math.max(SIZING_WIZARD_WIDTH, defaultSize.x),
-                Math.max(SIZING_WIZARD_HEIGHT, defaultSize.y));
-        window.getWorkbench().getHelpSystem().setHelp(dialog.getShell(),
-                IWorkbenchHelpContextIds.NEW_WIZARD_SHORTCUT);
-
-        mDialogResult = dialog.open();
-    }
-
-    /**
-     * Called by {@link #run(IAction)} to instantiate the actual wizard.
-     *
-     * @param action The action parameter from {@link #run(IAction)}.
-     *               This can be null.
-     * @return A new wizard instance. Must not be null.
-     */
-    protected abstract IWorkbenchWizard instanciateWizard(IAction action);
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
-     */
-    public void selectionChanged(IAction action, ISelection selection) {
-        mSelection = selection;
-    }
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
-     */
-    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-        mWorkbench = targetPart.getSite().getWorkbenchWindow().getWorkbench();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
deleted file mode 100644
index 15e9912..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.export;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.jarutils.KeystoreHelper;
-import com.android.jarutils.SignedJarBuilder;
-import com.android.jarutils.DebugKeyProvider.IKeyGenOutput;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IExportWizard;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.lang.reflect.InvocationTargetException;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * Export wizard to export an apk signed with a release key/certificate.
- */
-public final class ExportWizard extends Wizard implements IExportWizard {
-
-    private static final String PROJECT_LOGO_LARGE = "icons/android_large.png"; //$NON-NLS-1$
-
-    private static final String PAGE_PROJECT_CHECK = "Page_ProjectCheck"; //$NON-NLS-1$
-    private static final String PAGE_KEYSTORE_SELECTION = "Page_KeystoreSelection"; //$NON-NLS-1$
-    private static final String PAGE_KEY_CREATION = "Page_KeyCreation"; //$NON-NLS-1$
-    private static final String PAGE_KEY_SELECTION = "Page_KeySelection"; //$NON-NLS-1$
-    private static final String PAGE_KEY_CHECK = "Page_KeyCheck"; //$NON-NLS-1$
-
-    static final String PROPERTY_KEYSTORE = "keystore"; //$NON-NLS-1$
-    static final String PROPERTY_ALIAS = "alias"; //$NON-NLS-1$
-    static final String PROPERTY_DESTINATION = "destination"; //$NON-NLS-1$
-    static final String PROPERTY_FILENAME = "baseFilename"; //$NON-NLS-1$
-
-    static final int APK_FILE_SOURCE = 0;
-    static final int APK_FILE_DEST = 1;
-    static final int APK_COUNT = 2;
-
-    /**
-     * Base page class for the ExportWizard page. This class add the {@link #onShow()} callback.
-     */
-    static abstract class ExportWizardPage extends WizardPage {
-
-        /** bit mask constant for project data change event */
-        protected static final int DATA_PROJECT = 0x001;
-        /** bit mask constant for keystore data change event */
-        protected static final int DATA_KEYSTORE = 0x002;
-        /** bit mask constant for key data change event */
-        protected static final int DATA_KEY = 0x004;
-
-        protected static final VerifyListener sPasswordVerifier = new VerifyListener() {
-            public void verifyText(VerifyEvent e) {
-                // verify the characters are valid for password.
-                int len = e.text.length();
-
-                // first limit to 127 characters max
-                if (len + ((Text)e.getSource()).getText().length() > 127) {
-                    e.doit = false;
-                    return;
-                }
-
-                // now only take non control characters
-                for (int i = 0 ; i < len ; i++) {
-                    if (e.text.charAt(i) < 32) {
-                        e.doit = false;
-                        return;
-                    }
-                }
-            }
-        };
-
-        /**
-         * Bit mask indicating what changed while the page was hidden.
-         * @see #DATA_PROJECT
-         * @see #DATA_KEYSTORE
-         * @see #DATA_KEY
-         */
-        protected int mProjectDataChanged = 0;
-
-        ExportWizardPage(String name) {
-            super(name);
-        }
-
-        abstract void onShow();
-
-        @Override
-        public void setVisible(boolean visible) {
-            super.setVisible(visible);
-            if (visible) {
-                onShow();
-                mProjectDataChanged = 0;
-            }
-        }
-
-        final void projectDataChanged(int changeMask) {
-            mProjectDataChanged |= changeMask;
-        }
-
-        /**
-         * Calls {@link #setErrorMessage(String)} and {@link #setPageComplete(boolean)} based on a
-         * {@link Throwable} object.
-         */
-        protected void onException(Throwable t) {
-            String message = getExceptionMessage(t);
-
-            setErrorMessage(message);
-            setPageComplete(false);
-        }
-    }
-
-    private ExportWizardPage mPages[] = new ExportWizardPage[5];
-
-    private IProject mProject;
-
-    private String mKeystore;
-    private String mKeystorePassword;
-    private boolean mKeystoreCreationMode;
-
-    private String mKeyAlias;
-    private String mKeyPassword;
-    private int mValidity;
-    private String mDName;
-
-    private PrivateKey mPrivateKey;
-    private X509Certificate mCertificate;
-
-    private File mDestinationParentFolder;
-
-    private ExportWizardPage mKeystoreSelectionPage;
-    private ExportWizardPage mKeyCreationPage;
-    private ExportWizardPage mKeySelectionPage;
-    private ExportWizardPage mKeyCheckPage;
-
-    private boolean mKeyCreationMode;
-
-    private List<String> mExistingAliases;
-
-    private Map<String, String[]> mApkMap;
-
-    public ExportWizard() {
-        setHelpAvailable(false); // TODO have help
-        setWindowTitle("Export Android Application");
-        setImageDescriptor();
-    }
-
-    @Override
-    public void addPages() {
-        addPage(mPages[0] = new ProjectCheckPage(this, PAGE_PROJECT_CHECK));
-        addPage(mKeystoreSelectionPage = mPages[1] = new KeystoreSelectionPage(this,
-                PAGE_KEYSTORE_SELECTION));
-        addPage(mKeyCreationPage = mPages[2] = new KeyCreationPage(this, PAGE_KEY_CREATION));
-        addPage(mKeySelectionPage = mPages[3] = new KeySelectionPage(this, PAGE_KEY_SELECTION));
-        addPage(mKeyCheckPage = mPages[4] = new KeyCheckPage(this, PAGE_KEY_CHECK));
-    }
-
-    @Override
-    public boolean performFinish() {
-        // save the properties
-        ProjectHelper.saveStringProperty(mProject, PROPERTY_KEYSTORE, mKeystore);
-        ProjectHelper.saveStringProperty(mProject, PROPERTY_ALIAS, mKeyAlias);
-        ProjectHelper.saveStringProperty(mProject, PROPERTY_DESTINATION,
-                mDestinationParentFolder.getAbsolutePath());
-        ProjectHelper.saveStringProperty(mProject, PROPERTY_FILENAME,
-                mApkMap.get(null)[APK_FILE_DEST]);
-
-        // run the export in an UI runnable.
-        IWorkbench workbench = PlatformUI.getWorkbench();
-        final boolean[] result = new boolean[1];
-        try {
-            workbench.getProgressService().busyCursorWhile(new IRunnableWithProgress() {
-                /**
-                 * Run the export.
-                 * @throws InvocationTargetException
-                 * @throws InterruptedException
-                 */
-                public void run(IProgressMonitor monitor) throws InvocationTargetException,
-                        InterruptedException {
-                    try {
-                        result[0] = doExport(monitor);
-                    } finally {
-                        monitor.done();
-                    }
-                }
-            });
-        } catch (InvocationTargetException e) {
-            return false;
-        } catch (InterruptedException e) {
-            return false;
-        }
-
-        return result[0];
-    }
-
-    private boolean doExport(IProgressMonitor monitor) {
-        try {
-            // first we make sure the project is built
-            mProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor);
-
-            // if needed, create the keystore and/or key.
-            if (mKeystoreCreationMode || mKeyCreationMode) {
-                final ArrayList<String> output = new ArrayList<String>();
-                boolean createdStore = KeystoreHelper.createNewStore(
-                        mKeystore,
-                        null /*storeType*/,
-                        mKeystorePassword,
-                        mKeyAlias,
-                        mKeyPassword,
-                        mDName,
-                        mValidity,
-                        new IKeyGenOutput() {
-                            public void err(String message) {
-                                output.add(message);
-                            }
-                            public void out(String message) {
-                                output.add(message);
-                            }
-                        });
-
-                if (createdStore == false) {
-                    // keystore creation error!
-                    displayError(output.toArray(new String[output.size()]));
-                    return false;
-                }
-
-                // keystore is created, now load the private key and certificate.
-                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream fis = new FileInputStream(mKeystore);
-                keyStore.load(fis, mKeystorePassword.toCharArray());
-                fis.close();
-                PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
-                        mKeyAlias, new KeyStore.PasswordProtection(mKeyPassword.toCharArray()));
-
-                if (entry != null) {
-                    mPrivateKey = entry.getPrivateKey();
-                    mCertificate = (X509Certificate)entry.getCertificate();
-                } else {
-                    // this really shouldn't happen since we now let the user choose the key
-                    // from a list read from the store.
-                    displayError("Could not find key");
-                    return false;
-                }
-            }
-
-            // check the private key/certificate again since it may have been created just above.
-            if (mPrivateKey != null && mCertificate != null) {
-                // get the output folder of the project to export.
-                // this is where we'll find the built apks to resign and export.
-                IFolder outputIFolder = BaseProjectHelper.getOutputFolder(mProject);
-                if (outputIFolder == null) {
-                    return false;
-                }
-                String outputOsPath =  outputIFolder.getLocation().toOSString();
-
-                // now generate the packages.
-                Set<Entry<String, String[]>> set = mApkMap.entrySet();
-
-                boolean runZipAlign = false;
-                String path = AdtPlugin.getOsAbsoluteZipAlign();
-                File zipalign = new File(path);
-                runZipAlign = zipalign.isFile();
-
-                for (Entry<String, String[]> entry : set) {
-                    String[] defaultApk = entry.getValue();
-                    String srcFilename = defaultApk[APK_FILE_SOURCE];
-                    String destFilename = defaultApk[APK_FILE_DEST];
-                    File destFile;
-                    if (runZipAlign) {
-                        destFile = File.createTempFile("android", ".apk");
-                    } else {
-                        destFile = new File(mDestinationParentFolder, destFilename);
-                    }
-
-
-                    FileOutputStream fos = new FileOutputStream(destFile);
-                    SignedJarBuilder builder = new SignedJarBuilder(fos, mPrivateKey, mCertificate);
-
-                    // get the input file.
-                    FileInputStream fis = new FileInputStream(new File(outputOsPath, srcFilename));
-
-                    // add the content of the source file to the output file, and sign it at
-                    // the same time.
-                    try {
-                        builder.writeZip(fis, null /* filter */);
-                        // close the builder: write the final signature files,
-                        // and close the archive.
-                        builder.close();
-
-                        // now zipalign the result
-                        if (runZipAlign) {
-                            File realDestFile = new File(mDestinationParentFolder, destFilename);
-                            String message = zipAlign(path, destFile, realDestFile);
-                            if (message != null) {
-                                displayError(message);
-                                return false;
-                            }
-                        }
-                    } finally {
-                        try {
-                            fis.close();
-                        } finally {
-                            fos.close();
-                        }
-                    }
-                }
-
-                // export success. In case we didn't run ZipAlign we display a warning
-                if (runZipAlign == false) {
-                    AdtPlugin.displayWarning("Export Wizard",
-                            "The zipalign tool was not found in the SDK.\n\n" +
-                            "Please update to the latest SDK and re-export your application\n" +
-                            "or run zipalign manually.\n\n" +
-                            "Aligning applications allows Android to use application resources\n" +
-                            "more efficiently.");
-                }
-
-                return true;
-            }
-        } catch (Throwable t) {
-            displayError(t);
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean canFinish() {
-        // check if we have the apk to resign, the destination location, and either
-        // a private key/certificate or the creation mode. In creation mode, unless
-        // all the key/keystore info is valid, the user cannot reach the last page, so there's
-        // no need to check them again here.
-        return mApkMap != null && mApkMap.size() > 0 &&
-                ((mPrivateKey != null && mCertificate != null)
-                        || mKeystoreCreationMode || mKeyCreationMode) &&
-                mDestinationParentFolder != null;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection)
-     */
-    public void init(IWorkbench workbench, IStructuredSelection selection) {
-        // get the project from the selection
-        Object selected = selection.getFirstElement();
-
-        if (selected instanceof IProject) {
-            mProject = (IProject)selected;
-        } else if (selected instanceof IAdaptable) {
-            IResource r = (IResource)((IAdaptable)selected).getAdapter(IResource.class);
-            if (r != null) {
-                mProject = r.getProject();
-            }
-        }
-    }
-
-    ExportWizardPage getKeystoreSelectionPage() {
-        return mKeystoreSelectionPage;
-    }
-
-    ExportWizardPage getKeyCreationPage() {
-        return mKeyCreationPage;
-    }
-
-    ExportWizardPage getKeySelectionPage() {
-        return mKeySelectionPage;
-    }
-
-    ExportWizardPage getKeyCheckPage() {
-        return mKeyCheckPage;
-    }
-
-    /**
-     * Returns an image descriptor for the wizard logo.
-     */
-    private void setImageDescriptor() {
-        ImageDescriptor desc = AdtPlugin.getImageDescriptor(PROJECT_LOGO_LARGE);
-        setDefaultPageImageDescriptor(desc);
-    }
-
-    IProject getProject() {
-        return mProject;
-    }
-
-    void setProject(IProject project) {
-        mProject = project;
-
-        updatePageOnChange(ExportWizardPage.DATA_PROJECT);
-    }
-
-    void setKeystore(String path) {
-        mKeystore = path;
-        mPrivateKey = null;
-        mCertificate = null;
-
-        updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
-    }
-
-    String getKeystore() {
-        return mKeystore;
-    }
-
-    void setKeystoreCreationMode(boolean createStore) {
-        mKeystoreCreationMode = createStore;
-        updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
-    }
-
-    boolean getKeystoreCreationMode() {
-        return mKeystoreCreationMode;
-    }
-
-
-    void setKeystorePassword(String password) {
-        mKeystorePassword = password;
-        mPrivateKey = null;
-        mCertificate = null;
-
-        updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
-    }
-
-    String getKeystorePassword() {
-        return mKeystorePassword;
-    }
-
-    void setKeyCreationMode(boolean createKey) {
-        mKeyCreationMode = createKey;
-        updatePageOnChange(ExportWizardPage.DATA_KEY);
-    }
-
-    boolean getKeyCreationMode() {
-        return mKeyCreationMode;
-    }
-
-    void setExistingAliases(List<String> aliases) {
-        mExistingAliases = aliases;
-    }
-
-    List<String> getExistingAliases() {
-        return mExistingAliases;
-    }
-
-    void setKeyAlias(String name) {
-        mKeyAlias = name;
-        mPrivateKey = null;
-        mCertificate = null;
-
-        updatePageOnChange(ExportWizardPage.DATA_KEY);
-    }
-
-    String getKeyAlias() {
-        return mKeyAlias;
-    }
-
-    void setKeyPassword(String password) {
-        mKeyPassword = password;
-        mPrivateKey = null;
-        mCertificate = null;
-
-        updatePageOnChange(ExportWizardPage.DATA_KEY);
-    }
-
-    String getKeyPassword() {
-        return mKeyPassword;
-    }
-
-    void setValidity(int validity) {
-        mValidity = validity;
-        updatePageOnChange(ExportWizardPage.DATA_KEY);
-    }
-
-    int getValidity() {
-        return mValidity;
-    }
-
-    void setDName(String dName) {
-        mDName = dName;
-        updatePageOnChange(ExportWizardPage.DATA_KEY);
-    }
-
-    String getDName() {
-        return mDName;
-    }
-
-    void setSigningInfo(PrivateKey privateKey, X509Certificate certificate) {
-        mPrivateKey = privateKey;
-        mCertificate = certificate;
-    }
-
-    void setDestination(File parentFolder, Map<String, String[]> apkMap) {
-        mDestinationParentFolder = parentFolder;
-        mApkMap = apkMap;
-    }
-
-    void resetDestination() {
-        mDestinationParentFolder = null;
-        mApkMap = null;
-    }
-
-    void updatePageOnChange(int changeMask) {
-        for (ExportWizardPage page : mPages) {
-            page.projectDataChanged(changeMask);
-        }
-    }
-
-    private void displayError(String... messages) {
-        String message = null;
-        if (messages.length == 1) {
-            message = messages[0];
-        } else {
-            StringBuilder sb = new StringBuilder(messages[0]);
-            for (int i = 1;  i < messages.length; i++) {
-                sb.append('\n');
-                sb.append(messages[i]);
-            }
-
-            message = sb.toString();
-        }
-
-        AdtPlugin.displayError("Export Wizard", message);
-    }
-
-    private void displayError(Throwable t) {
-        String message = getExceptionMessage(t);
-        displayError(message);
-
-        AdtPlugin.log(t, "Export Wizard Error");
-    }
-
-    /**
-     * Executes zipalign
-     * @param zipAlignPath location of the zipalign too
-     * @param source file to zipalign
-     * @param destination where to write the resulting file
-     * @return null if success, the error otherwise
-     * @throws IOException
-     */
-    private String zipAlign(String zipAlignPath, File source, File destination) throws IOException {
-        // command line: zipaling -f 4 tmp destination
-        String[] command = new String[5];
-        command[0] = zipAlignPath;
-        command[1] = "-f"; //$NON-NLS-1$
-        command[2] = "4"; //$NON-NLS-1$
-        command[3] = source.getAbsolutePath();
-        command[4] = destination.getAbsolutePath();
-
-        Process process = Runtime.getRuntime().exec(command);
-        ArrayList<String> output = new ArrayList<String>();
-        try {
-            if (grabProcessOutput(process, output) != 0) {
-                // build a single message from the array list
-                StringBuilder sb = new StringBuilder("Error while running zipalign:");
-                for (String msg : output) {
-                    sb.append('\n');
-                    sb.append(msg);
-                }
-
-                return sb.toString();
-            }
-        } catch (InterruptedException e) {
-            // ?
-        }
-        return null;
-    }
-
-    /**
-     * Get the stderr output of a process and return when the process is done.
-     * @param process The process to get the ouput from
-     * @param results The array to store the stderr output
-     * @return the process return code.
-     * @throws InterruptedException
-     */
-    private final int grabProcessOutput(final Process process,
-            final ArrayList<String> results)
-            throws InterruptedException {
-        // Due to the limited buffer size on windows for the standard io (stderr, stdout), we
-        // *need* to read both stdout and stderr all the time. If we don't and a process output
-        // a large amount, this could deadlock the process.
-
-        // read the lines as they come. if null is returned, it's
-        // because the process finished
-        new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            results.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        }.start();
-
-        new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                IProject project = getProject();
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
-                                    project, line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-
-        }.start();
-
-        // get the return code from the process
-        return process.waitFor();
-    }
-
-
-
-    /**
-     * Returns the {@link Throwable#getMessage()}. If the {@link Throwable#getMessage()} returns
-     * <code>null</code>, the method is called again on the cause of the Throwable object.
-     * <p/>If no Throwable in the chain has a valid message, the canonical name of the first
-     * exception is returned.
-     */
-    static String getExceptionMessage(Throwable t) {
-        String message = t.getMessage();
-        if (message == null) {
-            // no error info? get the stack call to display it
-            // At least that'll give us a better bug report.
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            t.printStackTrace(new PrintStream(baos));
-            message = baos.toString();
-        }
-
-        return message;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java
deleted file mode 100644
index 5f8a8d5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-import com.android.sdklib.internal.project.ApkSettings;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.widgets.FormText;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.UnrecoverableEntryException;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * Final page of the wizard that checks the key and ask for the ouput location.
- */
-final class KeyCheckPage extends ExportWizardPage {
-
-    private final ExportWizard mWizard;
-    private PrivateKey mPrivateKey;
-    private X509Certificate mCertificate;
-    private Text mDestination;
-    private boolean mFatalSigningError;
-    private FormText mDetailText;
-    private ScrolledComposite mScrolledComposite;
-
-    private ApkSettings mApkSettings;
-
-    private String mKeyDetails;
-    private String mDestinationDetails;
-
-    protected KeyCheckPage(ExportWizard wizard, String pageName) {
-        super(pageName);
-        mWizard = wizard;
-
-        setTitle("Destination and key/certificate checks");
-        setDescription(""); // TODO
-    }
-
-    public void createControl(Composite parent) {
-        setErrorMessage(null);
-        setMessage(null);
-
-        // build the ui.
-        Composite composite = new Composite(parent, SWT.NULL);
-        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        GridLayout gl = new GridLayout(3, false);
-        gl.verticalSpacing *= 3;
-        composite.setLayout(gl);
-
-        GridData gd;
-
-        new Label(composite, SWT.NONE).setText("Destination APK file:");
-        mDestination = new Text(composite, SWT.BORDER);
-        mDestination.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        mDestination.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onDestinationChange(false /*forceDetailUpdate*/);
-            }
-        });
-        final Button browseButton = new Button(composite, SWT.PUSH);
-        browseButton.setText("Browse...");
-        browseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                FileDialog fileDialog = new FileDialog(browseButton.getShell(), SWT.SAVE);
-
-                fileDialog.setText("Destination file name");
-                // get a default apk name based on the project
-                String filename = ProjectHelper.getApkFilename(mWizard.getProject(),
-                        null /*config*/);
-                fileDialog.setFileName(filename);
-
-                String saveLocation = fileDialog.open();
-                if (saveLocation != null) {
-                    mDestination.setText(saveLocation);
-                }
-            }
-        });
-
-        mScrolledComposite = new ScrolledComposite(composite, SWT.V_SCROLL);
-        mScrolledComposite.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
-        gd.horizontalSpan = 3;
-        mScrolledComposite.setExpandHorizontal(true);
-        mScrolledComposite.setExpandVertical(true);
-
-        mDetailText = new FormText(mScrolledComposite, SWT.NONE);
-        mScrolledComposite.setContent(mDetailText);
-
-        mScrolledComposite.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                updateScrolling();
-            }
-        });
-
-        setControl(composite);
-    }
-
-    @Override
-    void onShow() {
-        // fill the texts with information loaded from the project.
-        if ((mProjectDataChanged & DATA_PROJECT) != 0) {
-            // reset the destination from the content of the project
-            IProject project = mWizard.getProject();
-            mApkSettings = Sdk.getCurrent().getApkSettings(project);
-
-            String destination = ProjectHelper.loadStringProperty(project,
-                    ExportWizard.PROPERTY_DESTINATION);
-            String filename = ProjectHelper.loadStringProperty(project,
-                    ExportWizard.PROPERTY_FILENAME);
-            if (destination != null && filename != null) {
-                mDestination.setText(destination + File.separator + filename);
-            }
-        }
-
-        // if anything change we basically reload the data.
-        if (mProjectDataChanged != 0) {
-            mFatalSigningError = false;
-
-            // reset the wizard with no key/cert to make it not finishable, unless a valid
-            // key/cert is found.
-            mWizard.setSigningInfo(null, null);
-            mPrivateKey = null;
-            mCertificate = null;
-            mKeyDetails = null;
-
-            if (mWizard.getKeystoreCreationMode() || mWizard.getKeyCreationMode()) {
-                int validity = mWizard.getValidity();
-                StringBuilder sb = new StringBuilder(
-                        String.format("<p>Certificate expires in %d years.</p>",
-                        validity));
-
-                if (validity < 25) {
-                    sb.append("<p>Make sure the certificate is valid for the planned lifetime of the product.</p>");
-                    sb.append("<p>If the certificate expires, you will be forced to sign your application with a different one.</p>");
-                    sb.append("<p>Applications cannot be upgraded if their certificate changes from one version to another, ");
-                    sb.append("forcing a full uninstall/install, which will make the user lose his/her data.</p>");
-                    sb.append("<p>Android Market currently requires certificates to be valid until 2033.</p>");
-                }
-
-                mKeyDetails = sb.toString();
-            } else {
-                try {
-                    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
-                    FileInputStream fis = new FileInputStream(mWizard.getKeystore());
-                    keyStore.load(fis, mWizard.getKeystorePassword().toCharArray());
-                    fis.close();
-                    PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
-                            mWizard.getKeyAlias(),
-                            new KeyStore.PasswordProtection(
-                                    mWizard.getKeyPassword().toCharArray()));
-
-                    if (entry != null) {
-                        mPrivateKey = entry.getPrivateKey();
-                        mCertificate = (X509Certificate)entry.getCertificate();
-                    } else {
-                        setErrorMessage("Unable to find key.");
-
-                        setPageComplete(false);
-                    }
-                } catch (FileNotFoundException e) {
-                    // this was checked at the first previous step and will not happen here, unless
-                    // the file was removed during the export wizard execution.
-                    onException(e);
-                } catch (KeyStoreException e) {
-                    onException(e);
-                } catch (NoSuchAlgorithmException e) {
-                    onException(e);
-                } catch (UnrecoverableEntryException e) {
-                    onException(e);
-                } catch (CertificateException e) {
-                    onException(e);
-                } catch (IOException e) {
-                    onException(e);
-                }
-
-                if (mPrivateKey != null && mCertificate != null) {
-                    Calendar expirationCalendar = Calendar.getInstance();
-                    expirationCalendar.setTime(mCertificate.getNotAfter());
-                    Calendar today = Calendar.getInstance();
-
-                    if (expirationCalendar.before(today)) {
-                        mKeyDetails = String.format(
-                                "<p>Certificate expired on %s</p>",
-                                mCertificate.getNotAfter().toString());
-
-                        // fatal error = nothing can make the page complete.
-                        mFatalSigningError = true;
-
-                        setErrorMessage("Certificate is expired.");
-                        setPageComplete(false);
-                    } else {
-                        // valid, key/cert: put it in the wizard so that it can be finished
-                        mWizard.setSigningInfo(mPrivateKey, mCertificate);
-
-                        StringBuilder sb = new StringBuilder(String.format(
-                                "<p>Certificate expires on %s.</p>",
-                                mCertificate.getNotAfter().toString()));
-
-                        int expirationYear = expirationCalendar.get(Calendar.YEAR);
-                        int thisYear = today.get(Calendar.YEAR);
-
-                        if (thisYear + 25 < expirationYear) {
-                            // do nothing
-                        } else {
-                            if (expirationYear == thisYear) {
-                                sb.append("<p>The certificate expires this year.</p>");
-                            } else {
-                                int count = expirationYear-thisYear;
-                                sb.append(String.format(
-                                        "<p>The Certificate expires in %1$s %2$s.</p>",
-                                        count, count == 1 ? "year" : "years"));
-                            }
-
-                            sb.append("<p>Make sure the certificate is valid for the planned lifetime of the product.</p>");
-                            sb.append("<p>If the certificate expires, you will be forced to sign your application with a different one.</p>");
-                            sb.append("<p>Applications cannot be upgraded if their certificate changes from one version to another, ");
-                            sb.append("forcing a full uninstall/install, which will make the user lose his/her data.</p>");
-                            sb.append("<p>Android Market currently requires certificates to be valid until 2033.</p>");
-                        }
-
-                        mKeyDetails = sb.toString();
-                    }
-                } else {
-                    // fatal error = nothing can make the page complete.
-                    mFatalSigningError = true;
-                }
-            }
-        }
-
-        onDestinationChange(true /*forceDetailUpdate*/);
-    }
-
-    /**
-     * Callback for destination field edition
-     * @param forceDetailUpdate if true, the detail {@link FormText} is updated even if a fatal
-     * error has happened in the signing.
-     */
-    private void onDestinationChange(boolean forceDetailUpdate) {
-        if (mFatalSigningError == false) {
-            // reset messages for now.
-            setErrorMessage(null);
-            setMessage(null);
-
-            String path = mDestination.getText().trim();
-
-            if (path.length() == 0) {
-                setErrorMessage("Enter destination for the APK file.");
-                // reset canFinish in the wizard.
-                mWizard.resetDestination();
-                setPageComplete(false);
-                return;
-            }
-
-            File file = new File(path);
-            if (file.isDirectory()) {
-                setErrorMessage("Destination is a directory.");
-                // reset canFinish in the wizard.
-                mWizard.resetDestination();
-                setPageComplete(false);
-                return;
-            }
-
-            File parentFolder = file.getParentFile();
-            if (parentFolder == null || parentFolder.isDirectory() == false) {
-                setErrorMessage("Not a valid directory.");
-                // reset canFinish in the wizard.
-                mWizard.resetDestination();
-                setPageComplete(false);
-                return;
-            }
-
-            // display the list of files that will actually be created
-            Map<String, String[]> apkFileMap = getApkFileMap(file);
-
-            // display them
-            boolean fileExists = false;
-            StringBuilder sb = new StringBuilder(String.format(
-                    "<p>This will create the following files:</p>"));
-
-            Set<Entry<String, String[]>> set = apkFileMap.entrySet();
-            for (Entry<String, String[]> entry : set) {
-                String[] apkArray = entry.getValue();
-                String filename = apkArray[ExportWizard.APK_FILE_DEST];
-                File f = new File(parentFolder, filename);
-                if (f.isFile()) {
-                    fileExists = true;
-                    sb.append(String.format("<li>%1$s (WARNING: already exists)</li>", filename));
-                } else if (f.isDirectory()) {
-                    setErrorMessage(String.format("%1$s is a directory.", filename));
-                    // reset canFinish in the wizard.
-                    mWizard.resetDestination();
-                    setPageComplete(false);
-                    return;
-                } else {
-                    sb.append(String.format("<li>%1$s</li>", filename));
-                }
-            }
-
-            mDestinationDetails = sb.toString();
-
-            // no error, set the destination in the wizard.
-            mWizard.setDestination(parentFolder, apkFileMap);
-            setPageComplete(true);
-
-            // However, we should also test if the file already exists.
-            if (fileExists) {
-                setMessage("A destination file already exists.", WARNING);
-            }
-
-            updateDetailText();
-        } else if (forceDetailUpdate) {
-            updateDetailText();
-        }
-    }
-
-    /**
-     * Updates the scrollbar to match the content of the {@link FormText} or the new size
-     * of the {@link ScrolledComposite}.
-     */
-    private void updateScrolling() {
-        if (mDetailText != null) {
-            Rectangle r = mScrolledComposite.getClientArea();
-            mScrolledComposite.setMinSize(mDetailText.computeSize(r.width, SWT.DEFAULT));
-            mScrolledComposite.layout();
-        }
-    }
-
-    private void updateDetailText() {
-        StringBuilder sb = new StringBuilder("<form>");
-        if (mKeyDetails != null) {
-            sb.append(mKeyDetails);
-        }
-
-        if (mDestinationDetails != null && mFatalSigningError == false) {
-            sb.append(mDestinationDetails);
-        }
-
-        sb.append("</form>");
-
-        mDetailText.setText(sb.toString(), true /* parseTags */,
-                true /* expandURLs */);
-
-        mDetailText.getParent().layout();
-
-        updateScrolling();
-    }
-
-    /**
-     * Creates the list of destination filenames based on the content of the destination field
-     * and the list of APK configurations for the project.
-     *
-     * @param file File name from the destination field
-     * @return A list of destination filenames based <code>file</code> and the list of APK
-     *         configurations for the project.
-     */
-    private Map<String, String[]> getApkFileMap(File file) {
-        String filename = file.getName();
-
-        HashMap<String, String[]> map = new HashMap<String, String[]>();
-
-        // add the default APK filename
-        String[] apkArray = new String[ExportWizard.APK_COUNT];
-        apkArray[ExportWizard.APK_FILE_SOURCE] = ProjectHelper.getApkFilename(
-                mWizard.getProject(), null /*config*/);
-        apkArray[ExportWizard.APK_FILE_DEST] = filename;
-        map.put(null, apkArray);
-
-        // add the APKs for each APK configuration.
-        if (mApkSettings != null) {
-            Map<String, String> apkFilters = mApkSettings.getResourceFilters();
-            if (apkFilters.size() > 0) {
-                // remove the extension from the user-chosen filename
-                int index = filename.lastIndexOf('.');
-                String base = filename.substring(0, index);
-                String extension = filename.substring(index);
-
-                for (Entry<String, String> entry : apkFilters.entrySet()) {
-                    apkArray = new String[ExportWizard.APK_COUNT];
-                    apkArray[ExportWizard.APK_FILE_SOURCE] = ProjectHelper.getApkFilename(
-                            mWizard.getProject(), entry.getKey());
-                    apkArray[ExportWizard.APK_FILE_DEST] = base + "-" + //$NON-NLS-1$
-                            entry.getKey() + extension;
-                    map.put(entry.getKey(), apkArray);
-                }
-            }
-        }
-
-        return map;
-    }
-
-    @Override
-    protected void onException(Throwable t) {
-        super.onException(t);
-
-        mKeyDetails = String.format("ERROR: %1$s", ExportWizard.getExceptionMessage(t));
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java
deleted file mode 100644
index 2bc72db..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.List;
-
-/**
- * Key creation page. 
- */
-final class KeyCreationPage extends ExportWizardPage {
-
-    private final ExportWizard mWizard;
-    private Text mAlias;
-    private Text mKeyPassword;
-    private Text mKeyPassword2;
-    private Text mCnField;
-    private boolean mDisableOnChange = false;
-    private Text mOuField;
-    private Text mOField;
-    private Text mLField;
-    private Text mStField;
-    private Text mCField;
-    private String mDName;
-    private int mValidity = 0;
-    private List<String> mExistingAliases;
-
-    
-    protected KeyCreationPage(ExportWizard wizard, String pageName) {
-        super(pageName);
-        mWizard = wizard;
-
-        setTitle("Key Creation");
-        setDescription(""); // TODO?
-    }
-
-    public void createControl(Composite parent) {
-        Composite composite = new Composite(parent, SWT.NULL);
-        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        GridLayout gl = new GridLayout(2, false);
-        composite.setLayout(gl);
-        
-        GridData gd;
-
-        new Label(composite, SWT.NONE).setText("Alias:");
-        mAlias = new Text(composite, SWT.BORDER);
-        mAlias.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
-        new Label(composite, SWT.NONE).setText("Password:");
-        mKeyPassword = new Text(composite, SWT.BORDER | SWT.PASSWORD);
-        mKeyPassword.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        mKeyPassword.addVerifyListener(sPasswordVerifier);
-
-        new Label(composite, SWT.NONE).setText("Confirm:");
-        mKeyPassword2 = new Text(composite, SWT.BORDER | SWT.PASSWORD);
-        mKeyPassword2.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        mKeyPassword2.addVerifyListener(sPasswordVerifier);
-
-        new Label(composite, SWT.NONE).setText("Validity (years):");
-        final Text validityText = new Text(composite, SWT.BORDER);
-        validityText.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        validityText.addVerifyListener(new VerifyListener() {
-            public void verifyText(VerifyEvent e) {
-                // check for digit only.
-                for (int i = 0 ; i < e.text.length(); i++) {
-                    char letter = e.text.charAt(i);
-                    if (letter < '0' || letter > '9') {
-                        e.doit = false;
-                        return;
-                    }
-                }
-            }
-        });
-
-        new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(
-                gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-        
-        new Label(composite, SWT.NONE).setText("First and Last Name:");
-        mCnField = new Text(composite, SWT.BORDER);
-        mCnField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
-        new Label(composite, SWT.NONE).setText("Organizational Unit:");
-        mOuField = new Text(composite, SWT.BORDER);
-        mOuField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
-        new Label(composite, SWT.NONE).setText("Organization:");
-        mOField = new Text(composite, SWT.BORDER);
-        mOField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
-        new Label(composite, SWT.NONE).setText("City or Locality:");
-        mLField = new Text(composite, SWT.BORDER);
-        mLField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
-        new Label(composite, SWT.NONE).setText("State or Province:");
-        mStField = new Text(composite, SWT.BORDER);
-        mStField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        
-        new Label(composite, SWT.NONE).setText("Country Code (XX):");
-        mCField = new Text(composite, SWT.BORDER);
-        mCField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setControl(composite);
-        
-        mAlias.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mWizard.setKeyAlias(mAlias.getText().trim());
-                onChange();
-            }
-        });
-        mKeyPassword.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mWizard.setKeyPassword(mKeyPassword.getText());
-                onChange();
-            }
-        });
-        mKeyPassword2.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onChange();
-            }
-        });
-        
-        validityText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                try {
-                    mValidity = Integer.parseInt(validityText.getText());
-                } catch (NumberFormatException e2) {
-                    // this should only happen if the text field is empty due to the verifyListener.
-                    mValidity = 0;
-                }
-                mWizard.setValidity(mValidity);
-                onChange();
-            }
-        });
-
-        ModifyListener dNameListener = new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onDNameChange();
-            }
-        };
-        
-        mCnField.addModifyListener(dNameListener);
-        mOuField.addModifyListener(dNameListener);
-        mOField.addModifyListener(dNameListener);
-        mLField.addModifyListener(dNameListener);
-        mStField.addModifyListener(dNameListener);
-        mCField.addModifyListener(dNameListener);
-    }
-    
-    @Override
-    void onShow() {
-        // fill the texts with information loaded from the project.
-        if ((mProjectDataChanged & (DATA_PROJECT | DATA_KEYSTORE)) != 0) {
-            // reset the keystore/alias from the content of the project
-            IProject project = mWizard.getProject();
-            
-            // disable onChange for now. we'll call it once at the end.
-            mDisableOnChange = true;
-            
-            String alias = ProjectHelper.loadStringProperty(project, ExportWizard.PROPERTY_ALIAS);
-            if (alias != null) {
-                mAlias.setText(alias);
-            }
-            
-            // get the existing list of keys if applicable
-            if (mWizard.getKeyCreationMode()) {
-                mExistingAliases = mWizard.getExistingAliases();
-            } else {
-                mExistingAliases = null;
-            }
-            
-            // reset the passwords
-            mKeyPassword.setText(""); //$NON-NLS-1$
-            mKeyPassword2.setText(""); //$NON-NLS-1$
-            
-            // enable onChange, and call it to display errors and enable/disable pageCompleted.
-            mDisableOnChange = false;
-            onChange();
-        }
-    }
-
-    @Override
-    public IWizardPage getPreviousPage() {
-        if (mWizard.getKeyCreationMode()) { // this means we create a key from an existing store
-            return mWizard.getKeySelectionPage();
-        }
-        
-        return mWizard.getKeystoreSelectionPage();
-    }
-
-    @Override
-    public IWizardPage getNextPage() {
-        return mWizard.getKeyCheckPage();
-    }
-
-    /**
-     * Handles changes and update the error message and calls {@link #setPageComplete(boolean)}.
-     */
-    private void onChange() {
-        if (mDisableOnChange) {
-            return;
-        }
-
-        setErrorMessage(null);
-        setMessage(null);
-
-        if (mAlias.getText().trim().length() == 0) {
-            setErrorMessage("Enter key alias.");
-            setPageComplete(false);
-            return;
-        } else if (mExistingAliases != null) {
-            // we cannot use indexOf, because we need to do a case-insensitive check
-            String keyAlias = mAlias.getText().trim();
-            for (String alias : mExistingAliases) {
-                if (alias.equalsIgnoreCase(keyAlias)) {
-                    setErrorMessage("Key alias already exists in keystore.");
-                    setPageComplete(false);
-                    return;
-                }
-            }
-        }
-
-        String value = mKeyPassword.getText();
-        if (value.length() == 0) {
-            setErrorMessage("Enter key password.");
-            setPageComplete(false);
-            return;
-        } else if (value.length() < 6) {
-            setErrorMessage("Key password is too short - must be at least 6 characters.");
-            setPageComplete(false);
-            return;
-        }
-
-        if (value.equals(mKeyPassword2.getText()) == false) {
-            setErrorMessage("Key passwords don't match.");
-            setPageComplete(false);
-            return;
-        }
-
-        if (mValidity == 0) {
-            setErrorMessage("Key certificate validity is required.");
-            setPageComplete(false);
-            return;
-        } else if (mValidity < 25) {
-            setMessage("A 25 year certificate validity is recommended.", WARNING);
-        } else if (mValidity > 1000) {
-            setErrorMessage("Key certificate validity must be between 1 and 1000 years.");
-            setPageComplete(false);
-            return;
-        }
-
-        if (mDName == null || mDName.length() == 0) {
-            setErrorMessage("At least one Certificate issuer field is required to be non-empty.");
-            setPageComplete(false);
-            return;
-        }
-
-        setPageComplete(true);
-    }
-    
-    /**
-     * Handles changes in the DName fields.
-     */
-    private void onDNameChange() {
-        StringBuilder sb = new StringBuilder();
-        
-        buildDName("CN", mCnField, sb);
-        buildDName("OU", mOuField, sb);
-        buildDName("O", mOField, sb);
-        buildDName("L", mLField, sb);
-        buildDName("ST", mStField, sb);
-        buildDName("C", mCField, sb);
-        
-        mDName = sb.toString();
-        mWizard.setDName(mDName);
-
-        onChange();
-    }
-    
-    /**
-     * Builds the distinguished name string with the provided {@link StringBuilder}.
-     * @param prefix the prefix of the entry.
-     * @param textField The {@link Text} field containing the entry value.
-     * @param sb the string builder containing the dname.
-     */
-    private void buildDName(String prefix, Text textField, StringBuilder sb) {
-        if (textField != null) {
-            String value = textField.getText().trim();
-            if (value.length() > 0) {
-                if (sb.length() > 0) {
-                    sb.append(",");
-                }
-                
-                sb.append(prefix);
-                sb.append('=');
-                sb.append(value);
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java
deleted file mode 100644
index 131e009..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-
-/**
- * Key Selection Page. This is used when an existing keystore is used. 
- */
-final class KeySelectionPage extends ExportWizardPage {
-
-    private final ExportWizard mWizard;
-    private Label mKeyAliasesLabel;
-    private Combo mKeyAliases;
-    private Label mKeyPasswordLabel;
-    private Text mKeyPassword;
-    private boolean mDisableOnChange = false;
-    private Button mUseExistingKey;
-    private Button mCreateKey;
-
-    protected KeySelectionPage(ExportWizard wizard, String pageName) {
-        super(pageName);
-        mWizard = wizard;
-
-        setTitle("Key alias selection");
-        setDescription(""); // TODO
-    }
-
-    public void createControl(Composite parent) {
-        Composite composite = new Composite(parent, SWT.NULL);
-        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        GridLayout gl = new GridLayout(3, false);
-        composite.setLayout(gl);
-
-        GridData gd;
-
-        mUseExistingKey = new Button(composite, SWT.RADIO);
-        mUseExistingKey.setText("Use existing key");
-        mUseExistingKey.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 3;
-        mUseExistingKey.setSelection(true);
-
-        new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
-        gd.heightHint = 0;
-        gd.widthHint = 50;
-        mKeyAliasesLabel = new Label(composite, SWT.NONE);
-        mKeyAliasesLabel.setText("Alias:");
-        mKeyAliases = new Combo(composite, SWT.READ_ONLY);
-        mKeyAliases.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        
-        new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
-        gd.heightHint = 0;
-        gd.widthHint = 50;
-        mKeyPasswordLabel = new Label(composite, SWT.NONE);
-        mKeyPasswordLabel.setText("Password:");
-        mKeyPassword = new Text(composite, SWT.BORDER | SWT.PASSWORD);
-        mKeyPassword.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mCreateKey = new Button(composite, SWT.RADIO);
-        mCreateKey.setText("Create new key");
-        mCreateKey.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 3;
-
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setControl(composite);
-        
-        mUseExistingKey.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mWizard.setKeyCreationMode(!mUseExistingKey.getSelection());
-                enableWidgets();
-                onChange();
-            }
-        });
-        
-        mKeyAliases.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                mWizard.setKeyAlias(mKeyAliases.getItem(mKeyAliases.getSelectionIndex()));
-                onChange();
-            }
-        });
-        
-        mKeyPassword.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mWizard.setKeyPassword(mKeyPassword.getText());
-                onChange();
-            }
-        });
-    }
-    
-    @Override
-    void onShow() {
-        // fill the texts with information loaded from the project.
-        if ((mProjectDataChanged & (DATA_PROJECT | DATA_KEYSTORE)) != 0) {
-            // disable onChange for now. we'll call it once at the end.
-            mDisableOnChange = true;
-
-            // reset the alias from the content of the project
-            try {
-                // reset to using a key
-                mWizard.setKeyCreationMode(false);
-                mUseExistingKey.setSelection(true);
-                mCreateKey.setSelection(false);
-                enableWidgets();
-
-                // remove the content of the alias combo always and first, in case the
-                // keystore password is wrong
-                mKeyAliases.removeAll();
-
-                // get the alias list (also used as a keystore password test)
-                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream fis = new FileInputStream(mWizard.getKeystore());
-                keyStore.load(fis, mWizard.getKeystorePassword().toCharArray());
-                fis.close();
-                
-                Enumeration<String> aliases = keyStore.aliases();
-
-                // get the alias from the project previous export, and look for a match as
-                // we add the aliases to the combo.
-                IProject project = mWizard.getProject();
-
-                String keyAlias = ProjectHelper.loadStringProperty(project,
-                        ExportWizard.PROPERTY_ALIAS);
-                
-                ArrayList<String> aliasList = new ArrayList<String>();
-
-                int selection = -1;
-                int count = 0;
-                while (aliases.hasMoreElements()) {
-                    String alias = aliases.nextElement();
-                    mKeyAliases.add(alias);
-                    aliasList.add(alias);
-                    if (selection == -1 && alias.equalsIgnoreCase(keyAlias)) {
-                        selection = count;
-                    }
-                    count++;
-                }
-                
-                mWizard.setExistingAliases(aliasList);
-
-                if (selection != -1) {
-                    mKeyAliases.select(selection);
-
-                    // since a match was found and is selected, we need to give it to
-                    // the wizard as well
-                    mWizard.setKeyAlias(keyAlias);
-                } else {
-                    mKeyAliases.clearSelection();
-                }
-
-                // reset the password
-                mKeyPassword.setText(""); //$NON-NLS-1$
-
-                // enable onChange, and call it to display errors and enable/disable pageCompleted.
-                mDisableOnChange = false;
-                onChange();
-            } catch (KeyStoreException e) {
-                onException(e);
-            } catch (FileNotFoundException e) {
-                onException(e);
-            } catch (NoSuchAlgorithmException e) {
-                onException(e);
-            } catch (CertificateException e) {
-                onException(e);
-            } catch (IOException e) {
-                onException(e);
-            } finally {
-                // in case we exit with an exception, we need to reset this
-                mDisableOnChange = false;
-            }
-        }
-    }
-    
-    @Override
-    public IWizardPage getPreviousPage() {
-        return mWizard.getKeystoreSelectionPage();
-    }
-
-    @Override
-    public IWizardPage getNextPage() {
-        if (mWizard.getKeyCreationMode()) {
-            return mWizard.getKeyCreationPage();
-        }
-        
-        return mWizard.getKeyCheckPage();
-    }
-
-    /**
-     * Handles changes and update the error message and calls {@link #setPageComplete(boolean)}.
-     */
-    private void onChange() {
-        if (mDisableOnChange) {
-            return;
-        }
-
-        setErrorMessage(null);
-        setMessage(null);
-
-        if (mWizard.getKeyCreationMode() == false) {
-            if (mKeyAliases.getSelectionIndex() == -1) {
-                setErrorMessage("Select a key alias.");
-                setPageComplete(false);
-                return;
-            }
-    
-            if (mKeyPassword.getText().trim().length() == 0) {
-                setErrorMessage("Enter key password.");
-                setPageComplete(false);
-                return;
-            }
-        }
-
-        setPageComplete(true);
-    }
-    
-    private void enableWidgets() {
-        boolean useKey = !mWizard.getKeyCreationMode();
-        mKeyAliasesLabel.setEnabled(useKey);
-        mKeyAliases.setEnabled(useKey);
-        mKeyPassword.setEnabled(useKey);
-        mKeyPasswordLabel.setEnabled(useKey);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java
deleted file mode 100644
index a02b7b0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-
-/**
- * Keystore selection page. This page allows to choose to create a new keystore or use an
- * existing one. 
- */
-final class KeystoreSelectionPage extends ExportWizardPage {
-
-    private final ExportWizard mWizard;
-    private Button mUseExistingKeystore;
-    private Button mCreateKeystore;
-    private Text mKeystore;
-    private Text mKeystorePassword;
-    private Label mConfirmLabel;
-    private Text mKeystorePassword2;
-    private boolean mDisableOnChange = false;
-
-    protected KeystoreSelectionPage(ExportWizard wizard, String pageName) {
-        super(pageName);
-        mWizard = wizard;
-
-        setTitle("Keystore selection");
-        setDescription(""); //TODO
-    }
-
-    public void createControl(Composite parent) {
-        Composite composite = new Composite(parent, SWT.NULL);
-        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        GridLayout gl = new GridLayout(3, false);
-        composite.setLayout(gl);
-        
-        GridData gd;
-        
-        mUseExistingKeystore = new Button(composite, SWT.RADIO);
-        mUseExistingKeystore.setText("Use existing keystore");
-        mUseExistingKeystore.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 3;
-        mUseExistingKeystore.setSelection(true);
-
-        mCreateKeystore = new Button(composite, SWT.RADIO);
-        mCreateKeystore.setText("Create new keystore");
-        mCreateKeystore.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 3;
-
-        new Label(composite, SWT.NONE).setText("Location:");
-        mKeystore = new Text(composite, SWT.BORDER);
-        mKeystore.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        final Button browseButton = new Button(composite, SWT.PUSH);
-        browseButton.setText("Browse...");
-        browseButton.addSelectionListener(new SelectionAdapter() {
-           @Override
-           public void widgetSelected(SelectionEvent e) {
-               FileDialog fileDialog;
-               if (mUseExistingKeystore.getSelection()) {
-                   fileDialog = new FileDialog(browseButton.getShell(),SWT.OPEN);
-                   fileDialog.setText("Load Keystore");
-               } else {
-                   fileDialog = new FileDialog(browseButton.getShell(),SWT.SAVE);
-                   fileDialog.setText("Select Keystore Name");
-               }
-
-               String fileName = fileDialog.open();
-               if (fileName != null) {
-                   mKeystore.setText(fileName);
-               }
-           }
-        });
-
-        new Label(composite, SWT.NONE).setText("Password:");
-        mKeystorePassword = new Text(composite, SWT.BORDER | SWT.PASSWORD);
-        mKeystorePassword.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        mKeystorePassword.addVerifyListener(sPasswordVerifier);
-        new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
-        gd.heightHint = gd.widthHint = 0;
-
-        mConfirmLabel = new Label(composite, SWT.NONE);
-        mConfirmLabel.setText("Confirm:");
-        mKeystorePassword2 = new Text(composite, SWT.BORDER | SWT.PASSWORD);
-        mKeystorePassword2.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        mKeystorePassword2.addVerifyListener(sPasswordVerifier);
-        new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
-        gd.heightHint = gd.widthHint = 0;
-        mKeystorePassword2.setEnabled(false);
-
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setControl(composite);
-        
-        mUseExistingKeystore.addSelectionListener(new SelectionAdapter() {
-           @Override
-           public void widgetSelected(SelectionEvent e) {
-               boolean createStore = !mUseExistingKeystore.getSelection();
-               mKeystorePassword2.setEnabled(createStore);
-               mConfirmLabel.setEnabled(createStore);
-               mWizard.setKeystoreCreationMode(createStore);
-               onChange();
-            }
-        });
-        
-        mKeystore.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mWizard.setKeystore(mKeystore.getText().trim());
-                onChange();
-            }
-        });
-
-        mKeystorePassword.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                mWizard.setKeystorePassword(mKeystorePassword.getText());
-                onChange();
-            }
-        });
-
-        mKeystorePassword2.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onChange();
-            }
-        });
-    }
-    
-    @Override
-    public IWizardPage getNextPage() {
-        if (mUseExistingKeystore.getSelection()) {
-            return mWizard.getKeySelectionPage();
-        }
-        
-        return mWizard.getKeyCreationPage();
-    }
-    
-    @Override
-    void onShow() {
-        // fill the texts with information loaded from the project.
-        if ((mProjectDataChanged & DATA_PROJECT) != 0) {
-            // reset the keystore/alias from the content of the project
-            IProject project = mWizard.getProject();
-            
-            // disable onChange for now. we'll call it once at the end.
-            mDisableOnChange = true;
-            
-            String keystore = ProjectHelper.loadStringProperty(project,
-                    ExportWizard.PROPERTY_KEYSTORE);
-            if (keystore != null) {
-                mKeystore.setText(keystore);
-            }
-            
-            // reset the passwords
-            mKeystorePassword.setText(""); //$NON-NLS-1$
-            mKeystorePassword2.setText(""); //$NON-NLS-1$
-            
-            // enable onChange, and call it to display errors and enable/disable pageCompleted.
-            mDisableOnChange = false;
-            onChange();
-        }
-    }
-
-    /**
-     * Handles changes and update the error message and calls {@link #setPageComplete(boolean)}.
-     */
-    private void onChange() {
-        if (mDisableOnChange) {
-            return;
-        }
-
-        setErrorMessage(null);
-        setMessage(null);
-
-        boolean createStore = !mUseExistingKeystore.getSelection();
-
-        // checks the keystore path is non null.
-        String keystore = mKeystore.getText().trim();
-        if (keystore.length() == 0) {
-            setErrorMessage("Enter path to keystore.");
-            setPageComplete(false);
-            return;
-        } else {
-            File f = new File(keystore);
-            if (f.exists() == false) {
-                if (createStore == false) {
-                    setErrorMessage("Keystore does not exist.");
-                    setPageComplete(false);
-                    return;
-                }
-            } else if (f.isDirectory()) {
-                setErrorMessage("Keystore path is a directory.");
-                setPageComplete(false);
-                return;
-            } else if (f.isFile()) {
-                if (createStore) {
-                    setErrorMessage("File already exists.");
-                    setPageComplete(false);
-                    return;
-                }
-            }
-        }
-        
-        String value = mKeystorePassword.getText();
-        if (value.length() == 0) {
-            setErrorMessage("Enter keystore password.");
-            setPageComplete(false);
-            return;
-        } else if (createStore && value.length() < 6) {
-            setErrorMessage("Keystore password is too short - must be at least 6 characters.");
-            setPageComplete(false);
-            return;
-        }
-
-        if (createStore) {
-            if (mKeystorePassword2.getText().length() == 0) {
-                setErrorMessage("Confirm keystore password.");
-                setPageComplete(false);
-                return;
-            }
-            
-            if (mKeystorePassword.getText().equals(mKeystorePassword2.getText()) == false) {
-                setErrorMessage("Keystore passwords do not match.");
-                setPageComplete(false);
-                return;
-            }
-        }
-
-        setPageComplete(true);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java
deleted file mode 100644
index 4b8cb69..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.export;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-
-/**
- * First Export Wizard Page. Display warning/errors. 
- */
-final class ProjectCheckPage extends ExportWizardPage {
-    private final static String IMG_ERROR = "error.png"; //$NON-NLS-1$
-    private final static String IMG_WARNING = "warning.png"; //$NON-NLS-1$
-
-    private final ExportWizard mWizard;
-    private Display mDisplay;
-    private Image mError;
-    private Image mWarning;
-    private boolean mHasMessage = false;
-    private Composite mTopComposite;
-    private Composite mErrorComposite;
-    private Text mProjectText;
-    private ProjectChooserHelper mProjectChooserHelper;
-    private boolean mFirstOnShow = true;
-
-    protected ProjectCheckPage(ExportWizard wizard, String pageName) {
-        super(pageName);
-        mWizard = wizard;
-
-        setTitle("Project Checks");
-        setDescription("Performs a set of checks to make sure the application can be exported.");
-    }
-
-    public void createControl(Composite parent) {
-        mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
-        mDisplay = parent.getDisplay();
-
-        GridLayout gl = null;
-        GridData gd = null;
-
-        mTopComposite = new Composite(parent, SWT.NONE);
-        mTopComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mTopComposite.setLayout(new GridLayout(1, false));
-        
-        // composite for the project selection.
-        Composite projectComposite = new Composite(mTopComposite, SWT.NONE);
-        projectComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        projectComposite.setLayout(gl = new GridLayout(3, false));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        Label label = new Label(projectComposite, SWT.NONE);
-        label.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 3;
-        label.setText("Select the project to export:");
-
-        new Label(projectComposite, SWT.NONE).setText("Project:");
-        mProjectText = new Text(projectComposite, SWT.BORDER);
-        mProjectText.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        mProjectText.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                handleProjectNameChange();
-            }
-        });
-
-        Button browseButton = new Button(projectComposite, SWT.PUSH);
-        browseButton.setText("Browse...");
-        browseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                IJavaProject javaProject = mProjectChooserHelper.chooseJavaProject(
-                        mProjectText.getText().trim());
-
-                if (javaProject != null) {
-                    IProject project = javaProject.getProject();
-
-                    // set the new name in the text field. The modify listener will take
-                    // care of updating the status and the ExportWizard object.
-                    mProjectText.setText(project.getName());
-                }
-            }
-        });
-
-        setControl(mTopComposite);
-    }
-
-    @Override
-    void onShow() {
-        if (mFirstOnShow) {
-            // get the project and init the ui
-            IProject project = mWizard.getProject();
-            if (project != null) {
-                mProjectText.setText(project.getName());
-            }
-            
-            mFirstOnShow = false;
-        }
-    }
-    
-    private void buildErrorUi(IProject project) {
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setPageComplete(true);
-        mHasMessage = false;
-
-        // composite parent for the warning/error
-        GridLayout gl = null;
-        mErrorComposite = new Composite(mTopComposite, SWT.NONE);
-        mErrorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        gl = new GridLayout(2, false);
-        gl.marginHeight = gl.marginWidth = 0;
-        gl.verticalSpacing *= 3; // more spacing than normal.
-        mErrorComposite.setLayout(gl);
-
-        if (project == null) {
-            setErrorMessage("Select project to export.");
-            mHasMessage = true;
-        } else {
-            try {
-                if (project.hasNature(AndroidConstants.NATURE) == false) {
-                    addError(mErrorComposite, "Project is not an Android project.");
-                } else {
-                    // check for errors
-                    if (ProjectHelper.hasError(project, true))  {
-                        addError(mErrorComposite, "Project has compilation error(s)");
-                    }
-                    
-                    // check the project output
-                    IFolder outputIFolder = BaseProjectHelper.getOutputFolder(project);
-                    if (outputIFolder != null) {
-                        String outputOsPath =  outputIFolder.getLocation().toOSString();
-                        String apkFilePath =  outputOsPath + File.separator + project.getName() +
-                                AndroidConstants.DOT_ANDROID_PACKAGE;
-                        
-                        File f = new File(apkFilePath);
-                        if (f.isFile() == false) {
-                            addError(mErrorComposite,
-                                    String.format("%1$s/%2$s/%1$s%3$s does not exists!",
-                                            project.getName(),
-                                            outputIFolder.getName(),
-                                            AndroidConstants.DOT_ANDROID_PACKAGE));
-                        }
-                    } else {
-                        addError(mErrorComposite,
-                                "Unable to get the output folder of the project!");
-                    }
-
-
-                    // project is an android project, we check the debuggable attribute.
-                    AndroidManifestParser manifestParser = AndroidManifestParser.parse(
-                            BaseProjectHelper.getJavaProject(project), null /* errorListener */,
-                            true /* gatherData */, false /* markErrors */);
-
-                    Boolean debuggable = manifestParser.getDebuggable();
-                    
-                    if (debuggable != null && debuggable == Boolean.TRUE) {
-                        addWarning(mErrorComposite,
-                                "The manifest 'debuggable' attribute is set to true.\nYou should set it to false for applications that you release to the public."); 
-                    }
-                    
-                    // check for mapview stuff
-                }
-            } catch (CoreException e) {
-                // unable to access nature
-                addError(mErrorComposite, "Unable to get project nature");
-            }
-        }
-        
-        if (mHasMessage == false) {
-            Label label = new Label(mErrorComposite, SWT.NONE);
-            GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-            gd.horizontalSpan = 2;
-            label.setLayoutData(gd);
-            label.setText("No errors found. Click Next.");
-        }
-        
-        mTopComposite.layout();
-    }
-    
-    /**
-     * Adds an error label to a {@link Composite} object.
-     * @param parent the Composite parent.
-     * @param message the error message.
-     */
-    private void addError(Composite parent, String message) {
-        if (mError == null) {
-            mError = AdtPlugin.getImageLoader().loadImage(IMG_ERROR, mDisplay);
-        }
-        
-        new Label(parent, SWT.NONE).setImage(mError);
-        Label label = new Label(parent, SWT.NONE);
-        label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        label.setText(message);
-        
-        setErrorMessage("Application cannot be exported due to the error(s) below.");
-        setPageComplete(false);
-        mHasMessage = true;
-    }
-    
-    /**
-     * Adds a warning label to a {@link Composite} object.
-     * @param parent the Composite parent.
-     * @param message the warning message.
-     */
-    private void addWarning(Composite parent, String message) {
-        if (mWarning == null) {
-            mWarning = AdtPlugin.getImageLoader().loadImage(IMG_WARNING, mDisplay);
-        }
-        
-        new Label(parent, SWT.NONE).setImage(mWarning);
-        Label label = new Label(parent, SWT.NONE);
-        label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        label.setText(message);
-        
-        mHasMessage = true;
-    }
-    
-    /**
-     * Checks the parameters for correctness, and update the error message and buttons.
-     */
-    private void handleProjectNameChange() {
-        setPageComplete(false);
-        
-        if (mErrorComposite != null) {
-            mErrorComposite.dispose();
-            mErrorComposite = null;
-        }
-        
-        // update the wizard with the new project
-        mWizard.setProject(null);
-
-        //test the project name first!
-        String text = mProjectText.getText().trim();
-        if (text.length() == 0) {
-            setErrorMessage("Select project to export.");
-        } else if (text.matches("[a-zA-Z0-9_ \\.-]+") == false) {
-            setErrorMessage("Project name contains unsupported characters!");
-        } else {
-            IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null);
-            IProject found = null;
-            for (IJavaProject javaProject : projects) {
-                if (javaProject.getProject().getName().equals(text)) {
-                    found = javaProject.getProject();
-                    break;
-                }
-                
-            }
-            
-            if (found != null) {
-                setErrorMessage(null);
-                
-                // update the wizard with the new project
-                mWizard.setProject(found);
-
-                // now rebuild the error ui.
-                buildErrorUi(found);
-            } else {
-                setErrorMessage(String.format("There is no android project named '%1$s'",
-                        text));
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java
deleted file mode 100644
index 8d5cf27..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java
+++ /dev/null
@@ -1,1626 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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.
- */
-
-/*
- * References:
- * org.eclipse.jdt.internal.ui.wizards.JavaProjectWizard
- * org.eclipse.jdt.internal.ui.wizards.JavaProjectWizardFirstPage
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.newproject;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectCreationPage.TestInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
-import com.android.sdkuilib.internal.widgets.SdkTargetSelector;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jdt.core.JavaConventions;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.osgi.util.TextProcessor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.DirectoryDialog;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.regex.Pattern;
-
-/**
- * NewAndroidProjectCreationPage is a project creation page that provides the
- * following fields:
- * <ul>
- * <li> Project name
- * <li> SDK Target
- * <li> Application name
- * <li> Package name
- * <li> Activity name
- * </ul>
- * Note: this class is public so that it can be accessed from unit tests.
- * It is however an internal class. Its API may change without notice.
- * It should semantically be considered as a private final class.
- * Do not derive from this class.
- */
-public class NewProjectCreationPage extends WizardPage {
-
-    // constants
-    private static final String MAIN_PAGE_NAME = "newAndroidProjectPage"; //$NON-NLS-1$
-
-    /** Initial value for all name fields (project, activity, application, package). Used
-     * whenever a value is requested before controls are created. */
-    private static final String INITIAL_NAME = "";  //$NON-NLS-1$
-    /** Initial value for the Create New Project radio. */
-    private static final boolean INITIAL_CREATE_NEW_PROJECT = true;
-    /** Initial value for the Create Project From Sample. */
-    private static final boolean INITIAL_CREATE_FROM_SAMPLE = false;
-    /** Initial value for the Create Project From Existing Source. */
-    private static final boolean INITIAL_CREATE_FROM_SOURCE = false;
-    /** Initial value for the Use Default Location check box. */
-    private static final boolean INITIAL_USE_DEFAULT_LOCATION = true;
-    /** Initial value for the Create Activity check box. */
-    private static final boolean INITIAL_CREATE_ACTIVITY = true;
-
-
-    /** Pattern for characters accepted in a project name. Since this will be used as a
-     * directory name, we're being a bit conservative on purpose. It cannot start with a space. */
-    private static final Pattern sProjectNamePattern = Pattern.compile("^[\\w][\\w. -]*$");  //$NON-NLS-1$
-    /** Last user-browsed location, static so that it be remembered for the whole session */
-    private static String sCustomLocationOsPath = "";  //$NON-NLS-1$
-    private static boolean sAutoComputeCustomLocation = true;
-
-    private final int MSG_NONE = 0;
-    private final int MSG_WARNING = 1;
-    private final int MSG_ERROR = 2;
-
-    /** Structure with the externally visible information from this Main Project page. */
-    private final MainInfo mInfo = new MainInfo();
-    /** Structure with the externally visible information from the Test Project page.
-     *  This is null if there's no such page, meaning the main project page is standalone. */
-    private TestInfo mTestInfo;
-
-    private String mUserPackageName = "";       //$NON-NLS-1$
-    private String mUserActivityName = "";      //$NON-NLS-1$
-    private boolean mUserCreateActivityCheck = INITIAL_CREATE_ACTIVITY;
-    private String mSourceFolder = "";          //$NON-NLS-1$
-
-    // widgets
-    private Text mProjectNameField;
-    private Text mPackageNameField;
-    private Text mActivityNameField;
-    private Text mApplicationNameField;
-    private Button mCreateNewProjectRadio;
-    private Button mCreateFromSampleRadio;
-    private Button mUseDefaultLocation;
-    private Label mLocationLabel;
-    private Text mLocationPathField;
-    private Button mBrowseButton;
-    private Button mCreateActivityCheck;
-    private Text mMinSdkVersionField;
-    private SdkTargetSelector mSdkTargetSelector;
-    private ITargetChangeListener mSdkTargetChangeListener;
-
-    private boolean mInternalLocationPathUpdate;
-    private boolean mInternalProjectNameUpdate;
-    private boolean mInternalApplicationNameUpdate;
-    private boolean mInternalCreateActivityUpdate;
-    private boolean mInternalActivityNameUpdate;
-    private boolean mProjectNameModifiedByUser;
-    private boolean mApplicationNameModifiedByUser;
-    private boolean mInternalMinSdkVersionUpdate;
-
-    private final ArrayList<String> mSamplesPaths = new ArrayList<String>();
-    private Combo mSamplesCombo;
-
-
-
-    /**
-     * Creates a new project creation wizard page.
-     */
-    public NewProjectCreationPage() {
-        super(MAIN_PAGE_NAME);
-        setPageComplete(false);
-        setTitle("New Android Project");
-        setDescription("Creates a new Android Project resource.");
-    }
-
-    // --- Getters used by NewProjectWizard ---
-
-
-    /**
-     * Structure that collects all externally visible information from this page.
-     * This is used by the calling wizard to actually do the work or by other pages.
-     * <p/>
-     * This interface is provided so that the adt-test counterpart can override the returned
-     * information.
-     */
-    public interface IMainInfo {
-        public IPath getLocationPath();
-        /**
-         * Returns the current project location path as entered by the user, or its
-         * anticipated initial value. Note that if the default has been returned the
-         * path in a project description used to create a project should not be set.
-         *
-         * @return the project location path or its anticipated initial value.
-         */
-        /** Returns the value of the project name field with leading and trailing spaces removed. */
-        public String getProjectName();
-        /** Returns the value of the package name field with spaces trimmed. */
-        public String getPackageName();
-        /** Returns the value of the activity name field with spaces trimmed. */
-        public String getActivityName();
-        /** Returns the value of the min sdk version field with spaces trimmed. */
-        public String getMinSdkVersion();
-        /** Returns the value of the application name field with spaces trimmed. */
-        public String getApplicationName();
-        /** Returns the value of the "Create New Project" radio. */
-        public boolean isNewProject();
-        /** Returns the value of the "Create Activity" checkbox. */
-        public boolean isCreateActivity();
-        /** Returns the value of the Use Default Location field. */
-        public boolean useDefaultLocation();
-        /** Returns the internal source folder (for the "existing project" mode) or the default
-         * "src" constant. */
-        public String getSourceFolder();
-        /** Returns the current sdk target or null if none has been selected yet. */
-        public IAndroidTarget getSdkTarget();
-    }
-
-
-    /**
-     * Structure that collects all externally visible information from this page.
-     * This is used by the calling wizard to actually do the work or by other pages.
-     */
-    public class MainInfo implements IMainInfo {
-        /**
-         * Returns the current project location path as entered by the user, or its
-         * anticipated initial value. Note that if the default has been returned the
-         * path in a project description used to create a project should not be set.
-         *
-         * @return the project location path or its anticipated initial value.
-         */
-        public IPath getLocationPath() {
-            return new Path(getProjectLocation());
-        }
-
-        /** Returns the value of the project name field with leading and trailing spaces removed. */
-        public String getProjectName() {
-            return mProjectNameField == null ? INITIAL_NAME : mProjectNameField.getText().trim();
-        }
-
-        /** Returns the value of the package name field with spaces trimmed. */
-        public String getPackageName() {
-            return mPackageNameField == null ? INITIAL_NAME : mPackageNameField.getText().trim();
-        }
-
-        /** Returns the value of the activity name field with spaces trimmed. */
-        public String getActivityName() {
-            return mActivityNameField == null ? INITIAL_NAME : mActivityNameField.getText().trim();
-        }
-
-        /** Returns the value of the min sdk version field with spaces trimmed. */
-        public String getMinSdkVersion() {
-            return mMinSdkVersionField == null ? "" : mMinSdkVersionField.getText().trim();  //$NON-NLS-1$
-        }
-
-        /** Returns the value of the application name field with spaces trimmed. */
-        public String getApplicationName() {
-            // Return the name of the activity as default application name.
-            return mApplicationNameField == null ? getActivityName()
-                                                 : mApplicationNameField.getText().trim();
-
-        }
-
-        /** Returns the value of the "Create New Project" radio. */
-        public boolean isNewProject() {
-            return mCreateNewProjectRadio == null ? INITIAL_CREATE_NEW_PROJECT
-                                                  : mCreateNewProjectRadio.getSelection();
-        }
-
-        /** Returns the value of the "Create from Existing Sample" radio. */
-        public boolean isCreateFromSample() {
-            return mCreateFromSampleRadio == null ? INITIAL_CREATE_FROM_SAMPLE
-                                                  : mCreateFromSampleRadio.getSelection();
-        }
-
-        /** Returns the value of the "Create Activity" checkbox. */
-        public boolean isCreateActivity() {
-            return mCreateActivityCheck == null ? INITIAL_CREATE_ACTIVITY
-                                                  : mCreateActivityCheck.getSelection();
-        }
-
-        /** Returns the value of the Use Default Location field. */
-        public boolean useDefaultLocation() {
-            return mUseDefaultLocation == null ? INITIAL_USE_DEFAULT_LOCATION
-                                               : mUseDefaultLocation.getSelection();
-        }
-
-        /** Returns the internal source folder (for the "existing project" mode) or the default
-         * "src" constant. */
-        public String getSourceFolder() {
-            if (isNewProject() || mSourceFolder == null || mSourceFolder.length() == 0) {
-                return SdkConstants.FD_SOURCES;
-            } else {
-                return mSourceFolder;
-            }
-        }
-
-        /** Returns the current sdk target or null if none has been selected yet. */
-        public IAndroidTarget getSdkTarget() {
-            return mSdkTargetSelector == null ? null : mSdkTargetSelector.getSelected();
-        }
-    }
-
-    /**
-     * Returns a {@link MainInfo} structure that collects all externally visible information
-     * from this page, to be used by the calling wizard or by other pages.
-     */
-    public IMainInfo getMainInfo() {
-        return mInfo;
-    }
-
-    /**
-     * Grabs the {@link TestInfo} structure that collects externally visible fields from the
-     * test project page. This may be null.
-     */
-    public void setTestInfo(TestInfo testInfo) {
-        mTestInfo = testInfo;
-    }
-
-    /**
-     * Overrides @DialogPage.setVisible(boolean) to put the focus in the project name when
-     * the dialog is made visible.
-     */
-    @Override
-    public void setVisible(boolean visible) {
-        super.setVisible(visible);
-        if (visible) {
-            mProjectNameField.setFocus();
-            validatePageComplete();
-        }
-    }
-
-    // --- UI creation ---
-
-    /**
-     * Creates the top level control for this dialog page under the given parent
-     * composite.
-     *
-     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    public void createControl(Composite parent) {
-        Composite composite = new Composite(parent, SWT.NULL);
-        composite.setFont(parent.getFont());
-
-        initializeDialogUnits(parent);
-
-        composite.setLayout(new GridLayout());
-        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        createProjectNameGroup(composite);
-        createLocationGroup(composite);
-        createTargetGroup(composite);
-        createPropertiesGroup(composite);
-
-        // Update state the first time
-        enableLocationWidgets();
-        loadSamplesForTarget(null /*target*/);
-
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setControl(composite);
-
-        // Validate. This will complain about the first empty field.
-        validatePageComplete();
-    }
-
-    @Override
-    public void dispose() {
-
-        if (mSdkTargetChangeListener != null) {
-            AdtPlugin.getDefault().removeTargetListener(mSdkTargetChangeListener);
-            mSdkTargetChangeListener = null;
-        }
-
-        super.dispose();
-    }
-
-    /**
-     * Creates the group for the project name:
-     * [label: "Project Name"] [text field]
-     *
-     * @param parent the parent composite
-     */
-    private final void createProjectNameGroup(Composite parent) {
-        Composite group = new Composite(parent, SWT.NONE);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        // new project label
-        Label label = new Label(group, SWT.NONE);
-        label.setText("Project name:");
-        label.setFont(parent.getFont());
-        label.setToolTipText("Name of the Eclipse project to create. It cannot be empty.");
-
-        // new project name entry field
-        mProjectNameField = new Text(group, SWT.BORDER);
-        GridData data = new GridData(GridData.FILL_HORIZONTAL);
-        mProjectNameField.setToolTipText("Name of the Eclipse project to create. It cannot be empty.");
-        mProjectNameField.setLayoutData(data);
-        mProjectNameField.setFont(parent.getFont());
-        mProjectNameField.addListener(SWT.Modify, new Listener() {
-            public void handleEvent(Event event) {
-                if (!mInternalProjectNameUpdate) {
-                    mProjectNameModifiedByUser = true;
-                }
-                updateLocationPathField(null);
-            }
-        });
-    }
-
-
-    /**
-     * Creates the group for the Project options:
-     * [radio] Create new project
-     * [radio] Create project from existing sources
-     * [check] Use default location
-     * Location [text field] [browse button]
-     *
-     * @param parent the parent composite
-     */
-    private final void createLocationGroup(Composite parent) {
-        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
-        // Layout has 4 columns of non-equal size
-        group.setLayout(new GridLayout());
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        group.setFont(parent.getFont());
-        group.setText("Contents");
-
-        mCreateNewProjectRadio = new Button(group, SWT.RADIO);
-        mCreateNewProjectRadio.setText("Create new project in workspace");
-        mCreateNewProjectRadio.setSelection(INITIAL_CREATE_NEW_PROJECT);
-
-        Button existing_project_radio = new Button(group, SWT.RADIO);
-        existing_project_radio.setText("Create project from existing source");
-        existing_project_radio.setSelection(INITIAL_CREATE_FROM_SOURCE);
-
-        mUseDefaultLocation = new Button(group, SWT.CHECK);
-        mUseDefaultLocation.setText("Use default location");
-        mUseDefaultLocation.setSelection(INITIAL_USE_DEFAULT_LOCATION);
-
-        SelectionListener location_listener = new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                enableLocationWidgets();
-                extractNamesFromAndroidManifest();
-                validatePageComplete();
-            }
-        };
-
-        mCreateNewProjectRadio.addSelectionListener(location_listener);
-        existing_project_radio.addSelectionListener(location_listener);
-        mUseDefaultLocation.addSelectionListener(location_listener);
-
-        Composite location_group = new Composite(group, SWT.NONE);
-        location_group.setLayout(new GridLayout(3, /* num columns */
-                false /* columns of not equal size */));
-        location_group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        location_group.setFont(parent.getFont());
-
-        mLocationLabel = new Label(location_group, SWT.NONE);
-        mLocationLabel.setText("Location:");
-
-        mLocationPathField = new Text(location_group, SWT.BORDER);
-        GridData data = new GridData(GridData.FILL, /* horizontal alignment */
-                GridData.BEGINNING, /* vertical alignment */
-                true,  /* grabExcessHorizontalSpace */
-                false, /* grabExcessVerticalSpace */
-                1,     /* horizontalSpan */
-                1);    /* verticalSpan */
-        mLocationPathField.setLayoutData(data);
-        mLocationPathField.setFont(parent.getFont());
-        mLocationPathField.addListener(SWT.Modify, new Listener() {
-           public void handleEvent(Event event) {
-               onLocationPathFieldModified();
-            }
-        });
-
-        mBrowseButton = new Button(location_group, SWT.PUSH);
-        mBrowseButton.setText("Browse...");
-        setButtonLayoutData(mBrowseButton);
-        mBrowseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onOpenDirectoryBrowser();
-            }
-        });
-
-        mCreateFromSampleRadio = new Button(group, SWT.RADIO);
-        mCreateFromSampleRadio.setText("Create project from existing sample");
-        mCreateFromSampleRadio.setSelection(INITIAL_CREATE_FROM_SAMPLE);
-        mCreateFromSampleRadio.addSelectionListener(location_listener);
-
-        Composite samples_group = new Composite(group, SWT.NONE);
-        samples_group.setLayout(new GridLayout(2, /* num columns */
-                false /* columns of not equal size */));
-        samples_group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        samples_group.setFont(parent.getFont());
-
-        new Label(samples_group, SWT.NONE).setText("Samples:");
-
-        mSamplesCombo = new Combo(samples_group, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mSamplesCombo.setEnabled(false);
-        mSamplesCombo.select(0);
-        mSamplesCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mSamplesCombo.setToolTipText("Select a sample");
-
-        mSamplesCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onSampleSelected();
-            }
-        });
-
-    }
-
-    /**
-     * Creates the target group.
-     * It only contains an SdkTargetSelector.
-     */
-    private void createTargetGroup(Composite parent) {
-        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
-        // Layout has 1 column
-        group.setLayout(new GridLayout());
-        group.setLayoutData(new GridData(GridData.FILL_BOTH));
-        group.setFont(parent.getFont());
-        group.setText("Build Target");
-
-        // The selector is created without targets. They are added below in the change listener.
-        mSdkTargetSelector = new SdkTargetSelector(group, null);
-
-        mSdkTargetChangeListener = new ITargetChangeListener() {
-            public void onProjectTargetChange(IProject changedProject) {
-                // Ignore
-            }
-
-            public void onTargetsLoaded() {
-                // Update the sdk target selector with the new targets
-
-                // get the targets from the sdk
-                IAndroidTarget[] targets = null;
-                if (Sdk.getCurrent() != null) {
-                    targets = Sdk.getCurrent().getTargets();
-                }
-                mSdkTargetSelector.setTargets(targets);
-
-                // If there's only one target, select it
-                if (targets != null && targets.length == 1) {
-                    mSdkTargetSelector.setSelection(targets[0]);
-                }
-            }
-        };
-
-        AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);
-
-        // Invoke it once to initialize the targets
-        mSdkTargetChangeListener.onTargetsLoaded();
-
-        mSdkTargetSelector.setSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onSdkTargetModified();
-                updateLocationPathField(null);
-                validatePageComplete();
-            }
-        });
-    }
-
-    /**
-     * Creates the group for the project properties:
-     * - Package name [text field]
-     * - Activity name [text field]
-     * - Application name [text field]
-     *
-     * @param parent the parent composite
-     */
-    private final void createPropertiesGroup(Composite parent) {
-        // package specification group
-        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        group.setFont(parent.getFont());
-        group.setText("Properties");
-
-        // new application label
-        Label label = new Label(group, SWT.NONE);
-        label.setText("Application name:");
-        label.setFont(parent.getFont());
-        label.setToolTipText("Name of the Application. This is a free string. It can be empty.");
-
-        // new application name entry field
-        mApplicationNameField = new Text(group, SWT.BORDER);
-        GridData data = new GridData(GridData.FILL_HORIZONTAL);
-        mApplicationNameField.setToolTipText("Name of the Application. This is a free string. It can be empty.");
-        mApplicationNameField.setLayoutData(data);
-        mApplicationNameField.setFont(parent.getFont());
-        mApplicationNameField.addListener(SWT.Modify, new Listener() {
-           public void handleEvent(Event event) {
-               if (!mInternalApplicationNameUpdate) {
-                   mApplicationNameModifiedByUser = true;
-               }
-           }
-        });
-
-        // new package label
-        label = new Label(group, SWT.NONE);
-        label.setText("Package name:");
-        label.setFont(parent.getFont());
-        label.setToolTipText("Namespace of the Package to create. This must be a Java namespace with at least two components.");
-
-        // new package name entry field
-        mPackageNameField = new Text(group, SWT.BORDER);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        mPackageNameField.setToolTipText("Namespace of the Package to create. This must be a Java namespace with at least two components.");
-        mPackageNameField.setLayoutData(data);
-        mPackageNameField.setFont(parent.getFont());
-        mPackageNameField.addListener(SWT.Modify, new Listener() {
-            public void handleEvent(Event event) {
-                onPackageNameFieldModified();
-            }
-        });
-
-        // new activity label
-        mCreateActivityCheck = new Button(group, SWT.CHECK);
-        mCreateActivityCheck.setText("Create Activity:");
-        mCreateActivityCheck.setToolTipText("Specifies if you want to create a default Activity.");
-        mCreateActivityCheck.setFont(parent.getFont());
-        mCreateActivityCheck.setSelection(INITIAL_CREATE_ACTIVITY);
-        mCreateActivityCheck.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event event) {
-                onCreateActivityCheckModified();
-                enableLocationWidgets();
-            }
-        });
-
-        // new activity name entry field
-        mActivityNameField = new Text(group, SWT.BORDER);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        mActivityNameField.setToolTipText("Name of the Activity class to create. Must be a valid Java identifier.");
-        mActivityNameField.setLayoutData(data);
-        mActivityNameField.setFont(parent.getFont());
-        mActivityNameField.addListener(SWT.Modify, new Listener() {
-            public void handleEvent(Event event) {
-                onActivityNameFieldModified();
-            }
-        });
-
-        // min sdk version label
-        label = new Label(group, SWT.NONE);
-        label.setText("Min SDK Version:");
-        label.setFont(parent.getFont());
-        label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");
-
-        // min sdk version entry field
-        mMinSdkVersionField = new Text(group, SWT.BORDER);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");
-        mMinSdkVersionField.setLayoutData(data);
-        mMinSdkVersionField.setFont(parent.getFont());
-        mMinSdkVersionField.addListener(SWT.Modify, new Listener() {
-            public void handleEvent(Event event) {
-                onMinSdkVersionFieldModified();
-                validatePageComplete();
-            }
-        });
-    }
-
-
-    //--- Internal getters & setters ------------------
-
-    /** Returns the location path field value with spaces trimmed. */
-    private String getLocationPathFieldValue() {
-        return mLocationPathField == null ? "" : mLocationPathField.getText().trim();  //$NON-NLS-1$
-    }
-
-    /** Returns the current selected sample path,
-     * or an empty string if there's no valid selection. */
-    private String getSelectedSamplePath() {
-        int selIndex = mSamplesCombo.getSelectionIndex();
-        if (selIndex >= 0 && selIndex < mSamplesPaths.size()) {
-            return mSamplesPaths.get(selIndex);
-        }
-        return "";
-    }
-
-    /** Returns the current project location, depending on the Use Default Location check box
-     * or the Create From Sample check box. */
-    private String getProjectLocation() {
-        if (mInfo.isCreateFromSample()) {
-            return getSelectedSamplePath();
-        } else if (mInfo.isNewProject() && mInfo.useDefaultLocation()) {
-            return Platform.getLocation().toString();
-        } else {
-            return getLocationPathFieldValue();
-        }
-    }
-
-    /**
-     * Creates a project resource handle for the current project name field
-     * value.
-     * <p>
-     * This method does not create the project resource; this is the
-     * responsibility of <code>IProject::create</code> invoked by the new
-     * project resource wizard.
-     * </p>
-     *
-     * @return the new project resource handle
-     */
-    private IProject getProjectHandle() {
-        return ResourcesPlugin.getWorkspace().getRoot().getProject(mInfo.getProjectName());
-    }
-
-    // --- UI Callbacks ----
-
-    /**
-     * Display a directory browser and update the location path field with the selected path
-     */
-    private void onOpenDirectoryBrowser() {
-
-        String existing_dir = getLocationPathFieldValue();
-
-        // Disable the path if it doesn't exist
-        if (existing_dir.length() == 0) {
-            existing_dir = null;
-        } else {
-            File f = new File(existing_dir);
-            if (!f.exists()) {
-                existing_dir = null;
-            }
-        }
-
-        DirectoryDialog dd = new DirectoryDialog(mLocationPathField.getShell());
-        dd.setMessage("Browse for folder");
-        dd.setFilterPath(existing_dir);
-        String abs_dir = dd.open();
-
-        if (abs_dir != null) {
-            updateLocationPathField(abs_dir);
-            extractNamesFromAndroidManifest();
-            validatePageComplete();
-        }
-    }
-
-    /**
-     * A sample was selected. Update the location field, manifest and validate.
-     */
-    private void onSampleSelected() {
-        // Note that getProjectLocation() is automatically updated to use the currently
-        // selected sample. We just need to refresh the manifest data & validate.
-        extractNamesFromAndroidManifest();
-        validatePageComplete();
-    }
-
-    /**
-     * Enables or disable the location widgets depending on the user selection:
-     * the location path is enabled when using the "existing source" mode (i.e. not new project)
-     * or in new project mode with the "use default location" turned off.
-     */
-    private void enableLocationWidgets() {
-        boolean is_new_project = mInfo.isNewProject();
-        boolean is_create_from_sample = mInfo.isCreateFromSample();
-        boolean use_default = mInfo.useDefaultLocation() && !is_create_from_sample;
-        boolean location_enabled = (!is_new_project || !use_default) && !is_create_from_sample;
-        boolean create_activity = mInfo.isCreateActivity();
-
-        mUseDefaultLocation.setEnabled(is_new_project);
-
-        mLocationLabel.setEnabled(location_enabled);
-        mLocationPathField.setEnabled(location_enabled);
-        mBrowseButton.setEnabled(location_enabled);
-
-        mSamplesCombo.setEnabled(is_create_from_sample && mSamplesPaths.size() > 0);
-
-        mPackageNameField.setEnabled(is_new_project);
-        mCreateActivityCheck.setEnabled(is_new_project);
-        mActivityNameField.setEnabled(is_new_project & create_activity);
-
-        updateLocationPathField(null);
-        updatePackageAndActivityFields();
-    }
-
-    /**
-     * Updates the location directory path field.
-     * <br/>
-     * When custom user selection is enabled, use the abs_dir argument if not null and also
-     * save it internally. If abs_dir is null, restore the last saved abs_dir. This allows the
-     * user selection to be remembered when the user switches from default to custom.
-     * <br/>
-     * When custom user selection is disabled, use the workspace default location with the
-     * current project name. This does not change the internally cached abs_dir.
-     *
-     * @param abs_dir A new absolute directory path or null to use the default.
-     */
-    private void updateLocationPathField(String abs_dir) {
-
-        // We don't touch the location path if using the "Create From Sample" mode
-        if (mInfo.isCreateFromSample()) {
-            return;
-        }
-
-        boolean is_new_project = mInfo.isNewProject();
-        boolean use_default = mInfo.useDefaultLocation();
-        boolean custom_location = !is_new_project || !use_default;
-
-        if (!mInternalLocationPathUpdate) {
-            mInternalLocationPathUpdate = true;
-            if (custom_location) {
-                if (abs_dir != null) {
-                    // We get here if the user selected a directory with the "Browse" button.
-                    // Disable auto-compute of the custom location unless the user selected
-                    // the exact same path.
-                    sAutoComputeCustomLocation = sAutoComputeCustomLocation &&
-                                                 abs_dir.equals(sCustomLocationOsPath);
-                    sCustomLocationOsPath = TextProcessor.process(abs_dir);
-                } else  if (sAutoComputeCustomLocation ||
-                            (!is_new_project && !new File(sCustomLocationOsPath).isDirectory())) {
-                    // By default select the samples directory of the current target
-                    IAndroidTarget target = mInfo.getSdkTarget();
-                    if (target != null) {
-                        sCustomLocationOsPath = target.getPath(IAndroidTarget.SAMPLES);
-                    }
-
-                    // If we don't have a target, select the base directory of the
-                    // "universal sdk". If we don't even have that, use a root drive.
-                    if (sCustomLocationOsPath == null || sCustomLocationOsPath.length() == 0) {
-                        if (Sdk.getCurrent() != null) {
-                            sCustomLocationOsPath = Sdk.getCurrent().getSdkLocation();
-                        } else {
-                            sCustomLocationOsPath = File.listRoots()[0].getAbsolutePath();
-                        }
-                    }
-                }
-                if (!mLocationPathField.getText().equals(sCustomLocationOsPath)) {
-                    mLocationPathField.setText(sCustomLocationOsPath);
-                }
-            } else {
-                String value = Platform.getLocation().append(mInfo.getProjectName()).toString();
-                value = TextProcessor.process(value);
-                if (!mLocationPathField.getText().equals(value)) {
-                    mLocationPathField.setText(value);
-                }
-            }
-            validatePageComplete();
-            mInternalLocationPathUpdate = false;
-        }
-    }
-
-    /**
-     * The location path field is either modified internally (from updateLocationPathField)
-     * or manually by the user when the custom_location mode is not set.
-     *
-     * Ignore the internal modification. When modified by the user, memorize the choice and
-     * validate the page.
-     */
-    private void onLocationPathFieldModified() {
-        if (!mInternalLocationPathUpdate) {
-            // When the updates doesn't come from updateLocationPathField, it must be the user
-            // editing the field manually, in which case we want to save the value internally
-            // and we disable auto-compute of the custom location (to avoid overriding the user
-            // value)
-            String newPath = getLocationPathFieldValue();
-            sAutoComputeCustomLocation = sAutoComputeCustomLocation &&
-                                         newPath.equals(sCustomLocationOsPath);
-            sCustomLocationOsPath = newPath;
-            extractNamesFromAndroidManifest();
-            validatePageComplete();
-        }
-    }
-
-    /**
-     * The package name field is either modified internally (from extractNamesFromAndroidManifest)
-     * or manually by the user when the custom_location mode is not set.
-     *
-     * Ignore the internal modification. When modified by the user, memorize the choice and
-     * validate the page.
-     */
-    private void onPackageNameFieldModified() {
-        if (mInfo.isNewProject()) {
-            mUserPackageName = mInfo.getPackageName();
-            validatePageComplete();
-        }
-    }
-
-    /**
-     * The create activity checkbox is either modified internally (from
-     * extractNamesFromAndroidManifest)  or manually by the user.
-     *
-     * Ignore the internal modification. When modified by the user, memorize the choice and
-     * validate the page.
-     */
-    private void onCreateActivityCheckModified() {
-        if (mInfo.isNewProject() && !mInternalCreateActivityUpdate) {
-            mUserCreateActivityCheck = mInfo.isCreateActivity();
-        }
-        validatePageComplete();
-    }
-
-    /**
-     * The activity name field is either modified internally (from extractNamesFromAndroidManifest)
-     * or manually by the user when the custom_location mode is not set.
-     *
-     * Ignore the internal modification. When modified by the user, memorize the choice and
-     * validate the page.
-     */
-    private void onActivityNameFieldModified() {
-        if (mInfo.isNewProject() && !mInternalActivityNameUpdate) {
-            mUserActivityName = mInfo.getActivityName();
-            validatePageComplete();
-        }
-    }
-
-    /**
-     * Called when the min sdk version field has been modified.
-     *
-     * Ignore the internal modifications. When modified by the user, try to match
-     * a target with the same API level.
-     */
-    private void onMinSdkVersionFieldModified() {
-        if (mInternalMinSdkVersionUpdate) {
-            return;
-        }
-
-        String minSdkVersion = mInfo.getMinSdkVersion();
-
-        // Before changing, compare with the currently selected one, if any.
-        // There can be multiple targets with the same sdk api version, so don't change
-        // it if it's already at the right version.
-        IAndroidTarget curr_target = mInfo.getSdkTarget();
-        if (curr_target != null && curr_target.getVersion().equals(minSdkVersion)) {
-            return;
-        }
-
-        for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-            if (target.getVersion().equals(minSdkVersion)) {
-                mSdkTargetSelector.setSelection(target);
-                break;
-            }
-        }
-    }
-
-    /**
-     * Called when an SDK target is modified.
-     *
-     * Also changes the minSdkVersion field to reflect the sdk api level that has
-     * just been selected.
-     */
-    private void onSdkTargetModified() {
-        IAndroidTarget target = mInfo.getSdkTarget();
-
-        if (target != null) {
-            mInternalMinSdkVersionUpdate = true;
-            mMinSdkVersionField.setText(target.getVersion().getApiString());
-            mInternalMinSdkVersionUpdate = false;
-        }
-
-        loadSamplesForTarget(target);
-        enableLocationWidgets();
-        onSampleSelected();
-    }
-
-    /**
-     * Called when the radio buttons are changed between the "create new project" and the
-     * "use existing source" mode. This reverts the fields to whatever the user manually
-     * entered before.
-     */
-    private void updatePackageAndActivityFields() {
-        if (mInfo.isNewProject()) {
-            if (mUserPackageName.length() > 0 &&
-                    !mPackageNameField.getText().equals(mUserPackageName)) {
-                mPackageNameField.setText(mUserPackageName);
-            }
-
-            if (mUserActivityName.length() > 0 &&
-                    !mActivityNameField.getText().equals(mUserActivityName)) {
-                mInternalActivityNameUpdate = true;
-                mActivityNameField.setText(mUserActivityName);
-                mInternalActivityNameUpdate = false;
-            }
-
-            if (mUserCreateActivityCheck != mCreateActivityCheck.getSelection()) {
-                mInternalCreateActivityUpdate = true;
-                mCreateActivityCheck.setSelection(mUserCreateActivityCheck);
-                mInternalCreateActivityUpdate = false;
-            }
-        }
-    }
-
-    /**
-     * Extract names from an android manifest.
-     * This is done only if the user selected the "use existing source" and a manifest xml file
-     * can actually be found in the custom user directory.
-     */
-    private void extractNamesFromAndroidManifest() {
-        if (mInfo.isNewProject()) {
-            return;
-        }
-
-        String projectLocation = getProjectLocation();
-        File f = new File(projectLocation);
-        if (!f.isDirectory()) {
-            return;
-        }
-
-        Path path = new Path(f.getPath());
-        String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
-
-        AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath);
-        if (manifestData == null) {
-            return;
-        }
-
-        String packageName = null;
-        Activity activity = null;
-        String activityName = null;
-        String minSdkVersion = null;
-        try {
-            packageName = manifestData.getPackage();
-            minSdkVersion = manifestData.getApiLevelRequirement();
-
-            // try to get the first launcher activity. If none, just take the first activity.
-            activity = manifestData.getLauncherActivity();
-            if (activity == null) {
-                Activity[] activities = manifestData.getActivities();
-                if (activities != null && activities.length > 0) {
-                    activity = activities[0];
-                }
-            }
-        } catch (Exception e) {
-            // ignore exceptions
-        }
-
-        if (packageName != null && packageName.length() > 0) {
-            mPackageNameField.setText(packageName);
-        }
-
-        if (activity != null) {
-            activityName = AndroidManifestParser.extractActivityName(activity.getName(),
-                    packageName);
-        }
-
-        if (activityName != null && activityName.length() > 0) {
-            mInternalActivityNameUpdate = true;
-            mInternalCreateActivityUpdate = true;
-            mActivityNameField.setText(activityName);
-            mCreateActivityCheck.setSelection(true);
-            mInternalCreateActivityUpdate = false;
-            mInternalActivityNameUpdate = false;
-
-            // If project name and application names are empty, use the activity
-            // name as a default. If the activity name has dots, it's a part of a
-            // package specification and only the last identifier must be used.
-            if (activityName.indexOf('.') != -1) {
-                String[] ids = activityName.split(AndroidConstants.RE_DOT);
-                activityName = ids[ids.length - 1];
-            }
-            if (mProjectNameField.getText().length() == 0 || !mProjectNameModifiedByUser) {
-                mInternalProjectNameUpdate = true;
-                mProjectNameModifiedByUser = false;
-                mProjectNameField.setText(activityName);
-                mInternalProjectNameUpdate = false;
-            }
-            if (mApplicationNameField.getText().length() == 0 || !mApplicationNameModifiedByUser) {
-                mInternalApplicationNameUpdate = true;
-                mApplicationNameModifiedByUser = false;
-                mApplicationNameField.setText(activityName);
-                mInternalApplicationNameUpdate = false;
-            }
-        } else {
-            mInternalActivityNameUpdate = true;
-            mInternalCreateActivityUpdate = true;
-            mActivityNameField.setText("");  //$NON-NLS-1$
-            mCreateActivityCheck.setSelection(false);
-            mInternalCreateActivityUpdate = false;
-            mInternalActivityNameUpdate = false;
-
-            // There is no activity name to use to fill in the project and application
-            // name. However if there's a package name, we can use this as a base.
-            if (packageName != null && packageName.length() > 0) {
-                // Package name is a java identifier, so it's most suitable for
-                // an application name.
-
-                if (mApplicationNameField.getText().length() == 0 ||
-                        !mApplicationNameModifiedByUser) {
-                    mInternalApplicationNameUpdate = true;
-                    mApplicationNameField.setText(packageName);
-                    mInternalApplicationNameUpdate = false;
-                }
-
-                // For the project name, remove any dots
-                packageName = packageName.replace('.', '_');
-                if (mProjectNameField.getText().length() == 0 || !mProjectNameModifiedByUser) {
-                    mInternalProjectNameUpdate = true;
-                    mProjectNameField.setText(packageName);
-                    mInternalProjectNameUpdate = false;
-                }
-
-            }
-        }
-
-        // Select the target matching the manifest's sdk or build properties, if any
-        IAndroidTarget foundTarget = null;
-        IAndroidTarget currentTarget = mInfo.getSdkTarget();
-
-        ProjectProperties p = ProjectProperties.create(projectLocation, null);
-        if (p != null) {
-            // Check the {build|default}.properties files if present
-            p.merge(PropertyType.BUILD).merge(PropertyType.DEFAULT);
-            String v = p.getProperty(ProjectProperties.PROPERTY_TARGET);
-            IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString(v);
-            // We can change the current target if:
-            // - we found a new target
-            // - there is no current target
-            // - there is a current target but the new target is not <= to the current one.
-            if (target != null &&
-                    (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
-                foundTarget = target;
-            }
-        }
-
-        if (foundTarget == null && minSdkVersion != null) {
-            // Otherwise try to match the requested sdk version
-            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-                if (target != null &&
-                        target.getVersion().equals(minSdkVersion) &&
-                        (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
-                    foundTarget = target;
-                    break;
-                }
-            }
-        }
-
-        if (foundTarget == null) {
-            // Or last attemp, try to match a sample project location
-            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-                if (target != null &&
-                        projectLocation.startsWith(target.getLocation()) &&
-                        (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
-                    foundTarget = target;
-                    break;
-                }
-            }
-        }
-
-        if (foundTarget != null) {
-            mSdkTargetSelector.setSelection(foundTarget);
-        } else {
-            mInternalMinSdkVersionUpdate = true;
-            if (minSdkVersion != null) {
-                mMinSdkVersionField.setText(minSdkVersion);
-            }
-            mInternalMinSdkVersionUpdate = false;
-        }
-    }
-
-    /**
-     * Updates the list of all samples for the given target SDK.
-     * The list is stored in mSamplesPaths as absolute directory paths.
-     * The combo is recreated to match this.
-     */
-    private void loadSamplesForTarget(IAndroidTarget target) {
-
-        // Keep the name of the old selection (if there were any samples)
-        String oldChoice = null;
-        if (mSamplesPaths.size() > 0) {
-            int selIndex = mSamplesCombo.getSelectionIndex();
-            if (selIndex > -1) {
-                oldChoice = mSamplesCombo.getItem(selIndex);
-            }
-        }
-
-        // Clear all current content
-        mSamplesCombo.removeAll();
-        mSamplesPaths.clear();
-
-        if (target != null) {
-            // Get the sample root path and recompute the list of samples
-            String samplesRootPath = target.getPath(IAndroidTarget.SAMPLES);
-
-            File samplesDir = new File(samplesRootPath);
-            findSamplesManifests(samplesDir, mSamplesPaths);
-
-            if (mSamplesPaths.size() == 0) {
-                // Odd, this target has no samples. Could happen with an addon.
-                mSamplesCombo.add("This target has no samples. Please select another target.");
-                mSamplesCombo.select(0);
-                return;
-            }
-
-            // Recompute the description of each sample (the relative path
-            // to the sample root). Also try to find the old selection.
-            int selIndex = 0;
-            int i = 0;
-            int n = samplesRootPath.length();
-            for (String path : mSamplesPaths) {
-                if (path.length() > n) {
-                    path = path.substring(n);
-                    if (path.charAt(0) == File.separatorChar) {
-                        path = path.substring(1);
-                    }
-                    if (path.endsWith(File.separator)) {
-                        path = path.substring(0, path.length() - 1);
-                    }
-                    path = path.replaceAll(Pattern.quote(File.separator), " > ");
-                }
-
-                if (oldChoice != null && oldChoice.equals(path)) {
-                    selIndex = i;
-                }
-
-                mSamplesCombo.add(path);
-                i++;
-            }
-
-            mSamplesCombo.select(selIndex);
-
-        } else {
-            mSamplesCombo.add("Please select a target.");
-            mSamplesCombo.select(0);
-        }
-    }
-
-    /**
-     * Recursively find potential sample directories under the given directory.
-     * Actually lists any directory that contains an android manifest.
-     * Paths found are added the samplesPaths list.
-     */
-    private void findSamplesManifests(File samplesDir, ArrayList<String> samplesPaths) {
-        if (!samplesDir.isDirectory()) {
-            return;
-        }
-
-        for (File f : samplesDir.listFiles()) {
-            if (f.isDirectory()) {
-                // Assume this is a sample if it contains an android manifest.
-                File manifestFile = new File(f, SdkConstants.FN_ANDROID_MANIFEST_XML);
-                if (manifestFile.isFile()) {
-                    samplesPaths.add(f.getPath());
-                }
-
-                // Recurse in the project, to find embedded tests sub-projects
-                // We can however skip this recursion for known android sub-dirs that
-                // can't have projects, namely for sources, assets and resources.
-                String leaf = f.getName();
-                if (!SdkConstants.FD_SOURCES.equals(leaf) &&
-                        !SdkConstants.FD_ASSETS.equals(leaf) &&
-                        !SdkConstants.FD_RES.equals(leaf)) {
-                    findSamplesManifests(f, samplesPaths);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns whether this page's controls currently all contain valid values.
-     *
-     * @return <code>true</code> if all controls are valid, and
-     *         <code>false</code> if at least one is invalid
-     */
-    private boolean validatePage() {
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-
-        int status = validateProjectField(workspace);
-        if ((status & MSG_ERROR) == 0) {
-            status |= validateSdkTarget();
-        }
-        if ((status & MSG_ERROR) == 0) {
-            status |= validateLocationPath(workspace);
-        }
-        if ((status & MSG_ERROR) == 0) {
-            status |= validatePackageField();
-        }
-        if ((status & MSG_ERROR) == 0) {
-            status |= validateActivityField();
-        }
-        if ((status & MSG_ERROR) == 0) {
-            status |= validateMinSdkVersionField();
-        }
-        if ((status & MSG_ERROR) == 0) {
-            status |= validateSourceFolder();
-        }
-        if (status == MSG_NONE)  {
-            setStatus(null, MSG_NONE);
-        }
-
-        // Return false if there's an error so that the finish button be disabled.
-        return (status & MSG_ERROR) == 0;
-    }
-
-    /**
-     * Validates the page and updates the Next/Finish buttons
-     */
-    private void validatePageComplete() {
-        setPageComplete(validatePage());
-    }
-
-    /**
-     * Validates the project name field.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateProjectField(IWorkspace workspace) {
-        // Validate project field
-        String projectName = mInfo.getProjectName();
-        if (projectName.length() == 0) {
-            return setStatus("Project name must be specified", MSG_ERROR);
-        }
-
-        // Limit the project name to shell-agnostic characters since it will be used to
-        // generate the final package
-        if (!sProjectNamePattern.matcher(projectName).matches()) {
-            return setStatus("The project name must start with an alphanumeric characters, followed by one or more alphanumerics, digits, dots, dashes, underscores or spaces.",
-                    MSG_ERROR);
-        }
-
-        IStatus nameStatus = workspace.validateName(projectName, IResource.PROJECT);
-        if (!nameStatus.isOK()) {
-            return setStatus(nameStatus.getMessage(), MSG_ERROR);
-        }
-
-        if (getProjectHandle().exists()) {
-            return setStatus("A project with that name already exists in the workspace",
-                    MSG_ERROR);
-        }
-
-        if (mTestInfo != null &&
-                mTestInfo.getCreateTestProject() &&
-                projectName.equals(mTestInfo.getProjectName())) {
-            return setStatus("The main project name and the test project name must be different.",
-                    MSG_WARNING);
-        }
-
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the location path field.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateLocationPath(IWorkspace workspace) {
-        Path path = new Path(getProjectLocation());
-        if (mInfo.isNewProject()) {
-            if (!mInfo.useDefaultLocation()) {
-                // If not using the default value validate the location.
-                URI uri = URIUtil.toURI(path.toOSString());
-                IStatus locationStatus = workspace.validateProjectLocationURI(getProjectHandle(),
-                        uri);
-                if (!locationStatus.isOK()) {
-                    return setStatus(locationStatus.getMessage(), MSG_ERROR);
-                } else {
-                    // The location is valid as far as Eclipse is concerned (i.e. mostly not
-                    // an existing workspace project.) Check it either doesn't exist or is
-                    // a directory that is empty.
-                    File f = path.toFile();
-                    if (f.exists() && !f.isDirectory()) {
-                        return setStatus("A directory name must be specified.", MSG_ERROR);
-                    } else if (f.isDirectory()) {
-                        // However if the directory exists, we should put a warning if it is not
-                        // empty. We don't put an error (we'll ask the user again for confirmation
-                        // before using the directory.)
-                        String[] l = f.list();
-                        if (l.length != 0) {
-                            return setStatus("The selected output directory is not empty.",
-                                    MSG_WARNING);
-                        }
-                    }
-                }
-            } else {
-                // Otherwise validate the path string is not empty
-                if (getProjectLocation().length() == 0) {
-                    return setStatus("A directory name must be specified.", MSG_ERROR);
-                }
-
-                File dest = path.append(mInfo.getProjectName()).toFile();
-                if (dest.exists()) {
-                    return setStatus(String.format("There is already a file or directory named \"%1$s\" in the selected location.",
-                            mInfo.getProjectName()), MSG_ERROR);
-                }
-            }
-        } else {
-            // Must be an existing directory
-            File f = path.toFile();
-            if (!f.isDirectory()) {
-                return setStatus("An existing directory name must be specified.", MSG_ERROR);
-            }
-
-            // Check there's an android manifest in the directory
-            String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
-            File manifestFile = new File(osPath);
-            if (!manifestFile.isFile()) {
-                return setStatus(
-                        String.format("File %1$s not found in %2$s.",
-                                AndroidConstants.FN_ANDROID_MANIFEST, f.getName()),
-                                MSG_ERROR);
-            }
-
-            // Parse it and check the important fields.
-            AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath);
-            if (manifestData == null) {
-                return setStatus(
-                        String.format("File %1$s could not be parsed.", osPath),
-                        MSG_ERROR);
-            }
-
-            String packageName = manifestData.getPackage();
-            if (packageName == null || packageName.length() == 0) {
-                return setStatus(
-                        String.format("No package name defined in %1$s.", osPath),
-                        MSG_ERROR);
-            }
-
-            Activity[] activities = manifestData.getActivities();
-            if (activities == null || activities.length == 0) {
-                // This is acceptable now as long as no activity needs to be created
-                if (mInfo.isCreateActivity()) {
-                    return setStatus(
-                            String.format("No activity name defined in %1$s.", osPath),
-                            MSG_ERROR);
-                }
-            }
-
-            // If there's already a .project, tell the user to use import instead.
-            if (path.append(".project").toFile().exists()) {  //$NON-NLS-1$
-                return setStatus("An Eclipse project already exists in this directory. Consider using File > Import > Existing Project instead.",
-                        MSG_WARNING);
-            }
-        }
-
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the sdk target choice.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateSdkTarget() {
-        if (mInfo.getSdkTarget() == null) {
-            return setStatus("An SDK Target must be specified.", MSG_ERROR);
-        }
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the sdk target choice.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateMinSdkVersionField() {
-
-        // If the min sdk version is empty, it is always accepted.
-        if (mInfo.getMinSdkVersion().length() == 0) {
-            return MSG_NONE;
-        }
-
-        if (mInfo.getSdkTarget() != null &&
-                mInfo.getSdkTarget().getVersion().equals(mInfo.getMinSdkVersion()) == false) {
-            return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
-                    mInfo.getSdkTarget().getVersion().isPreview() ? MSG_ERROR : MSG_WARNING);
-        }
-
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the activity name field.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateActivityField() {
-        // Disregard if not creating an activity
-        if (!mInfo.isCreateActivity()) {
-            return MSG_NONE;
-        }
-
-        // Validate activity field
-        String activityFieldContents = mInfo.getActivityName();
-        if (activityFieldContents.length() == 0) {
-            return setStatus("Activity name must be specified.", MSG_ERROR);
-        }
-
-        // The activity field can actually contain part of a sub-package name
-        // or it can start with a dot "." to indicates it comes from the parent package name.
-        String packageName = "";  //$NON-NLS-1$
-        int pos = activityFieldContents.lastIndexOf('.');
-        if (pos >= 0) {
-            packageName = activityFieldContents.substring(0, pos);
-            if (packageName.startsWith(".")) { //$NON-NLS-1$
-                packageName = packageName.substring(1);
-            }
-
-            activityFieldContents = activityFieldContents.substring(pos + 1);
-        }
-
-        // the activity field can contain a simple java identifier, or a
-        // package name or one that starts with a dot. So if it starts with a dot,
-        // ignore this dot -- the rest must look like a package name.
-        if (activityFieldContents.charAt(0) == '.') {
-            activityFieldContents = activityFieldContents.substring(1);
-        }
-
-        // Check it's a valid activity string
-        int result = MSG_NONE;
-        IStatus status = JavaConventions.validateTypeVariableName(activityFieldContents,
-                                                            "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
-        if (!status.isOK()) {
-            result = setStatus(status.getMessage(),
-                        status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
-        }
-
-        // Check it's a valid package string
-        if (result != MSG_ERROR && packageName.length() > 0) {
-            status = JavaConventions.validatePackageName(packageName,
-                                                            "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
-            if (!status.isOK()) {
-                result = setStatus(status.getMessage() + " (in the activity name)",
-                            status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
-            }
-        }
-
-
-        return result;
-    }
-
-    /**
-     * Validates the package name field.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validatePackageField() {
-        // Validate package field
-        String packageFieldContents = mInfo.getPackageName();
-        if (packageFieldContents.length() == 0) {
-            return setStatus("Package name must be specified.", MSG_ERROR);
-        }
-
-        // Check it's a valid package string
-        int result = MSG_NONE;
-        IStatus status = JavaConventions.validatePackageName(packageFieldContents, "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
-        if (!status.isOK()) {
-            result = setStatus(status.getMessage(),
-                        status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
-        }
-
-        // The Android Activity Manager does not accept packages names with only one
-        // identifier. Check the package name has at least one dot in them (the previous rule
-        // validated that if such a dot exist, it's not the first nor last characters of the
-        // string.)
-        if (result != MSG_ERROR && packageFieldContents.indexOf('.') == -1) {
-            return setStatus("Package name must have at least two identifiers.", MSG_ERROR);
-        }
-
-        return result;
-    }
-
-    /**
-     * Validates that an existing project actually has a source folder.
-     *
-     * For project in "use existing source" mode, this tries to find the source folder.
-     * A source folder should be just under the project directory and it should have all
-     * the directories composing the package+activity name.
-     *
-     * As a side effect, it memorizes the source folder in mSourceFolder.
-     *
-     * TODO: support multiple source folders for multiple activities.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateSourceFolder() {
-        // This check does nothing when creating a new project.
-        // This check is also useless when no activity is present or created.
-        if (mInfo.isNewProject() || !mInfo.isCreateActivity()) {
-            return MSG_NONE;
-        }
-
-        String osTarget = mInfo.getActivityName();
-
-        if (osTarget.indexOf('.') == -1) {
-            osTarget = mInfo.getPackageName() + File.separator + osTarget;
-        } else if (osTarget.indexOf('.') == 0) {
-            osTarget = mInfo.getPackageName() + osTarget;
-        }
-        osTarget = osTarget.replace('.', File.separatorChar) + AndroidConstants.DOT_JAVA;
-
-        String projectPath = getProjectLocation();
-        File projectDir = new File(projectPath);
-        File[] all_dirs = projectDir.listFiles(new FileFilter() {
-            public boolean accept(File pathname) {
-                return pathname.isDirectory();
-            }
-        });
-        for (File f : all_dirs) {
-            Path path = new Path(f.getAbsolutePath());
-            File java_activity = path.append(osTarget).toFile();
-            if (java_activity.isFile()) {
-                mSourceFolder = f.getName();
-                return MSG_NONE;
-            }
-        }
-
-        if (all_dirs.length > 0) {
-            return setStatus(
-                    String.format("%1$s can not be found under %2$s.", osTarget, projectPath),
-                    MSG_ERROR);
-        } else {
-            return setStatus(
-                    String.format("No source folders can be found in %1$s.", projectPath),
-                    MSG_ERROR);
-        }
-    }
-
-    /**
-     * Sets the error message for the wizard with the given message icon.
-     *
-     * @param message The wizard message type, one of MSG_ERROR or MSG_WARNING.
-     * @return As a convenience, always returns messageType so that the caller can return
-     *         immediately.
-     */
-    private int setStatus(String message, int messageType) {
-        if (message == null) {
-            setErrorMessage(null);
-            setMessage(null);
-        } else if (!message.equals(getMessage())) {
-            setMessage(message, messageType == MSG_WARNING ? WizardPage.WARNING : WizardPage.ERROR);
-        }
-        return messageType;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java
deleted file mode 100644
index df333a5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java
+++ /dev/null
@@ -1,1092 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.newproject;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidNature;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage.IMainInfo;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectCreationPage.TestInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceStatus;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IAccessRule;
-import org.eclipse.jdt.core.IClasspathAttribute;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.ui.actions.OpenJavaPerspectiveAction;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.ui.INewWizard;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.actions.WorkspaceModifyOperation;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * A "New Android Project" Wizard.
- * <p/>
- * Note: this class is public so that it can be accessed from unit tests.
- * It is however an internal class. Its API may change without notice.
- * It should semantically be considered as a private final class.
- * Do not derive from this class.
-
- */
-public class NewProjectWizard extends Wizard implements INewWizard {
-
-    /**
-     * Indicates which pages should be available in the New Project Wizard.
-     */
-    protected enum AvailablePages {
-        /**
-         * Both the usual "Android Project" and the "Android Test Project" pages will
-         * be available. The first page displayed will be the former one and it can depend
-         * on the soon-to-be created normal project.
-         */
-        ANDROID_AND_TEST_PROJECT,
-        /**
-         * Only the "Android Test Project" page will be available. User will have to
-         * select an existing Android Project. If the selection matches such a project,
-         * it will be used as a default.
-         */
-        TEST_PROJECT_ONLY
-    }
-
-    private static final String PARAM_SDK_TOOLS_DIR = "ANDROID_SDK_TOOLS";          //$NON-NLS-1$
-    private static final String PARAM_ACTIVITY = "ACTIVITY_NAME";                   //$NON-NLS-1$
-    private static final String PARAM_APPLICATION = "APPLICATION_NAME";             //$NON-NLS-1$
-    private static final String PARAM_PACKAGE = "PACKAGE";                          //$NON-NLS-1$
-    private static final String PARAM_PROJECT = "PROJECT_NAME";                     //$NON-NLS-1$
-    private static final String PARAM_STRING_NAME = "STRING_NAME";                  //$NON-NLS-1$
-    private static final String PARAM_STRING_CONTENT = "STRING_CONTENT";            //$NON-NLS-1$
-    private static final String PARAM_IS_NEW_PROJECT = "IS_NEW_PROJECT";            //$NON-NLS-1$
-    private static final String PARAM_SRC_FOLDER = "SRC_FOLDER";                    //$NON-NLS-1$
-    private static final String PARAM_SDK_TARGET = "SDK_TARGET";                    //$NON-NLS-1$
-    private static final String PARAM_MIN_SDK_VERSION = "MIN_SDK_VERSION";          //$NON-NLS-1$
-    // Warning: The expanded string PARAM_TEST_TARGET_PACKAGE must not contain the
-    // string "PACKAGE" since it collides with the replacement of PARAM_PACKAGE.
-    private static final String PARAM_TEST_TARGET_PACKAGE = "TEST_TARGET_PCKG";     //$NON-NLS-1$
-    private static final String PARAM_TARGET_SELF = "TARGET_SELF";                  //$NON-NLS-1$
-    private static final String PARAM_TARGET_MAIN = "TARGET_MAIN";                  //$NON-NLS-1$
-    private static final String PARAM_TARGET_EXISTING = "TARGET_EXISTING";          //$NON-NLS-1$
-    private static final String PARAM_REFERENCE_PROJECT = "REFERENCE_PROJECT";      //$NON-NLS-1$
-
-    private static final String PH_ACTIVITIES = "ACTIVITIES";                       //$NON-NLS-1$
-    private static final String PH_USES_SDK = "USES-SDK";                           //$NON-NLS-1$
-    private static final String PH_INTENT_FILTERS = "INTENT_FILTERS";               //$NON-NLS-1$
-    private static final String PH_STRINGS = "STRINGS";                             //$NON-NLS-1$
-    private static final String PH_TEST_USES_LIBRARY = "TEST-USES-LIBRARY";         //$NON-NLS-1$
-    private static final String PH_TEST_INSTRUMENTATION = "TEST-INSTRUMENTATION";   //$NON-NLS-1$
-
-    private static final String BIN_DIRECTORY =
-        SdkConstants.FD_OUTPUT + AndroidConstants.WS_SEP;
-    private static final String RES_DIRECTORY =
-        SdkConstants.FD_RESOURCES + AndroidConstants.WS_SEP;
-    private static final String ASSETS_DIRECTORY =
-        SdkConstants.FD_ASSETS + AndroidConstants.WS_SEP;
-    private static final String DRAWABLE_DIRECTORY =
-        SdkConstants.FD_DRAWABLE + AndroidConstants.WS_SEP;
-    private static final String DRAWABLE_HDPI_DIRECTORY =
-        SdkConstants.FD_DRAWABLE + "-" + Density.HIGH.getValue() + AndroidConstants.WS_SEP;   //$NON-NLS-1$
-    private static final String DRAWABLE_MDPI_DIRECTORY =
-        SdkConstants.FD_DRAWABLE + "-" + Density.MEDIUM.getValue() + AndroidConstants.WS_SEP; //$NON-NLS-1$
-    private static final String DRAWABLE_LDPI_DIRECTORY =
-        SdkConstants.FD_DRAWABLE + "-" + Density.LOW.getValue() + AndroidConstants.WS_SEP;    //$NON-NLS-1$
-    private static final String LAYOUT_DIRECTORY =
-        SdkConstants.FD_LAYOUT + AndroidConstants.WS_SEP;
-    private static final String VALUES_DIRECTORY =
-        SdkConstants.FD_VALUES + AndroidConstants.WS_SEP;
-    private static final String GEN_SRC_DIRECTORY =
-        SdkConstants.FD_GEN_SOURCES + AndroidConstants.WS_SEP;
-
-    private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$
-    private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY
-            + "AndroidManifest.template"; //$NON-NLS-1$
-    private static final String TEMPLATE_ACTIVITIES = TEMPLATES_DIRECTORY
-            + "activity.template"; //$NON-NLS-1$
-    private static final String TEMPLATE_USES_SDK = TEMPLATES_DIRECTORY
-            + "uses-sdk.template"; //$NON-NLS-1$
-    private static final String TEMPLATE_INTENT_LAUNCHER = TEMPLATES_DIRECTORY
-            + "launcher_intent_filter.template"; //$NON-NLS-1$
-    private static final String TEMPLATE_TEST_USES_LIBRARY = TEMPLATES_DIRECTORY
-            + "test_uses-library.template"; //$NON-NLS-1$
-    private static final String TEMPLATE_TEST_INSTRUMENTATION = TEMPLATES_DIRECTORY
-            + "test_instrumentation.template"; //$NON-NLS-1$
-
-
-
-    private static final String TEMPLATE_STRINGS = TEMPLATES_DIRECTORY
-            + "strings.template"; //$NON-NLS-1$
-    private static final String TEMPLATE_STRING = TEMPLATES_DIRECTORY
-            + "string.template"; //$NON-NLS-1$
-    private static final String PROJECT_ICON = "icon.png"; //$NON-NLS-1$
-    private static final String ICON_HDPI = "icon_hdpi.png"; //$NON-NLS-1$
-    private static final String ICON_MDPI = "icon_mdpi.png"; //$NON-NLS-1$
-    private static final String ICON_LDPI = "icon_ldpi.png"; //$NON-NLS-1$
-
-    private static final String STRINGS_FILE = "strings.xml";       //$NON-NLS-1$
-
-    private static final String STRING_RSRC_PREFIX = "@string/";    //$NON-NLS-1$
-    private static final String STRING_APP_NAME = "app_name";       //$NON-NLS-1$
-    private static final String STRING_HELLO_WORLD = "hello";       //$NON-NLS-1$
-
-    private static final String[] DEFAULT_DIRECTORIES = new String[] {
-            BIN_DIRECTORY, RES_DIRECTORY, ASSETS_DIRECTORY };
-    private static final String[] RES_DIRECTORIES = new String[] {
-            DRAWABLE_DIRECTORY, LAYOUT_DIRECTORY, VALUES_DIRECTORY };
-    private static final String[] RES_DENSITY_ENABLED_DIRECTORIES = new String[] {
-            DRAWABLE_HDPI_DIRECTORY, DRAWABLE_MDPI_DIRECTORY, DRAWABLE_LDPI_DIRECTORY,
-            LAYOUT_DIRECTORY, VALUES_DIRECTORY };
-
-    private static final String PROJECT_LOGO_LARGE = "icons/android_large.png"; //$NON-NLS-1$
-    private static final String JAVA_ACTIVITY_TEMPLATE = "java_file.template";  //$NON-NLS-1$
-    private static final String LAYOUT_TEMPLATE = "layout.template";            //$NON-NLS-1$
-    private static final String MAIN_LAYOUT_XML = "main.xml";                   //$NON-NLS-1$
-
-    private NewProjectCreationPage mMainPage;
-    private NewTestProjectCreationPage mTestPage;
-    /** Package name available when the wizard completes. */
-    private String mPackageName;
-    private final AvailablePages mAvailablePages;
-
-    public NewProjectWizard() {
-        this(AvailablePages.ANDROID_AND_TEST_PROJECT);
-    }
-
-    protected NewProjectWizard(AvailablePages availablePages) {
-        mAvailablePages = availablePages;
-    }
-
-    /**
-     * Initializes this creation wizard using the passed workbench and object
-     * selection. Inherited from org.eclipse.ui.IWorkbenchWizard
-     */
-    public void init(IWorkbench workbench, IStructuredSelection selection) {
-        setHelpAvailable(false); // TODO have help
-        setWindowTitle("New Android Project");
-        setImageDescriptor();
-
-        if (mAvailablePages == AvailablePages.ANDROID_AND_TEST_PROJECT) {
-            mMainPage = createMainPage();
-        }
-        mTestPage = createTestPage();
-    }
-
-    /**
-     * Creates the main wizard page.
-     * <p/>
-     * Please do NOT override this method.
-     * <p/>
-     * This is protected so that it can be overridden by unit tests.
-     * However the contract of this class is private and NO ATTEMPT will be made
-     * to maintain compatibility between different versions of the plugin.
-     */
-    protected NewProjectCreationPage createMainPage() {
-        return new NewProjectCreationPage();
-    }
-
-    /**
-     * Creates the test wizard page.
-     * <p/>
-     * Please do NOT override this method.
-     * <p/>
-     * This is protected so that it can be overridden by unit tests.
-     * However the contract of this class is private and NO ATTEMPT will be made
-     * to maintain compatibility between different versions of the plugin.
-     */
-    protected NewTestProjectCreationPage createTestPage() {
-        return new NewTestProjectCreationPage();
-    }
-
-    // -- Methods inherited from org.eclipse.jface.wizard.Wizard --
-    // The Wizard class implements most defaults and boilerplate code needed by
-    // IWizard
-
-    /**
-     * Adds pages to this wizard.
-     */
-    @Override
-    public void addPages() {
-        if (mAvailablePages == AvailablePages.ANDROID_AND_TEST_PROJECT) {
-            addPage(mMainPage);
-        }
-        addPage(mTestPage);
-
-        if (mMainPage != null && mTestPage != null) {
-            mTestPage.setMainInfo(mMainPage.getMainInfo());
-            mMainPage.setTestInfo(mTestPage.getTestInfo());
-        }
-    }
-
-    /**
-     * Performs any actions appropriate in response to the user having pressed
-     * the Finish button, or refuse if finishing now is not permitted: here, it
-     * actually creates the workspace project and then switch to the Java
-     * perspective.
-     *
-     * @return True
-     */
-    @Override
-    public boolean performFinish() {
-        if (!createAndroidProjects()) {
-            return false;
-        }
-
-        // Open the default Java Perspective
-        OpenJavaPerspectiveAction action = new OpenJavaPerspectiveAction();
-        action.run();
-        return true;
-    }
-
-    // -- Public Fields --
-
-    /** Returns the main project package name. Only valid once the wizard finishes. */
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    // -- Custom Methods --
-
-    /**
-     * Before actually creating the project for a new project (as opposed to using an
-     * existing project), we check if the target location is a directory that either does
-     * not exist or is empty.
-     *
-     * If it's not empty, ask the user for confirmation.
-     *
-     * @param destination The destination folder where the new project is to be created.
-     * @return True if the destination doesn't exist yet or is an empty directory or is
-     *         accepted by the user.
-     */
-    private boolean validateNewProjectLocationIsEmpty(IPath destination) {
-        File f = new File(destination.toOSString());
-        if (f.isDirectory() && f.list().length > 0) {
-            return AdtPlugin.displayPrompt("New Android Project",
-                    "You are going to create a new Android Project in an existing, non-empty, directory. Are you sure you want to proceed?");
-        }
-        return true;
-    }
-
-    /**
-     * Structure that describes all the information needed to create a project.
-     * This is collected from the pages by {@link NewProjectWizard#createAndroidProjects()}
-     * and then used by
-     * {@link NewProjectWizard#createProjectAsync(IProgressMonitor, ProjectInfo, ProjectInfo)}.
-     */
-    private static class ProjectInfo {
-        private final IProject mProject;
-        private final IProjectDescription mDescription;
-        private final Map<String, Object> mParameters;
-        private final HashMap<String, String> mDictionary;
-
-        public ProjectInfo(IProject project,
-                IProjectDescription description,
-                Map<String, Object> parameters,
-                HashMap<String, String> dictionary) {
-                    mProject = project;
-                    mDescription = description;
-                    mParameters = parameters;
-                    mDictionary = dictionary;
-        }
-
-        public IProject getProject() {
-            return mProject;
-        }
-
-        public IProjectDescription getDescription() {
-            return mDescription;
-        }
-
-        public Map<String, Object> getParameters() {
-            return mParameters;
-        }
-
-        public HashMap<String, String> getDictionary() {
-            return mDictionary;
-        }
-    }
-
-    /**
-     * Creates the android project.
-     * @return True if the project could be created.
-     */
-    private boolean createAndroidProjects() {
-
-        final ProjectInfo mainData = collectMainPageInfo();
-        if (mMainPage != null && mainData == null) {
-            return false;
-        }
-
-        final ProjectInfo testData = collectTestPageInfo();
-
-        // Create a monitored operation to create the actual project
-        WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-            @Override
-            protected void execute(IProgressMonitor monitor) throws InvocationTargetException {
-                createProjectAsync(monitor, mainData, testData);
-            }
-        };
-
-        // Run the operation in a different thread
-        runAsyncOperation(op);
-        return true;
-    }
-
-    /**
-     * Collects all the parameters needed to create the main project.
-     * @return A new {@link ProjectInfo} on success. Returns null if the project cannot be
-     *    created because parameters are incorrect or should not be created because there
-     *    is no main page.
-     */
-    private ProjectInfo collectMainPageInfo() {
-        if (mMainPage == null) {
-            return null;
-        }
-
-        IMainInfo info = mMainPage.getMainInfo();
-
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-        final IProject project = workspace.getRoot().getProject(info.getProjectName());
-        final IProjectDescription description = workspace.newProjectDescription(project.getName());
-
-        // keep some variables to make them available once the wizard closes
-        mPackageName = info.getPackageName();
-
-        final Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put(PARAM_PROJECT, info.getProjectName());
-        parameters.put(PARAM_PACKAGE, mPackageName);
-        parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME);
-        parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder());
-        parameters.put(PARAM_IS_NEW_PROJECT, info.isNewProject());
-        parameters.put(PARAM_SRC_FOLDER, info.getSourceFolder());
-        parameters.put(PARAM_SDK_TARGET, info.getSdkTarget());
-        parameters.put(PARAM_MIN_SDK_VERSION, info.getMinSdkVersion());
-
-        if (info.isCreateActivity()) {
-            // An activity name can be of the form ".package.Class" or ".Class".
-            // The initial dot is ignored, as it is always added later in the templates.
-            String activityName = info.getActivityName();
-            if (activityName.startsWith(".")) { //$NON-NLS-1$
-                activityName = activityName.substring(1);
-            }
-            parameters.put(PARAM_ACTIVITY, activityName);
-        }
-
-        // create a dictionary of string that will contain name+content.
-        // we'll put all the strings into values/strings.xml
-        final HashMap<String, String> dictionary = new HashMap<String, String>();
-        dictionary.put(STRING_APP_NAME, info.getApplicationName());
-
-        IPath path = info.getLocationPath();
-        IPath defaultLocation = Platform.getLocation();
-        if (!path.equals(defaultLocation)) {
-            description.setLocation(path);
-        }
-
-        if (info.isNewProject() && !info.useDefaultLocation() &&
-                !validateNewProjectLocationIsEmpty(path)) {
-            return null;
-        }
-
-        return new ProjectInfo(project, description, parameters, dictionary);
-    }
-
-    /**
-     * Collects all the parameters needed to create the test project.
-     *
-     * @return A new {@link ProjectInfo} on success. Returns null if the project cannot be
-     *    created because parameters are incorrect or should not be created because there
-     *    is no test page.
-     */
-    private ProjectInfo collectTestPageInfo() {
-        if (mTestPage == null) {
-            return null;
-        }
-        TestInfo info = mTestPage.getTestInfo();
-
-        if (!info.getCreateTestProject()) {
-            return null;
-        }
-
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-        final IProject project = workspace.getRoot().getProject(info.getProjectName());
-        final IProjectDescription description = workspace.newProjectDescription(project.getName());
-
-        final Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put(PARAM_PROJECT, info.getProjectName());
-        parameters.put(PARAM_PACKAGE, info.getPackageName());
-        parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME);
-        parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder());
-        parameters.put(PARAM_IS_NEW_PROJECT, true);
-        parameters.put(PARAM_SRC_FOLDER, info.getSourceFolder());
-        parameters.put(PARAM_SDK_TARGET, info.getSdkTarget());
-        parameters.put(PARAM_MIN_SDK_VERSION, info.getMinSdkVersion());
-
-        // Test-specific parameters
-        parameters.put(PARAM_TEST_TARGET_PACKAGE, info.getTargetPackageName());
-
-        if (info.isTestingSelf()) {
-            parameters.put(PARAM_TARGET_SELF, true);
-        }
-        if (info.isTestingMain()) {
-            parameters.put(PARAM_TARGET_MAIN, true);
-        }
-        if (info.isTestingExisting()) {
-            parameters.put(PARAM_TARGET_EXISTING, true);
-            parameters.put(PARAM_REFERENCE_PROJECT, info.getExistingTestedProject());
-        }
-
-        // create a dictionary of string that will contain name+content.
-        // we'll put all the strings into values/strings.xml
-        final HashMap<String, String> dictionary = new HashMap<String, String>();
-        dictionary.put(STRING_APP_NAME, info.getApplicationName());
-
-        IPath path = info.getLocationPath();
-        IPath defaultLocation = Platform.getLocation();
-        if (!path.equals(defaultLocation)) {
-            description.setLocation(path);
-        }
-
-        if (!info.useDefaultLocation() && !validateNewProjectLocationIsEmpty(path)) {
-            return null;
-        }
-
-        return new ProjectInfo(project, description, parameters, dictionary);
-    }
-
-    /**
-     * Runs the operation in a different thread and display generated
-     * exceptions.
-     *
-     * @param op The asynchronous operation to run.
-     */
-    private void runAsyncOperation(WorkspaceModifyOperation op) {
-        try {
-            getContainer().run(true /* fork */, true /* cancelable */, op);
-        } catch (InvocationTargetException e) {
-            // The runnable threw an exception
-            Throwable t = e.getTargetException();
-            if (t instanceof CoreException) {
-                CoreException core = (CoreException) t;
-                if (core.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
-                    // The error indicates the file system is not case sensitive
-                    // and there's a resource with a similar name.
-                    MessageDialog.openError(getShell(), "Error", "Error: Case Variant Exists");
-                } else {
-                    ErrorDialog.openError(getShell(), "Error", null, core.getStatus());
-                }
-            } else {
-                // Some other kind of exception
-                MessageDialog.openError(getShell(), "Error", t.getMessage());
-            }
-            e.printStackTrace();
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Creates the actual project(s). This is run asynchronously in a different thread.
-     *
-     * @param monitor An existing monitor.
-     * @param mainData Data for main project. Can be null.
-     * @throws InvocationTargetException to wrap any unmanaged exception and
-     *         return it to the calling thread. The method can fail if it fails
-     *         to create or modify the project or if it is canceled by the user.
-     */
-    private void createProjectAsync(IProgressMonitor monitor,
-            ProjectInfo mainData,
-            ProjectInfo testData)
-                throws InvocationTargetException {
-        monitor.beginTask("Create Android Project", 100);
-        try {
-            IProject mainProject = null;
-
-            if (mainData != null) {
-                mainProject = createEclipseProject(
-                        new SubProgressMonitor(monitor, 50),
-                        mainData.getProject(),
-                        mainData.getDescription(),
-                        mainData.getParameters(),
-                        mainData.getDictionary());
-            }
-
-            if (testData != null) {
-
-                Map<String, Object> parameters = testData.getParameters();
-                if (parameters.containsKey(PARAM_TARGET_MAIN) && mainProject != null) {
-                    parameters.put(PARAM_REFERENCE_PROJECT, mainProject);
-                }
-
-                createEclipseProject(
-                        new SubProgressMonitor(monitor, 50),
-                        testData.getProject(),
-                        testData.getDescription(),
-                        parameters,
-                        testData.getDictionary());
-            }
-
-        } catch (CoreException e) {
-            throw new InvocationTargetException(e);
-        } catch (IOException e) {
-            throw new InvocationTargetException(e);
-        } finally {
-            monitor.done();
-        }
-    }
-
-    /**
-     * Creates the actual project, sets its nature and adds the required folders
-     * and files to it. This is run asynchronously in a different thread.
-     *
-     * @param monitor An existing monitor.
-     * @param project The project to create.
-     * @param description A description of the project.
-     * @param parameters Template parameters.
-     * @param dictionary String definition.
-     * @return The project newly created
-     */
-    private IProject createEclipseProject(IProgressMonitor monitor,
-            IProject project,
-            IProjectDescription description,
-            Map<String, Object> parameters,
-            Map<String, String> dictionary)
-                throws CoreException, IOException {
-
-        // get the project target
-        IAndroidTarget target = (IAndroidTarget) parameters.get(PARAM_SDK_TARGET);
-        boolean legacy = target.getVersion().getApiLevel() < 4;
-
-        // Create project and open it
-        project.create(description, new SubProgressMonitor(monitor, 10));
-        if (monitor.isCanceled()) throw new OperationCanceledException();
-
-        project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 10));
-
-        // Add the Java and android nature to the project
-        AndroidNature.setupProjectNatures(project, monitor);
-
-        // Create folders in the project if they don't already exist
-        addDefaultDirectories(project, AndroidConstants.WS_ROOT, DEFAULT_DIRECTORIES, monitor);
-        String[] sourceFolders = new String[] {
-                    (String) parameters.get(PARAM_SRC_FOLDER),
-                    GEN_SRC_DIRECTORY
-                };
-        addDefaultDirectories(project, AndroidConstants.WS_ROOT, sourceFolders, monitor);
-
-        // Create the resource folders in the project if they don't already exist.
-        if (legacy) {
-            addDefaultDirectories(project, RES_DIRECTORY, RES_DIRECTORIES, monitor);
-        } else {
-            addDefaultDirectories(project, RES_DIRECTORY, RES_DENSITY_ENABLED_DIRECTORIES, monitor);
-        }
-
-        // Setup class path: mark folders as source folders
-        IJavaProject javaProject = JavaCore.create(project);
-        for (String sourceFolder : sourceFolders) {
-            setupSourceFolder(javaProject, sourceFolder, monitor);
-        }
-
-        // Mark the gen source folder as derived
-        IFolder genSrcFolder = project.getFolder(AndroidConstants.WS_ROOT + GEN_SRC_DIRECTORY);
-        if (genSrcFolder.exists()) {
-            genSrcFolder.setDerived(true);
-        }
-
-        if (((Boolean) parameters.get(PARAM_IS_NEW_PROJECT)).booleanValue()) {
-            // Create files in the project if they don't already exist
-            addManifest(project, parameters, dictionary, monitor);
-
-            // add the default app icon
-            addIcon(project, legacy, monitor);
-
-            // Create the default package components
-            addSampleCode(project, sourceFolders[0], parameters, dictionary, monitor);
-
-            // add the string definition file if needed
-            if (dictionary.size() > 0) {
-                addStringDictionaryFile(project, dictionary, monitor);
-            }
-
-            // Set output location
-            javaProject.setOutputLocation(project.getFolder(BIN_DIRECTORY).getFullPath(),
-                    monitor);
-        }
-
-        // Create the reference to the target project
-        if (parameters.containsKey(PARAM_REFERENCE_PROJECT)) {
-            IProject refProject = (IProject) parameters.get(PARAM_REFERENCE_PROJECT);
-            if (refProject != null) {
-                IProjectDescription desc = project.getDescription();
-
-                // Add out reference to the existing project reference.
-                // We just created a project with no references so we don't need to expand
-                // the currently-empty current list.
-                desc.setReferencedProjects(new IProject[] { refProject });
-
-                project.setDescription(desc, IResource.KEEP_HISTORY,
-                        new SubProgressMonitor(monitor, 10));
-
-                IClasspathEntry entry = JavaCore.newProjectEntry(
-                        refProject.getFullPath(), //path
-                        new IAccessRule[0], //accessRules
-                        false, //combineAccessRules
-                        new IClasspathAttribute[0], //extraAttributes
-                        false //isExported
-
-                );
-                ProjectHelper.addEntryToClasspath(javaProject, entry);
-            }
-        }
-
-        Sdk.getCurrent().setProject(project, target, null /* apkConfigMap*/);
-
-        // Fix the project to make sure all properties are as expected.
-        // Necessary for existing projects and good for new ones to.
-        ProjectHelper.fixProject(project);
-
-        return project;
-    }
-
-    /**
-     * Adds default directories to the project.
-     *
-     * @param project The Java Project to update.
-     * @param parentFolder The path of the parent folder. Must end with a
-     *        separator.
-     * @param folders Folders to be added.
-     * @param monitor An existing monitor.
-     * @throws CoreException if the method fails to create the directories in
-     *         the project.
-     */
-    private void addDefaultDirectories(IProject project, String parentFolder,
-            String[] folders, IProgressMonitor monitor) throws CoreException {
-        for (String name : folders) {
-            if (name.length() > 0) {
-                IFolder folder = project.getFolder(parentFolder + name);
-                if (!folder.exists()) {
-                    folder.create(true /* force */, true /* local */,
-                            new SubProgressMonitor(monitor, 10));
-                }
-            }
-        }
-    }
-
-    /**
-     * Adds the manifest to the project.
-     *
-     * @param project The Java Project to update.
-     * @param parameters Template Parameters.
-     * @param dictionary String List to be added to a string definition
-     *        file. This map will be filled by this method.
-     * @param monitor An existing monitor.
-     * @throws CoreException if the method fails to update the project.
-     * @throws IOException if the method fails to create the files in the
-     *         project.
-     */
-    private void addManifest(IProject project, Map<String, Object> parameters,
-            Map<String, String> dictionary, IProgressMonitor monitor)
-            throws CoreException, IOException {
-
-        // get IFile to the manifest and check if it's not already there.
-        IFile file = project.getFile(AndroidConstants.FN_ANDROID_MANIFEST);
-        if (!file.exists()) {
-
-            // Read manifest template
-            String manifestTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_MANIFEST);
-
-            // Replace all keyword parameters
-            manifestTemplate = replaceParameters(manifestTemplate, parameters);
-
-            if (parameters.containsKey(PARAM_ACTIVITY)) {
-                // now get the activity template
-                String activityTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_ACTIVITIES);
-
-                // Replace all keyword parameters to make main activity.
-                String activities = replaceParameters(activityTemplate, parameters);
-
-                // set the intent.
-                String intent = AdtPlugin.readEmbeddedTextFile(TEMPLATE_INTENT_LAUNCHER);
-
-                // set the intent to the main activity
-                activities = activities.replaceAll(PH_INTENT_FILTERS, intent);
-
-                // set the activity(ies) in the manifest
-                manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, activities);
-            } else {
-                // remove the activity(ies) from the manifest
-                manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, "");  //$NON-NLS-1$
-            }
-
-            // Handle the case of the test projects
-            if (parameters.containsKey(PARAM_TEST_TARGET_PACKAGE)) {
-                // Set the uses-library needed by the test project
-                String usesLibrary = AdtPlugin.readEmbeddedTextFile(TEMPLATE_TEST_USES_LIBRARY);
-                manifestTemplate = manifestTemplate.replaceAll(PH_TEST_USES_LIBRARY, usesLibrary);
-
-                // Set the instrumentation element needed by the test project
-                String instru = AdtPlugin.readEmbeddedTextFile(TEMPLATE_TEST_INSTRUMENTATION);
-                manifestTemplate = manifestTemplate.replaceAll(PH_TEST_INSTRUMENTATION, instru);
-
-                // Replace PARAM_TEST_TARGET_PACKAGE itself now
-                manifestTemplate = replaceParameters(manifestTemplate, parameters);
-
-            } else {
-                // remove the unused entries
-                manifestTemplate = manifestTemplate.replaceAll(PH_TEST_USES_LIBRARY, "");     //$NON-NLS-1$
-                manifestTemplate = manifestTemplate.replaceAll(PH_TEST_INSTRUMENTATION, "");  //$NON-NLS-1$
-            }
-
-            String minSdkVersion = (String) parameters.get(PARAM_MIN_SDK_VERSION);
-            if (minSdkVersion != null && minSdkVersion.length() > 0) {
-                String usesSdkTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_USES_SDK);
-                String usesSdk = replaceParameters(usesSdkTemplate, parameters);
-                manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, usesSdk);
-            } else {
-                manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, "");
-            }
-
-            // Save in the project as UTF-8
-            InputStream stream = new ByteArrayInputStream(
-                    manifestTemplate.getBytes("UTF-8")); //$NON-NLS-1$
-            file.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
-        }
-    }
-
-    /**
-     * Adds the string resource file.
-     *
-     * @param project The Java Project to update.
-     * @param strings The list of strings to be added to the string file.
-     * @param monitor An existing monitor.
-     * @throws CoreException if the method fails to update the project.
-     * @throws IOException if the method fails to create the files in the
-     *         project.
-     */
-    private void addStringDictionaryFile(IProject project,
-            Map<String, String> strings, IProgressMonitor monitor)
-            throws CoreException, IOException {
-
-        // create the IFile object and check if the file doesn't already exist.
-        IFile file = project.getFile(RES_DIRECTORY + AndroidConstants.WS_SEP
-                                     + VALUES_DIRECTORY + AndroidConstants.WS_SEP + STRINGS_FILE);
-        if (!file.exists()) {
-            // get the Strings.xml template
-            String stringDefinitionTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_STRINGS);
-
-            // get the template for one string
-            String stringTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_STRING);
-
-            // get all the string names
-            Set<String> stringNames = strings.keySet();
-
-            // loop on it and create the string definitions
-            StringBuilder stringNodes = new StringBuilder();
-            for (String key : stringNames) {
-                // get the value from the key
-                String value = strings.get(key);
-
-                // place them in the template
-                String stringDef = stringTemplate.replace(PARAM_STRING_NAME, key);
-                stringDef = stringDef.replace(PARAM_STRING_CONTENT, value);
-
-                // append to the other string
-                if (stringNodes.length() > 0) {
-                    stringNodes.append("\n");
-                }
-                stringNodes.append(stringDef);
-            }
-
-            // put the string nodes in the Strings.xml template
-            stringDefinitionTemplate = stringDefinitionTemplate.replace(PH_STRINGS,
-                                                                        stringNodes.toString());
-
-            // write the file as UTF-8
-            InputStream stream = new ByteArrayInputStream(
-                    stringDefinitionTemplate.getBytes("UTF-8")); //$NON-NLS-1$
-            file.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
-        }
-    }
-
-
-    /**
-     * Adds default application icon to the project.
-     *
-     * @param project The Java Project to update.
-     * @param legacy whether we're running in legacy mode (no density support)
-     * @param monitor An existing monitor.
-     * @throws CoreException if the method fails to update the project.
-     */
-    private void addIcon(IProject project, boolean legacy, IProgressMonitor monitor)
-            throws CoreException {
-        if (legacy) { // density support
-            // do medium density icon only, in the default drawable folder.
-            IFile file = project.getFile(RES_DIRECTORY + AndroidConstants.WS_SEP
-                    + DRAWABLE_DIRECTORY + AndroidConstants.WS_SEP + PROJECT_ICON);
-            if (!file.exists()) {
-                addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_MDPI), monitor);
-            }
-        } else {
-            // do all 3 icons.
-            IFile file;
-
-            // high density
-            file = project.getFile(RES_DIRECTORY + AndroidConstants.WS_SEP
-                    + DRAWABLE_HDPI_DIRECTORY + AndroidConstants.WS_SEP + PROJECT_ICON);
-            if (!file.exists()) {
-                addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_HDPI), monitor);
-            }
-
-            // medium density
-            file = project.getFile(RES_DIRECTORY + AndroidConstants.WS_SEP
-                    + DRAWABLE_MDPI_DIRECTORY + AndroidConstants.WS_SEP + PROJECT_ICON);
-            if (!file.exists()) {
-                addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_MDPI), monitor);
-            }
-
-            // low density
-            file = project.getFile(RES_DIRECTORY + AndroidConstants.WS_SEP
-                    + DRAWABLE_LDPI_DIRECTORY + AndroidConstants.WS_SEP + PROJECT_ICON);
-            if (!file.exists()) {
-                addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_LDPI), monitor);
-            }
-        }
-    }
-
-    /**
-     * Creates a file from a data source.
-     * @param dest the file to write
-     * @param source the content of the file.
-     * @param monitor the progress monitor
-     * @throws CoreException
-     */
-    private void addFile(IFile dest, byte[] source, IProgressMonitor monitor) throws CoreException {
-        if (source != null) {
-            // Save in the project
-            InputStream stream = new ByteArrayInputStream(source);
-            dest.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
-        }
-    }
-
-    /**
-     * Creates the package folder and copies the sample code in the project.
-     *
-     * @param project The Java Project to update.
-     * @param parameters Template Parameters.
-     * @param dictionary String List to be added to a string definition
-     *        file. This map will be filled by this method.
-     * @param monitor An existing monitor.
-     * @throws CoreException if the method fails to update the project.
-     * @throws IOException if the method fails to create the files in the
-     *         project.
-     */
-    private void addSampleCode(IProject project, String sourceFolder,
-            Map<String, Object> parameters, Map<String, String> dictionary,
-            IProgressMonitor monitor) throws CoreException, IOException {
-        // create the java package directories.
-        IFolder pkgFolder = project.getFolder(sourceFolder);
-        String packageName = (String) parameters.get(PARAM_PACKAGE);
-
-        // The PARAM_ACTIVITY key will be absent if no activity should be created,
-        // in which case activityName will be null.
-        String activityName = (String) parameters.get(PARAM_ACTIVITY);
-        Map<String, Object> java_activity_parameters = parameters;
-        if (activityName != null) {
-            if (activityName.indexOf('.') >= 0) {
-                // There are package names in the activity name. Transform packageName to add
-                // those sub packages and remove them from activityName.
-                packageName += "." + activityName; //$NON-NLS-1$
-                int pos = packageName.lastIndexOf('.');
-                activityName = packageName.substring(pos + 1);
-                packageName = packageName.substring(0, pos);
-
-                // Also update the values used in the JAVA_FILE_TEMPLATE below
-                // (but not the ones from the manifest so don't change the caller's dictionary)
-                java_activity_parameters = new HashMap<String, Object>(parameters);
-                java_activity_parameters.put(PARAM_PACKAGE, packageName);
-                java_activity_parameters.put(PARAM_ACTIVITY, activityName);
-            }
-        }
-
-        String[] components = packageName.split(AndroidConstants.RE_DOT);
-        for (String component : components) {
-            pkgFolder = pkgFolder.getFolder(component);
-            if (!pkgFolder.exists()) {
-                pkgFolder.create(true /* force */, true /* local */,
-                        new SubProgressMonitor(monitor, 10));
-            }
-        }
-
-        if (activityName != null) {
-            // create the main activity Java file
-            String activityJava = activityName + AndroidConstants.DOT_JAVA;
-            IFile file = pkgFolder.getFile(activityJava);
-            if (!file.exists()) {
-                copyFile(JAVA_ACTIVITY_TEMPLATE, file, java_activity_parameters, monitor);
-            }
-        }
-
-        // create the layout file
-        IFolder layoutfolder = project.getFolder(RES_DIRECTORY).getFolder(LAYOUT_DIRECTORY);
-        IFile file = layoutfolder.getFile(MAIN_LAYOUT_XML);
-        if (!file.exists()) {
-            copyFile(LAYOUT_TEMPLATE, file, parameters, monitor);
-            if (activityName != null) {
-                dictionary.put(STRING_HELLO_WORLD, "Hello World, " + activityName + "!");
-            } else {
-                dictionary.put(STRING_HELLO_WORLD, "Hello World!");
-            }
-        }
-    }
-
-    /**
-     * Adds the given folder to the project's class path.
-     *
-     * @param javaProject The Java Project to update.
-     * @param sourceFolder Template Parameters.
-     * @param monitor An existing monitor.
-     * @throws JavaModelException if the classpath could not be set.
-     */
-    private void setupSourceFolder(IJavaProject javaProject, String sourceFolder,
-            IProgressMonitor monitor) throws JavaModelException {
-        IProject project = javaProject.getProject();
-
-        // Add "src" to class path
-        IFolder srcFolder = project.getFolder(sourceFolder);
-
-        IClasspathEntry[] entries = javaProject.getRawClasspath();
-        entries = removeSourceClasspath(entries, srcFolder);
-        entries = removeSourceClasspath(entries, srcFolder.getParent());
-
-        entries = ProjectHelper.addEntryToClasspath(entries,
-                JavaCore.newSourceEntry(srcFolder.getFullPath()));
-
-        javaProject.setRawClasspath(entries, new SubProgressMonitor(monitor, 10));
-    }
-
-
-    /**
-     * Removes the corresponding source folder from the class path entries if
-     * found.
-     *
-     * @param entries The class path entries to read. A copy will be returned.
-     * @param folder The parent source folder to remove.
-     * @return A new class path entries array.
-     */
-    private IClasspathEntry[] removeSourceClasspath(IClasspathEntry[] entries, IContainer folder) {
-        if (folder == null) {
-            return entries;
-        }
-        IClasspathEntry source = JavaCore.newSourceEntry(folder.getFullPath());
-        int n = entries.length;
-        for (int i = n - 1; i >= 0; i--) {
-            if (entries[i].equals(source)) {
-                IClasspathEntry[] newEntries = new IClasspathEntry[n - 1];
-                if (i > 0) System.arraycopy(entries, 0, newEntries, 0, i);
-                if (i < n - 1) System.arraycopy(entries, i + 1, newEntries, i, n - i - 1);
-                n--;
-                entries = newEntries;
-            }
-        }
-        return entries;
-    }
-
-
-    /**
-     * Copies the given file from our resource folder to the new project.
-     * Expects the file to the US-ASCII or UTF-8 encoded.
-     *
-     * @throws CoreException from IFile if failing to create the new file.
-     * @throws MalformedURLException from URL if failing to interpret the URL.
-     * @throws FileNotFoundException from RandomAccessFile.
-     * @throws IOException from RandomAccessFile.length() if can't determine the
-     *         length.
-     */
-    private void copyFile(String resourceFilename, IFile destFile,
-            Map<String, Object> parameters, IProgressMonitor monitor)
-            throws CoreException, IOException {
-
-        // Read existing file.
-        String template = AdtPlugin.readEmbeddedTextFile(
-                TEMPLATES_DIRECTORY + resourceFilename);
-
-        // Replace all keyword parameters
-        template = replaceParameters(template, parameters);
-
-        // Save in the project as UTF-8
-        InputStream stream = new ByteArrayInputStream(template.getBytes("UTF-8")); //$NON-NLS-1$
-        destFile.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
-    }
-
-    /**
-     * Returns an image descriptor for the wizard logo.
-     */
-    private void setImageDescriptor() {
-        ImageDescriptor desc = AdtPlugin.getImageDescriptor(PROJECT_LOGO_LARGE);
-        setDefaultPageImageDescriptor(desc);
-    }
-
-    /**
-     * Replaces placeholders found in a string with values.
-     *
-     * @param str the string to search for placeholders.
-     * @param parameters a map of <placeholder, Value> to search for in the string
-     * @return A new String object with the placeholder replaced by the values.
-     */
-    private String replaceParameters(String str, Map<String, Object> parameters) {
-        for (Entry<String, Object> entry : parameters.entrySet()) {
-            if (entry.getValue() instanceof String) {
-                str = str.replaceAll(entry.getKey(), (String) entry.getValue());
-            }
-        }
-
-        return str;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java
deleted file mode 100755
index 94fd99d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java
+++ /dev/null
@@ -1,1334 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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.
- */
-
-/*
- * References:
- * org.eclipse.jdt.internal.ui.wizards.JavaProjectWizard
- * org.eclipse.jdt.internal.ui.wizards.JavaProjectWizardFirstPage
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.newproject;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage.IMainInfo;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage.MainInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdkuilib.internal.widgets.SdkTargetSelector;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaConventions;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.osgi.util.TextProcessor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.DirectoryDialog;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.regex.Pattern;
-
-/**
- * NewAndroidProjectCreationPage is a project creation page that provides the
- * following fields:
- * <ul>
- * <li> Project name
- * <li> SDK Target
- * <li> Application name
- * <li> Package name
- * <li> Activity name
- * </ul>
- * Note: this class is public so that it can be accessed from unit tests.
- * It is however an internal class. Its API may change without notice.
- * It should semantically be considered as a private final class.
- * Do not derive from this class.
- */
-public class NewTestProjectCreationPage extends WizardPage {
-
-    // constants
-    static final String TEST_PAGE_NAME = "newAndroidTestProjectPage"; //$NON-NLS-1$
-
-    /** Initial value for all name fields (project, activity, application, package). Used
-     * whenever a value is requested before controls are created. */
-    private static final String INITIAL_NAME = "";  //$NON-NLS-1$
-    /** Initial value for the Use Default Location check box. */
-    private static final boolean INITIAL_USE_DEFAULT_LOCATION = true;
-    /** Initial value for the Create Test Project check box. */
-    private static final boolean INITIAL_CREATE_TEST_PROJECT = false;
-
-
-    /** Pattern for characters accepted in a project name. Since this will be used as a
-     * directory name, we're being a bit conservative on purpose. It cannot start with a space. */
-    private static final Pattern sProjectNamePattern = Pattern.compile("^[\\w][\\w. -]*$");  //$NON-NLS-1$
-    /** Last user-browsed location, static so that it be remembered for the whole session */
-    private static String sCustomLocationOsPath = "";  //$NON-NLS-1$
-
-    private final int MSG_NONE = 0;
-    private final int MSG_WARNING = 1;
-    private final int MSG_ERROR = 2;
-
-    /** Structure with the externally visible information from this Test Project page. */
-    private final TestInfo mInfo = new TestInfo();
-    /** Structure with the externally visible information from the Main Project page.
-     *  This is null if there's no such page, meaning the test project page is standalone. */
-    private IMainInfo mMainInfo;
-
-    // widgets
-    private Text mProjectNameField;
-    private Text mPackageNameField;
-    private Text mApplicationNameField;
-    private Button mUseDefaultLocation;
-    private Label mLocationLabel;
-    private Text mLocationPathField;
-    private Button mBrowseButton;
-    private Text mMinSdkVersionField;
-    private SdkTargetSelector mSdkTargetSelector;
-    private ITargetChangeListener mSdkTargetChangeListener;
-    private Button mCreateTestProjectField;
-    private Text mTestedProjectNameField;
-    private Button mProjectBrowseButton;
-    private ProjectChooserHelper mProjectChooserHelper;
-    private Button mTestSelfProjectRadio;
-    private Button mTestExistingProjectRadio;
-
-    /** A list of composites that are disabled when the "Create Test Project" toggle is off. */
-    private ArrayList<Composite> mToggleComposites = new ArrayList<Composite>();
-
-    private boolean mInternalProjectNameUpdate;
-    private boolean mInternalLocationPathUpdate;
-    private boolean mInternalPackageNameUpdate;
-    private boolean mInternalApplicationNameUpdate;
-    private boolean mInternalMinSdkVersionUpdate;
-    private boolean mInternalSdkTargetUpdate;
-    private IProject mExistingTestedProject;
-    private boolean mProjectNameModifiedByUser;
-    private boolean mApplicationNameModifiedByUser;
-    private boolean mPackageNameModifiedByUser;
-    private boolean mMinSdkVersionModifiedByUser;
-    private boolean mSdkTargetModifiedByUser;
-
-    private Label mTestTargetPackageLabel;
-
-    private String mLastExistingPackageName;
-
-
-    /**
-     * Creates a new project creation wizard page.
-     */
-    public NewTestProjectCreationPage() {
-        super(TEST_PAGE_NAME);
-        setPageComplete(false);
-        setTitle("New Android Test Project");
-        setDescription("Creates a new Android Test Project resource.");
-    }
-
-    // --- Getters used by NewProjectWizard ---
-
-    /**
-     * Structure that collects all externally visible information from this page.
-     * This is used by the calling wizard to actually do the work or by other pages.
-     */
-    public class TestInfo {
-
-        /** Returns true if a new Test Project should be created. */
-        public boolean getCreateTestProject() {
-            return mCreateTestProjectField == null ? true : mCreateTestProjectField.getSelection();
-        }
-
-        /**
-         * Returns the current project location path as entered by the user, or its
-         * anticipated initial value. Note that if the default has been returned the
-         * path in a project description used to create a project should not be set.
-         *
-         * @return the project location path or its anticipated initial value.
-         */
-        public IPath getLocationPath() {
-            return new Path(getProjectLocation());
-        }
-
-        /** Returns the value of the project name field with leading and trailing spaces removed. */
-        public String getProjectName() {
-            return mProjectNameField == null ? INITIAL_NAME : mProjectNameField.getText().trim();
-        }
-
-        /** Returns the value of the package name field with spaces trimmed. */
-        public String getPackageName() {
-            return mPackageNameField == null ? INITIAL_NAME : mPackageNameField.getText().trim();
-        }
-
-        /** Returns the value of the test target package name field with spaces trimmed. */
-        public String getTargetPackageName() {
-            return mTestTargetPackageLabel == null ? INITIAL_NAME
-                                                   : mTestTargetPackageLabel.getText().trim();
-        }
-
-        /** Returns the value of the min sdk version field with spaces trimmed. */
-        public String getMinSdkVersion() {
-            return mMinSdkVersionField == null ? "" : mMinSdkVersionField.getText().trim();  //$NON-NLS-1$
-        }
-
-        /** Returns the value of the application name field with spaces trimmed. */
-        public String getApplicationName() {
-            // Return the name of the activity as default application name.
-            return mApplicationNameField == null ? "" : mApplicationNameField.getText().trim();  //$NON-NLS-1$
-        }
-
-        /** Returns the value of the Use Default Location field. */
-        public boolean useDefaultLocation() {
-            return mUseDefaultLocation == null ? INITIAL_USE_DEFAULT_LOCATION
-                                               : mUseDefaultLocation.getSelection();
-        }
-
-        /** Returns the the default "src" constant. */
-        public String getSourceFolder() {
-            return SdkConstants.FD_SOURCES;
-        }
-
-        /** Returns the current sdk target or null if none has been selected yet. */
-        public IAndroidTarget getSdkTarget() {
-            return mSdkTargetSelector == null ? null : mSdkTargetSelector.getSelected();
-        }
-
-        public boolean isTestingSelf() {
-            return mMainInfo == null &&
-                (mTestSelfProjectRadio == null ? false : mTestSelfProjectRadio.getSelection());
-        }
-
-        public boolean isTestingMain() {
-            return mMainInfo != null;
-        }
-
-        public boolean isTestingExisting() {
-            return mMainInfo == null &&
-                (mTestExistingProjectRadio == null ? false
-                                                   : mTestExistingProjectRadio.getSelection());
-        }
-
-        public IProject getExistingTestedProject() {
-            return mExistingTestedProject;
-        }
-    }
-
-    /**
-     * Returns a {@link TestInfo} structure that collects all externally visible information
-     * from this page. This is used by the calling wizard to actually do the work or by other pages.
-     */
-    public TestInfo getTestInfo() {
-        return mInfo;
-    }
-
-    /**
-     * Grabs the {@link MainInfo} structure with visible parameters from the main project page.
-     * This may be null.
-     */
-    public void setMainInfo(IMainInfo mainInfo) {
-        mMainInfo = mainInfo;
-    }
-
-    // --- UI creation ---
-
-    /**
-     * Creates the top level control for this dialog page under the given parent
-     * composite.
-     *
-     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    public void createControl(Composite parent) {
-        Composite composite = new Composite(parent, SWT.NULL);
-        composite.setFont(parent.getFont());
-
-        initializeDialogUnits(parent);
-
-        composite.setLayout(new GridLayout());
-        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        createToggleTestProject(composite);
-        createTestProjectGroup(composite);
-        createLocationGroup(composite);
-        createTestTargetGroup(composite);
-        createTargetGroup(composite);
-        createPropertiesGroup(composite);
-
-        // Update state the first time
-        enableLocationWidgets();
-
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setControl(composite);
-
-        // Validate. This will complain about the first empty field.
-        validatePageComplete();
-    }
-
-    /**
-     * Overrides @DialogPage.setVisible(boolean) to put the focus in the project name when
-     * the dialog is made visible and to also update the enabled/disabled state of some
-     * controls (doing so in createControl doesn't always change their state somehow.)
-     */
-    @Override
-    public void setVisible(boolean visible) {
-        super.setVisible(visible);
-        if (visible) {
-            mProjectNameField.setFocus();
-            validatePageComplete();
-            onCreateTestProjectToggle();
-            onExistingProjectChanged();
-        }
-    }
-
-    @Override
-    public void dispose() {
-
-        if (mSdkTargetChangeListener != null) {
-            AdtPlugin.getDefault().removeTargetListener(mSdkTargetChangeListener);
-            mSdkTargetChangeListener = null;
-        }
-
-        super.dispose();
-    }
-
-    /**
-     * Creates the "create test project" checkbox but only if there's a main page in the wizard.
-     *
-     * @param parent the parent composite
-     */
-    private final void createToggleTestProject(Composite parent) {
-
-        if (mMainInfo != null) {
-            mCreateTestProjectField = new Button(parent, SWT.CHECK);
-            mCreateTestProjectField.setText("Create a Test Project");
-            mCreateTestProjectField.setToolTipText("Select this if you also want to create a Test Project.");
-            mCreateTestProjectField.setSelection(INITIAL_CREATE_TEST_PROJECT);
-            mCreateTestProjectField.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    onCreateTestProjectToggle();
-                }
-            });
-        }
-    }
-
-    /**
-     * Creates the group for the project name:
-     * [label: "Project Name"] [text field]
-     *
-     * @param parent the parent composite
-     */
-    private final void createTestProjectGroup(Composite parent) {
-        Composite group = new Composite(parent, SWT.NONE);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mToggleComposites.add(group);
-
-        // --- test project name ---
-
-        // new project label
-        String tooltip = "Name of the Eclipse test project to create. It cannot be empty.";
-        Label label = new Label(group, SWT.NONE);
-        label.setText("Test Project Name:");
-        label.setFont(parent.getFont());
-        label.setToolTipText(tooltip);
-
-        // new project name entry field
-        mProjectNameField = new Text(group, SWT.BORDER);
-        GridData data = new GridData(GridData.FILL_HORIZONTAL);
-        mProjectNameField.setToolTipText(tooltip);
-        mProjectNameField.setLayoutData(data);
-        mProjectNameField.setFont(parent.getFont());
-        mProjectNameField.addListener(SWT.Modify, new Listener() {
-            public void handleEvent(Event event) {
-                if (!mInternalProjectNameUpdate) {
-                    mProjectNameModifiedByUser = true;
-                }
-                updateLocationPathField(null);
-            }
-        });
-
-    }
-
-    private final void createLocationGroup(Composite parent) {
-
-        // --- project location ---
-
-        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
-        group.setLayout(new GridLayout(3, /* num columns */
-                false /* columns of not equal size */));
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        group.setFont(parent.getFont());
-        group.setText("Content");
-
-        mToggleComposites.add(group);
-
-        mUseDefaultLocation = new Button(group, SWT.CHECK);
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 3;
-        mUseDefaultLocation.setLayoutData(gd);
-        mUseDefaultLocation.setText("Use default location");
-        mUseDefaultLocation.setSelection(INITIAL_USE_DEFAULT_LOCATION);
-
-        mUseDefaultLocation.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                enableLocationWidgets();
-                validatePageComplete();
-            }
-        });
-
-
-        mLocationLabel = new Label(group, SWT.NONE);
-        mLocationLabel.setText("Location:");
-
-        mLocationPathField = new Text(group, SWT.BORDER);
-        GridData data = new GridData(GridData.FILL, /* horizontal alignment */
-                GridData.BEGINNING, /* vertical alignment */
-                true,  /* grabExcessHorizontalSpace */
-                false, /* grabExcessVerticalSpace */
-                1,     /* horizontalSpan */
-                1);    /* verticalSpan */
-        mLocationPathField.setLayoutData(data);
-        mLocationPathField.setFont(parent.getFont());
-        mLocationPathField.addListener(SWT.Modify, new Listener() {
-           public void handleEvent(Event event) {
-               onLocationPathFieldModified();
-            }
-        });
-
-        mBrowseButton = new Button(group, SWT.PUSH);
-        mBrowseButton.setText("Browse...");
-        setButtonLayoutData(mBrowseButton);
-        mBrowseButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onOpenDirectoryBrowser();
-            }
-        });
-    }
-
-    /**
-     * Creates the group for Test Target options.
-     *
-     * There are two different modes here:
-     * <ul>
-     * <li>When mMainInfo exists, this is part of a new Android Project. In which case
-     * the new test is tied to the soon-to-be main project and there is actually no choice.
-     * <li>When mMainInfo does not exist, this is a standalone new test project. In this case
-     * we offer 2 options for the test target: self test or against an existing Android project.
-     * </ul>
-     *
-     * @param parent the parent composite
-     */
-    private final void createTestTargetGroup(Composite parent) {
-
-        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 3;
-        group.setLayout(layout);
-        group.setLayoutData(new GridData(GridData.FILL_BOTH));
-        group.setFont(parent.getFont());
-        group.setText("Test Target");
-
-        mToggleComposites.add(group);
-
-        if (mMainInfo == null) {
-            // Standalone mode: choose between self-test and existing-project test
-
-            Label label = new Label(group, SWT.NONE);
-            label.setText("Select the project to test:");
-            GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-            gd.horizontalSpan = 3;
-            label.setLayoutData(gd);
-
-            mTestSelfProjectRadio = new Button(group, SWT.RADIO);
-            mTestSelfProjectRadio.setText("This project");
-            mTestSelfProjectRadio.setSelection(false);
-            gd = new GridData(GridData.FILL_HORIZONTAL);
-            gd.horizontalSpan = 3;
-            mTestSelfProjectRadio.setLayoutData(gd);
-
-            mTestExistingProjectRadio = new Button(group, SWT.RADIO);
-            mTestExistingProjectRadio.setText("An existing Android project");
-            mTestExistingProjectRadio.setSelection(mMainInfo == null);
-            mTestExistingProjectRadio.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    onExistingProjectChanged();
-                }
-            });
-
-            String tooltip = "The existing Android Project that is being tested.";
-
-            mTestedProjectNameField = new Text(group, SWT.BORDER);
-            mTestedProjectNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mTestedProjectNameField.setToolTipText(tooltip);
-            mTestedProjectNameField.addModifyListener(new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onProjectFieldUpdated();
-                }
-            });
-
-            mProjectBrowseButton = new Button(group, SWT.NONE);
-            mProjectBrowseButton.setText("Browse...");
-            mProjectBrowseButton.setToolTipText("Allows you to select the Android project to test.");
-            mProjectBrowseButton.addSelectionListener(new SelectionAdapter() {
-               @Override
-                public void widgetSelected(SelectionEvent e) {
-                   onProjectBrowse();
-                }
-            });
-
-            mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
-        } else {
-            // Part of NPW mode: no selection.
-
-        }
-
-        // package label line
-
-        Label label = new Label(group, SWT.NONE);
-        label.setText("Test Target Package:");
-        mTestTargetPackageLabel = new Label(group, SWT.NONE);
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-        gd.horizontalSpan = 2;
-        mTestTargetPackageLabel.setLayoutData(gd);
-    }
-
-    /**
-     * Creates the target group.
-     * It only contains an SdkTargetSelector.
-     */
-    private void createTargetGroup(Composite parent) {
-        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
-        // Layout has 1 column
-        group.setLayout(new GridLayout());
-        group.setLayoutData(new GridData(GridData.FILL_BOTH));
-        group.setFont(parent.getFont());
-        group.setText("Build Target");
-
-        mToggleComposites.add(group);
-
-        // The selector is created without targets. They are added below in the change listener.
-        mSdkTargetSelector = new SdkTargetSelector(group, null);
-
-        mSdkTargetChangeListener = new ITargetChangeListener() {
-            public void onProjectTargetChange(IProject changedProject) {
-                // Ignore
-            }
-
-            public void onTargetsLoaded() {
-                // Update the sdk target selector with the new targets
-
-                // get the targets from the sdk
-                IAndroidTarget[] targets = null;
-                if (Sdk.getCurrent() != null) {
-                    targets = Sdk.getCurrent().getTargets();
-                }
-                mSdkTargetSelector.setTargets(targets);
-
-                // If there's only one target, select it
-                if (targets != null && targets.length == 1) {
-                    mSdkTargetSelector.setSelection(targets[0]);
-                }
-            }
-        };
-
-        AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);
-
-        // Invoke it once to initialize the targets
-        mSdkTargetChangeListener.onTargetsLoaded();
-
-        mSdkTargetSelector.setSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onSdkTargetModified();
-                updateLocationPathField(null);
-                validatePageComplete();
-            }
-        });
-    }
-
-    /**
-     * Creates the group for the project properties:
-     * - Package name [text field]
-     * - Activity name [text field]
-     * - Application name [text field]
-     *
-     * @param parent the parent composite
-     */
-    private final void createPropertiesGroup(Composite parent) {
-        // package specification group
-        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 2;
-        group.setLayout(layout);
-        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        group.setFont(parent.getFont());
-        group.setText("Properties");
-
-        mToggleComposites.add(group);
-
-        // new application label
-        Label label = new Label(group, SWT.NONE);
-        label.setText("Application name:");
-        label.setFont(parent.getFont());
-        label.setToolTipText("Name of the Application. This is a free string. It can be empty.");
-
-        // new application name entry field
-        mApplicationNameField = new Text(group, SWT.BORDER);
-        GridData data = new GridData(GridData.FILL_HORIZONTAL);
-        mApplicationNameField.setToolTipText("Name of the Application. This is a free string. It can be empty.");
-        mApplicationNameField.setLayoutData(data);
-        mApplicationNameField.setFont(parent.getFont());
-        mApplicationNameField.addListener(SWT.Modify, new Listener() {
-           public void handleEvent(Event event) {
-               if (!mInternalApplicationNameUpdate) {
-                   mApplicationNameModifiedByUser = true;
-               }
-           }
-        });
-
-        // new package label
-        label = new Label(group, SWT.NONE);
-        label.setText("Package name:");
-        label.setFont(parent.getFont());
-        label.setToolTipText("Namespace of the Package to create. This must be a Java namespace with at least two components.");
-
-        // new package name entry field
-        mPackageNameField = new Text(group, SWT.BORDER);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        mPackageNameField.setToolTipText("Namespace of the Package to create. This must be a Java namespace with at least two components.");
-        mPackageNameField.setLayoutData(data);
-        mPackageNameField.setFont(parent.getFont());
-        mPackageNameField.addListener(SWT.Modify, new Listener() {
-            public void handleEvent(Event event) {
-                if (!mInternalPackageNameUpdate) {
-                    mPackageNameModifiedByUser = true;
-                }
-                onPackageNameFieldModified();
-            }
-        });
-
-        // min sdk version label
-        label = new Label(group, SWT.NONE);
-        label.setText("Min SDK Version:");
-        label.setFont(parent.getFont());
-        label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");
-
-        // min sdk version entry field
-        mMinSdkVersionField = new Text(group, SWT.BORDER);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");
-        mMinSdkVersionField.setLayoutData(data);
-        mMinSdkVersionField.setFont(parent.getFont());
-        mMinSdkVersionField.addListener(SWT.Modify, new Listener() {
-            public void handleEvent(Event event) {
-                onMinSdkVersionFieldModified();
-                validatePageComplete();
-            }
-        });
-    }
-
-
-    //--- Internal getters & setters ------------------
-
-    /** Returns the location path field value with spaces trimmed. */
-    private String getLocationPathFieldValue() {
-        return mLocationPathField == null ? "" : mLocationPathField.getText().trim();  //$NON-NLS-1$
-    }
-
-    /** Returns the current project location, depending on the Use Default Location check box. */
-    private String getProjectLocation() {
-        if (mInfo.useDefaultLocation()) {
-            return Platform.getLocation().toString();
-        } else {
-            return getLocationPathFieldValue();
-        }
-    }
-
-    /**
-     * Creates a project resource handle for the current project name field
-     * value.
-     * <p>
-     * This method does not create the project resource; this is the
-     * responsibility of <code>IProject::create</code> invoked by the new
-     * project resource wizard.
-     * </p>
-     *
-     * @return the new project resource handle
-     */
-    private IProject getProjectHandle() {
-        return ResourcesPlugin.getWorkspace().getRoot().getProject(mInfo.getProjectName());
-    }
-
-    // --- UI Callbacks ----
-
-    /**
-     * Callback invoked when the user toggles the "Test target: Existing Android Project"
-     * checkbox. It enables or disable the UI to select an existing project.
-     */
-    private void onExistingProjectChanged() {
-        if (mInfo.isTestingExisting()) {
-            boolean enabled = mTestExistingProjectRadio.getSelection();
-            mTestedProjectNameField.setEnabled(enabled);
-            mProjectBrowseButton.setEnabled(enabled);
-            setExistingProject(mInfo.getExistingTestedProject());
-            validatePageComplete();
-        }
-    }
-
-    /**
-     * Tries to load the defaults from the main page if possible.
-     */
-    private void useMainProjectInformation() {
-        if (mInfo.isTestingMain() && mMainInfo != null) {
-
-            String projName = String.format("%1$sTest", mMainInfo.getProjectName());
-            String appName = String.format("%1$sTest", mMainInfo.getApplicationName());
-
-            String packageName = mMainInfo.getPackageName();
-            if (packageName == null) {
-                packageName = "";  //$NON-NLS-1$
-            }
-
-            updateTestTargetPackageField(packageName);
-
-            if (!mProjectNameModifiedByUser) {
-                mInternalProjectNameUpdate = true;
-                mProjectNameField.setText(projName);  //$NON-NLS-1$
-                mInternalProjectNameUpdate = false;
-            }
-
-            if (!mApplicationNameModifiedByUser) {
-                mInternalApplicationNameUpdate = true;
-                mApplicationNameField.setText(appName);
-                mInternalApplicationNameUpdate = false;
-            }
-
-            if (!mPackageNameModifiedByUser) {
-                mInternalPackageNameUpdate = true;
-                packageName += ".test";  //$NON-NLS-1$
-                mPackageNameField.setText(packageName);
-                mInternalPackageNameUpdate = false;
-            }
-
-            if (!mSdkTargetModifiedByUser) {
-                mInternalSdkTargetUpdate = true;
-                mSdkTargetSelector.setSelection(mMainInfo.getSdkTarget());
-                mInternalSdkTargetUpdate = false;
-            }
-
-            if (!mMinSdkVersionModifiedByUser) {
-                mInternalMinSdkVersionUpdate = true;
-                mMinSdkVersionField.setText(mMainInfo.getMinSdkVersion());
-                mInternalMinSdkVersionUpdate = false;
-            }
-        }
-    }
-
-    /**
-     * Callback invoked when the user edits the project text field.
-     */
-    private void onProjectFieldUpdated() {
-        String project = mTestedProjectNameField.getText();
-
-        // Is this a valid project?
-        IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null /*javaModel*/);
-        for (IJavaProject p : projects) {
-            if (p.getProject().getName().equals(project)) {
-                setExistingProject(p.getProject());
-                return;
-            }
-        }
-    }
-
-    /**
-     * Callback called when the user uses the "Browse Projects" button.
-     */
-    private void onProjectBrowse() {
-        IJavaProject p = mProjectChooserHelper.chooseJavaProject(mTestedProjectNameField.getText());
-        if (p != null) {
-            setExistingProject(p.getProject());
-            mTestedProjectNameField.setText(mExistingTestedProject.getName());
-        }
-    }
-
-    private void setExistingProject(IProject project) {
-        mExistingTestedProject = project;
-
-        // Try to update the application, package, sdk target and minSdkVersion accordingly
-        if (project != null &&
-                (!mApplicationNameModifiedByUser ||
-                 !mPackageNameModifiedByUser     ||
-                 !mSdkTargetModifiedByUser       ||
-                 !mMinSdkVersionModifiedByUser)) {
-
-            IFile file = AndroidManifestParser.getManifest(project);
-            AndroidManifestParser manifestData = null;
-            if (file != null) {
-                try {
-                    manifestData = AndroidManifestParser.parseForData(file);
-                } catch (CoreException e) {
-                    // pass
-                }
-            }
-
-            if (manifestData != null) {
-                String appName = String.format("%1$sTest", project.getName());
-                String packageName = manifestData.getPackage();
-                String minSdkVersion = manifestData.getApiLevelRequirement();
-                IAndroidTarget sdkTarget = null;
-                if (Sdk.getCurrent() != null) {
-                    sdkTarget = Sdk.getCurrent().getTarget(project);
-                }
-
-                if (packageName == null) {
-                    packageName = "";  //$NON-NLS-1$
-                }
-                mLastExistingPackageName = packageName;
-
-                if (!mProjectNameModifiedByUser) {
-                    mInternalProjectNameUpdate = true;
-                    mProjectNameField.setText(appName);
-                    mInternalProjectNameUpdate = false;
-                }
-
-                if (!mApplicationNameModifiedByUser) {
-                    mInternalApplicationNameUpdate = true;
-                    mApplicationNameField.setText(appName);
-                    mInternalApplicationNameUpdate = false;
-                }
-
-                if (!mPackageNameModifiedByUser) {
-                    mInternalPackageNameUpdate = true;
-                    packageName += ".test";  //$NON-NLS-1$
-                    mPackageNameField.setText(packageName);  //$NON-NLS-1$
-                    mInternalPackageNameUpdate = false;
-                }
-
-                if (!mSdkTargetModifiedByUser && sdkTarget != null) {
-                    mInternalSdkTargetUpdate = true;
-                    mSdkTargetSelector.setSelection(sdkTarget);
-                    mInternalSdkTargetUpdate = false;
-                }
-
-                if (!mMinSdkVersionModifiedByUser) {
-                    mInternalMinSdkVersionUpdate = true;
-                    if (minSdkVersion != null) {
-                        mMinSdkVersionField.setText(minSdkVersion);
-                    }
-                    if (sdkTarget == null) {
-                        updateSdkSelectorToMatchMinSdkVersion();
-                    }
-                    mInternalMinSdkVersionUpdate = false;
-                }
-            }
-        }
-
-        updateTestTargetPackageField(mLastExistingPackageName);
-        validatePageComplete();
-    }
-
-    /**
-     * Display a directory browser and update the location path field with the selected path
-     */
-    private void onOpenDirectoryBrowser() {
-
-        String existing_dir = getLocationPathFieldValue();
-
-        // Disable the path if it doesn't exist
-        if (existing_dir.length() == 0) {
-            existing_dir = null;
-        } else {
-            File f = new File(existing_dir);
-            if (!f.exists()) {
-                existing_dir = null;
-            }
-        }
-
-        DirectoryDialog dd = new DirectoryDialog(mLocationPathField.getShell());
-        dd.setMessage("Browse for folder");
-        dd.setFilterPath(existing_dir);
-        String abs_dir = dd.open();
-
-        if (abs_dir != null) {
-            updateLocationPathField(abs_dir);
-            validatePageComplete();
-        }
-    }
-
-    /**
-     * Callback when the "create test project" checkbox is changed.
-     * It enables or disables all UI groups accordingly.
-     */
-    private void onCreateTestProjectToggle() {
-        boolean enabled = mInfo.getCreateTestProject();
-        for (Composite c : mToggleComposites) {
-            enableControl(c, enabled);
-        }
-        mSdkTargetSelector.setEnabled(enabled);
-
-        if (enabled) {
-            useMainProjectInformation();
-        }
-        validatePageComplete();
-    }
-
-    /** Enables or disables controls; recursive for composite controls. */
-    private void enableControl(Control c, boolean enabled) {
-        c.setEnabled(enabled);
-        if (c instanceof Composite)
-        for (Control c2 : ((Composite) c).getChildren()) {
-            enableControl(c2, enabled);
-        }
-    }
-
-    /**
-     * Enables or disable the location widgets depending on the user selection:
-     * the location path is enabled when using the "existing source" mode (i.e. not new project)
-     * or in new project mode with the "use default location" turned off.
-     */
-    private void enableLocationWidgets() {
-        boolean use_default = mInfo.useDefaultLocation();
-        boolean location_enabled = !use_default;
-
-        mLocationLabel.setEnabled(location_enabled);
-        mLocationPathField.setEnabled(location_enabled);
-        mBrowseButton.setEnabled(location_enabled);
-
-        updateLocationPathField(null);
-    }
-
-    /**
-     * Updates the location directory path field.
-     * <br/>
-     * When custom user selection is enabled, use the abs_dir argument if not null and also
-     * save it internally. If abs_dir is null, restore the last saved abs_dir. This allows the
-     * user selection to be remembered when the user switches from default to custom.
-     * <br/>
-     * When custom user selection is disabled, use the workspace default location with the
-     * current project name. This does not change the internally cached abs_dir.
-     *
-     * @param abs_dir A new absolute directory path or null to use the default.
-     */
-    private void updateLocationPathField(String abs_dir) {
-        boolean use_default = mInfo.useDefaultLocation();
-        boolean custom_location = !use_default;
-
-        if (!mInternalLocationPathUpdate) {
-            mInternalLocationPathUpdate = true;
-            if (custom_location) {
-                if (abs_dir != null) {
-                    // We get here if the user selected a directory with the "Browse" button.
-                    sCustomLocationOsPath = TextProcessor.process(abs_dir);
-                }
-                if (!mLocationPathField.getText().equals(sCustomLocationOsPath)) {
-                    mLocationPathField.setText(sCustomLocationOsPath);
-                }
-            } else {
-                String value = Platform.getLocation().append(mInfo.getProjectName()).toString();
-                value = TextProcessor.process(value);
-                if (!mLocationPathField.getText().equals(value)) {
-                    mLocationPathField.setText(value);
-                }
-            }
-            validatePageComplete();
-            mInternalLocationPathUpdate = false;
-        }
-    }
-
-    /**
-     * The location path field is either modified internally (from updateLocationPathField)
-     * or manually by the user when the custom_location mode is not set.
-     *
-     * Ignore the internal modification. When modified by the user, memorize the choice and
-     * validate the page.
-     */
-    private void onLocationPathFieldModified() {
-        if (!mInternalLocationPathUpdate) {
-            // When the updates doesn't come from updateLocationPathField, it must be the user
-            // editing the field manually, in which case we want to save the value internally
-            String newPath = getLocationPathFieldValue();
-            sCustomLocationOsPath = newPath;
-            validatePageComplete();
-        }
-    }
-
-    /**
-     * The package name field is either modified internally (from extractNamesFromAndroidManifest)
-     * or manually by the user when the custom_location mode is not set.
-     *
-     * Ignore the internal modification. When modified by the user, memorize the choice and
-     * validate the page.
-     */
-    private void onPackageNameFieldModified() {
-        updateTestTargetPackageField(null);
-        validatePageComplete();
-    }
-
-    /**
-     * Changes the {@link #mTestTargetPackageLabel} field.
-     *
-     * When using the "self-test" option, the packageName argument is ignored and the
-     * current value from the project package is used.
-     *
-     * Otherwise the packageName is used if it is not null.
-     */
-    private void updateTestTargetPackageField(String packageName) {
-        if (mInfo.isTestingSelf()) {
-            mTestTargetPackageLabel.setText(mInfo.getPackageName());
-
-        } else if (packageName != null) {
-            mTestTargetPackageLabel.setText(packageName);
-        }
-    }
-
-    /**
-     * Called when the min sdk version field has been modified.
-     *
-     * Ignore the internal modifications. When modified by the user, try to match
-     * a target with the same API level.
-     */
-    private void onMinSdkVersionFieldModified() {
-        if (mInternalMinSdkVersionUpdate || mInternalSdkTargetUpdate) {
-            return;
-        }
-
-        updateSdkSelectorToMatchMinSdkVersion();
-
-        mMinSdkVersionModifiedByUser = true;
-    }
-
-    /**
-     * Try to find an SDK Target that matches the current MinSdkVersion.
-     *
-     * There can be multiple targets with the same sdk api version, so don't change
-     * it if it's already at the right version. Otherwise pick the first target
-     * that matches.
-     */
-    private void updateSdkSelectorToMatchMinSdkVersion() {
-        String minSdkVersion = mInfo.getMinSdkVersion();
-
-        IAndroidTarget curr_target = mInfo.getSdkTarget();
-        if (curr_target != null && curr_target.getVersion().equals(minSdkVersion)) {
-            return;
-        }
-
-        for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-            if (target.getVersion().equals(minSdkVersion)) {
-                mSdkTargetSelector.setSelection(target);
-                return;
-            }
-        }
-    }
-
-    /**
-     * Called when an SDK target is modified.
-     *
-     * Also changes the minSdkVersion field to reflect the sdk api level that has
-     * just been selected.
-     */
-    private void onSdkTargetModified() {
-        if (mInternalMinSdkVersionUpdate || mInternalSdkTargetUpdate) {
-            return;
-        }
-
-        IAndroidTarget target = mInfo.getSdkTarget();
-
-        if (target != null) {
-            mInternalMinSdkVersionUpdate = true;
-            mMinSdkVersionField.setText(target.getVersion().getApiString());
-            mInternalMinSdkVersionUpdate = false;
-        }
-
-        mSdkTargetModifiedByUser = true;
-    }
-
-    /**
-     * Returns whether this page's controls currently all contain valid values.
-     *
-     * @return <code>true</code> if all controls are valid, and
-     *         <code>false</code> if at least one is invalid
-     */
-    private boolean validatePage() {
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-
-        int status = MSG_NONE;
-
-        // there is nothing to validate if we're not going to create a test project
-        if (mInfo.getCreateTestProject()) {
-            status = validateProjectField(workspace);
-            if ((status & MSG_ERROR) == 0) {
-                status |= validateLocationPath(workspace);
-            }
-            if ((status & MSG_ERROR) == 0) {
-                status |= validateTestTarget();
-            }
-            if ((status & MSG_ERROR) == 0) {
-                status |= validateSdkTarget();
-            }
-            if ((status & MSG_ERROR) == 0) {
-                status |= validatePackageField();
-            }
-            if ((status & MSG_ERROR) == 0) {
-                status |= validateMinSdkVersionField();
-            }
-        }
-        if (status == MSG_NONE)  {
-            setStatus(null, MSG_NONE);
-        }
-
-        // Return false if there's an error so that the finish button be disabled.
-        return (status & MSG_ERROR) == 0;
-    }
-
-    /**
-     * Validates the page and updates the Next/Finish buttons
-     */
-    private void validatePageComplete() {
-        setPageComplete(validatePage());
-    }
-
-    /**
-     * Validates the test target (self, main project or existing project)
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateTestTarget() {
-        if (mInfo.isTestingExisting() && mInfo.getExistingTestedProject() == null) {
-            return setStatus("Please select an existing Android project as a test target.",
-                    MSG_ERROR);
-        }
-
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the project name field.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateProjectField(IWorkspace workspace) {
-        // Validate project field
-        String projectName = mInfo.getProjectName();
-        if (projectName.length() == 0) {
-            return setStatus("Project name must be specified", MSG_ERROR);
-        }
-
-        // Limit the project name to shell-agnostic characters since it will be used to
-        // generate the final package
-        if (!sProjectNamePattern.matcher(projectName).matches()) {
-            return setStatus("The project name must start with an alphanumeric characters, followed by one or more alphanumerics, digits, dots, dashes, underscores or spaces.",
-                    MSG_ERROR);
-        }
-
-        IStatus nameStatus = workspace.validateName(projectName, IResource.PROJECT);
-        if (!nameStatus.isOK()) {
-            return setStatus(nameStatus.getMessage(), MSG_ERROR);
-        }
-
-        if (mMainInfo != null && projectName.equals(mMainInfo.getProjectName())) {
-            return setStatus("The main project name and the test project name must be different.",
-                    MSG_ERROR);
-        }
-
-        if (getProjectHandle().exists()) {
-            return setStatus("A project with that name already exists in the workspace",
-                    MSG_ERROR);
-        }
-
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the location path field.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateLocationPath(IWorkspace workspace) {
-        Path path = new Path(getProjectLocation());
-        if (!mInfo.useDefaultLocation()) {
-            // If not using the default value validate the location.
-            URI uri = URIUtil.toURI(path.toOSString());
-            IStatus locationStatus = workspace.validateProjectLocationURI(getProjectHandle(),
-                    uri);
-            if (!locationStatus.isOK()) {
-                return setStatus(locationStatus.getMessage(), MSG_ERROR);
-            } else {
-                // The location is valid as far as Eclipse is concerned (i.e. mostly not
-                // an existing workspace project.) Check it either doesn't exist or is
-                // a directory that is empty.
-                File f = path.toFile();
-                if (f.exists() && !f.isDirectory()) {
-                    return setStatus("A directory name must be specified.", MSG_ERROR);
-                } else if (f.isDirectory()) {
-                    // However if the directory exists, we should put a warning if it is not
-                    // empty. We don't put an error (we'll ask the user again for confirmation
-                    // before using the directory.)
-                    String[] l = f.list();
-                    if (l.length != 0) {
-                        return setStatus("The selected output directory is not empty.",
-                                MSG_WARNING);
-                    }
-                }
-            }
-        } else {
-            // Otherwise validate the path string is not empty
-            if (getProjectLocation().length() == 0) {
-                return setStatus("A directory name must be specified.", MSG_ERROR);
-            }
-
-            File dest = path.append(mInfo.getProjectName()).toFile();
-            if (dest.exists()) {
-                return setStatus(String.format("There is already a file or directory named \"%1$s\" in the selected location.",
-                        mInfo.getProjectName()), MSG_ERROR);
-            }
-        }
-
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the sdk target choice.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateSdkTarget() {
-        if (mInfo.getSdkTarget() == null) {
-            return setStatus("An SDK Target must be specified.", MSG_ERROR);
-        }
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the sdk target choice.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validateMinSdkVersionField() {
-
-        // If the min sdk version is empty, it is always accepted.
-        if (mInfo.getMinSdkVersion().length() == 0) {
-            return MSG_NONE;
-        }
-
-        if (mInfo.getSdkTarget() != null &&
-                mInfo.getSdkTarget().getVersion().equals(mInfo.getMinSdkVersion()) == false) {
-            return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
-                    mInfo.getSdkTarget().getVersion().isPreview() ? MSG_ERROR : MSG_WARNING);
-        }
-
-        return MSG_NONE;
-    }
-
-    /**
-     * Validates the package name field.
-     *
-     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
-     */
-    private int validatePackageField() {
-        // Validate package field
-        String packageName = mInfo.getPackageName();
-        if (packageName.length() == 0) {
-            return setStatus("Project package name must be specified.", MSG_ERROR);
-        }
-
-        // Check it's a valid package string
-        int result = MSG_NONE;
-        IStatus status = JavaConventions.validatePackageName(packageName, "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
-        if (!status.isOK()) {
-            result = setStatus(String.format("Project package: %s", status.getMessage()),
-                        status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
-        }
-
-        // The Android Activity Manager does not accept packages names with only one
-        // identifier. Check the package name has at least one dot in them (the previous rule
-        // validated that if such a dot exist, it's not the first nor last characters of the
-        // string.)
-        if (result != MSG_ERROR && packageName.indexOf('.') == -1) {
-            return setStatus("Project package name must have at least two identifiers.", MSG_ERROR);
-        }
-
-        // Check that the target package name is valid too
-        packageName = mInfo.getTargetPackageName();
-        if (packageName.length() == 0) {
-            return setStatus("Target package name must be specified.", MSG_ERROR);
-        }
-
-        // Check it's a valid package string
-        status = JavaConventions.validatePackageName(packageName, "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
-        if (!status.isOK()) {
-            result = setStatus(String.format("Target package: %s", status.getMessage()),
-                        status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
-        }
-
-        if (result != MSG_ERROR && packageName.indexOf('.') == -1) {
-            return setStatus("Target name must have at least two identifiers.", MSG_ERROR);
-        }
-
-        return result;
-    }
-
-    /**
-     * Sets the error message for the wizard with the given message icon.
-     *
-     * @param message The wizard message type, one of MSG_ERROR or MSG_WARNING.
-     * @return As a convenience, always returns messageType so that the caller can return
-     *         immediately.
-     */
-    private int setStatus(String message, int messageType) {
-        if (message == null) {
-            setErrorMessage(null);
-            setMessage(null);
-        } else if (!message.equals(getMessage())) {
-            setMessage(message, messageType == MSG_WARNING ? WizardPage.WARNING : WizardPage.ERROR);
-        }
-        return messageType;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java
deleted file mode 100755
index 62bf9c1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.wizards.newproject;
-
-
-/**
- * A "New Test Android Project" Wizard.
- * <p/>
- * This is really the {@link NewProjectWizard} that only displays the "test project" page.
- */
-public class NewTestProjectWizard extends NewProjectWizard {
-
-    public NewTestProjectWizard() {
-        super(AvailablePages.TEST_PROJECT_ONLY);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java
deleted file mode 100644
index 1e3c0df..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java
+++ /dev/null
@@ -1,1245 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.ide.eclipse.adt.internal.wizards.newxmlfile;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.adt.internal.editors.menu.descriptors.MenuDescriptors;
-import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.ConfigurationState;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-
-/**
- * This is the single page of the {@link NewXmlFileWizard} which provides the ability to create
- * skeleton XML resources files for Android projects.
- * <p/>
- * This page is used to select the project, the resource folder, resource type and file name.
- */
-class NewXmlFileCreationPage extends WizardPage {
-
-    /**
-     * Information on one type of resource that can be created (e.g. menu, pref, layout, etc.)
-     */
-    static class TypeInfo {
-        private final String mUiName;
-        private final ResourceFolderType mResFolderType;
-        private final String mTooltip;
-        private final Object mRootSeed;
-        private Button mWidget;
-        private ArrayList<String> mRoots = new ArrayList<String>();
-        private final String mXmlns;
-        private final String mDefaultAttrs;
-        private final String mDefaultRoot;
-        private final int mTargetApiLevel;
-
-        public TypeInfo(String uiName,
-                        String tooltip,
-                        ResourceFolderType resFolderType,
-                        Object rootSeed,
-                        String defaultRoot,
-                        String xmlns,
-                        String defaultAttrs,
-                        int targetApiLevel) {
-            mUiName = uiName;
-            mResFolderType = resFolderType;
-            mTooltip = tooltip;
-            mRootSeed = rootSeed;
-            mDefaultRoot = defaultRoot;
-            mXmlns = xmlns;
-            mDefaultAttrs = defaultAttrs;
-            mTargetApiLevel = targetApiLevel;
-        }
-
-        /** Returns the UI name for the resource type. Unique. Never null. */
-        String getUiName() {
-            return mUiName;
-        }
-
-        /** Returns the tooltip for the resource type. Can be null. */
-        String getTooltip() {
-            return mTooltip;
-        }
-
-        /**
-         * Returns the name of the {@link ResourceFolderType}.
-         * Never null but not necessarily unique,
-         * e.g. two types use  {@link ResourceFolderType#XML}.
-         */
-        String getResFolderName() {
-            return mResFolderType.getName();
-        }
-
-        /**
-         * Returns the matching {@link ResourceFolderType}.
-         * Never null but not necessarily unique,
-         * e.g. two types use  {@link ResourceFolderType#XML}.
-         */
-        ResourceFolderType getResFolderType() {
-            return mResFolderType;
-        }
-
-        /** Sets the radio button associate with the resource type. Can be null. */
-        void setWidget(Button widget) {
-            mWidget = widget;
-        }
-
-        /** Returns the radio button associate with the resource type. Can be null. */
-        Button getWidget() {
-            return mWidget;
-        }
-
-        /**
-         * Returns the seed used to fill the root element values.
-         * The seed might be either a String, a String array, an {@link ElementDescriptor},
-         * a {@link DocumentDescriptor} or null.
-         */
-        Object getRootSeed() {
-            return mRootSeed;
-        }
-
-        /** Returns the default root element that should be selected by default. Can be null. */
-        String getDefaultRoot() {
-            return mDefaultRoot;
-        }
-
-        /**
-         * Returns the list of all possible root elements for the resource type.
-         * This can be an empty ArrayList but not null.
-         * <p/>
-         * TODO: the root list SHOULD depend on the currently selected project, to include
-         * custom classes.
-         */
-        ArrayList<String> getRoots() {
-            return mRoots;
-        }
-
-        /**
-         * If the generated resource XML file requires an "android" XMLNS, this should be set
-         * to {@link SdkConstants#NS_RESOURCES}. When it is null, no XMLNS is generated.
-         */
-        String getXmlns() {
-            return mXmlns;
-        }
-
-        /**
-         * When not null, this represent extra attributes that must be specified in the
-         * root element of the generated XML file. When null, no extra attributes are inserted.
-         */
-        String getDefaultAttrs() {
-            return mDefaultAttrs;
-        }
-
-        /**
-         * The minimum API level required by the current SDK target to support this feature.
-         */
-        public int getTargetApiLevel() {
-            return mTargetApiLevel;
-        }
-    }
-
-    /**
-     * TypeInfo, information for each "type" of file that can be created.
-     */
-    private static final TypeInfo[] sTypes = {
-        new TypeInfo(
-                "Layout",                                           // UI name
-                "An XML file that describes a screen layout.",      // tooltip
-                ResourceFolderType.LAYOUT,                          // folder type
-                AndroidTargetData.DESCRIPTOR_LAYOUT,                // root seed
-                "LinearLayout",                                     // default root
-                SdkConstants.NS_RESOURCES,                          // xmlns
-                "android:layout_width=\"wrap_content\"\n" +         // default attributes
-                "android:layout_height=\"wrap_content\"",
-                1                                                   // target API level
-                ),
-        new TypeInfo("Values",                                      // UI name
-                "An XML file with simple values: colors, strings, dimensions, etc.", // tooltip
-                ResourceFolderType.VALUES,                          // folder type
-                ResourcesDescriptors.ROOT_ELEMENT,                  // root seed
-                null,                                               // default root
-                null,                                               // xmlns
-                null,                                               // default attributes
-                1                                                   // target API level
-                ),
-        new TypeInfo("Menu",                                        // UI name
-                "An XML file that describes an menu.",              // tooltip
-                ResourceFolderType.MENU,                            // folder type
-                MenuDescriptors.MENU_ROOT_ELEMENT,                  // root seed
-                null,                                               // default root
-                SdkConstants.NS_RESOURCES,                          // xmlns
-                null,                                               // default attributes
-                1                                                   // target API level
-                ),
-        new TypeInfo("AppWidget Provider",                          // UI name
-                "An XML file that describes a widget provider.",    // tooltip
-                ResourceFolderType.XML,                             // folder type
-                AndroidTargetData.DESCRIPTOR_APPWIDGET_PROVIDER,    // root seed
-                null,                                               // default root
-                SdkConstants.NS_RESOURCES,                          // xmlns
-                null,                                               // default attributes
-                3                                                   // target API level
-                ),
-        new TypeInfo("Preference",                                  // UI name
-                "An XML file that describes preferences.",          // tooltip
-                ResourceFolderType.XML,                             // folder type
-                AndroidTargetData.DESCRIPTOR_PREFERENCES,           // root seed
-                AndroidConstants.CLASS_NAME_PREFERENCE_SCREEN,      // default root
-                SdkConstants.NS_RESOURCES,                          // xmlns
-                null,                                               // default attributes
-                1                                                   // target API level
-                ),
-        new TypeInfo("Searchable",                                  // UI name
-                "An XML file that describes a searchable.",         // tooltip
-                ResourceFolderType.XML,                             // folder type
-                AndroidTargetData.DESCRIPTOR_SEARCHABLE,            // root seed
-                null,                                               // default root
-                SdkConstants.NS_RESOURCES,                          // xmlns
-                null,                                               // default attributes
-                1                                                   // target API level
-                ),
-        new TypeInfo("Animation",                                   // UI name
-                "An XML file that describes an animation.",         // tooltip
-                ResourceFolderType.ANIM,                            // folder type
-                // TODO reuse constants if we ever make an editor with descriptors for animations
-                new String[] {                                      // root seed
-                    "set",          //$NON-NLS-1$
-                    "alpha",        //$NON-NLS-1$
-                    "scale",        //$NON-NLS-1$
-                    "translate",    //$NON-NLS-1$
-                    "rotate"        //$NON-NLS-1$
-                    },
-                "set",              //$NON-NLS-1$                   // default root
-                null,                                               // xmlns
-                null,                                               // default attributes
-                1                                                   // target API level
-                ),
-    };
-
-    /** Number of columns in the grid layout */
-    final static int NUM_COL = 4;
-
-    /** Absolute destination folder root, e.g. "/res/" */
-    private static final String RES_FOLDER_ABS = AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP;
-    /** Relative destination folder root, e.g. "res/" */
-    private static final String RES_FOLDER_REL = SdkConstants.FD_RESOURCES + AndroidConstants.WS_SEP;
-
-    private IProject mProject;
-    private Text mProjectTextField;
-    private Button mProjectBrowseButton;
-    private Text mFileNameTextField;
-    private Text mWsFolderPathTextField;
-    private Combo mRootElementCombo;
-    private IStructuredSelection mInitialSelection;
-    private ConfigurationSelector mConfigSelector;
-    private FolderConfiguration mTempConfig = new FolderConfiguration();
-    private boolean mInternalWsFolderPathUpdate;
-    private boolean mInternalTypeUpdate;
-    private boolean mInternalConfigSelectorUpdate;
-    private ProjectChooserHelper mProjectChooserHelper;
-    private ITargetChangeListener mSdkTargetChangeListener;
-
-    private TypeInfo mCurrentTypeInfo;
-
-    // --- UI creation ---
-
-    /**
-     * Constructs a new {@link NewXmlFileCreationPage}.
-     * <p/>
-     * Called by {@link NewXmlFileWizard#createMainPage()}.
-     */
-    protected NewXmlFileCreationPage(String pageName) {
-        super(pageName);
-        setPageComplete(false);
-    }
-
-    public void setInitialSelection(IStructuredSelection initialSelection) {
-        mInitialSelection = initialSelection;
-    }
-
-    /**
-     * Called by the parent Wizard to create the UI for this Wizard Page.
-     *
-     * {@inheritDoc}
-     *
-     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    public void createControl(Composite parent) {
-        Composite composite = new Composite(parent, SWT.NULL);
-        composite.setFont(parent.getFont());
-
-        initializeDialogUnits(parent);
-
-        composite.setLayout(new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/));
-        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        createProjectGroup(composite);
-        createTypeGroup(composite);
-        createRootGroup(composite);
-
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setControl(composite);
-
-        // Update state the first time
-        initializeFromSelection(mInitialSelection);
-        initializeRootValues();
-        enableTypesBasedOnApi();
-        if (mCurrentTypeInfo != null) {
-            updateRootCombo(mCurrentTypeInfo);
-        }
-        installTargetChangeListener();
-        validatePage();
-    }
-
-    private void installTargetChangeListener() {
-        mSdkTargetChangeListener = new ITargetChangeListener() {
-            public void onProjectTargetChange(IProject changedProject) {
-                // If this is the current project, force it to reload its data
-                if (changedProject != null && changedProject == mProject) {
-                    changeProject(mProject);
-                }
-            }
-
-            public void onTargetsLoaded() {
-                // Reload the current project, if any, in case its target has changed.
-                if (mProject != null) {
-                    changeProject(mProject);
-                }
-            }
-        };
-
-        AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);
-    }
-
-    @Override
-    public void dispose() {
-
-        if (mSdkTargetChangeListener != null) {
-            AdtPlugin.getDefault().removeTargetListener(mSdkTargetChangeListener);
-            mSdkTargetChangeListener = null;
-        }
-
-        super.dispose();
-    }
-
-    /**
-     * Returns the target project or null.
-     */
-    public IProject getProject() {
-        return mProject;
-    }
-
-    /**
-     * Returns the destination filename or an empty string.
-     */
-    public String getFileName() {
-        return mFileNameTextField == null ? "" : mFileNameTextField.getText();         //$NON-NLS-1$
-    }
-
-    /**
-     * Returns the destination folder path relative to the project or an empty string.
-     */
-    public String getWsFolderPath() {
-        return mWsFolderPathTextField == null ? "" : mWsFolderPathTextField.getText(); //$NON-NLS-1$
-    }
-
-
-    /**
-     * Returns an {@link IFile} on the destination file.
-     * <p/>
-     * Uses {@link #getProject()}, {@link #getWsFolderPath()} and {@link #getFileName()}.
-     * <p/>
-     * Returns null if the project, filename or folder are invalid and the destination file
-     * cannot be determined.
-     * <p/>
-     * The {@link IFile} is a resource. There might or might not be an actual real file.
-     */
-    public IFile getDestinationFile() {
-        IProject project = getProject();
-        String wsFolderPath = getWsFolderPath();
-        String fileName = getFileName();
-        if (project != null && wsFolderPath.length() > 0 && fileName.length() > 0) {
-            IPath dest = new Path(wsFolderPath).append(fileName);
-            IFile file = project.getFile(dest);
-            return file;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the {@link TypeInfo} for the currently selected type radio button.
-     * Returns null if no radio button is selected.
-     *
-     * @return A {@link TypeInfo} or null.
-     */
-    public TypeInfo getSelectedType() {
-        TypeInfo type = null;
-        for (TypeInfo ti : sTypes) {
-            if (ti.getWidget().getSelection()) {
-                type = ti;
-                break;
-            }
-        }
-        return type;
-    }
-
-    /**
-     * Returns the selected root element string, if any.
-     *
-     * @return The selected root element string or null.
-     */
-    public String getRootElement() {
-        int index = mRootElementCombo.getSelectionIndex();
-        if (index >= 0) {
-            return mRootElementCombo.getItem(index);
-        }
-        return null;
-    }
-
-    // --- UI creation ---
-
-    /**
-     * Helper method to create a new GridData with an horizontal span.
-     *
-     * @param horizSpan The number of cells for the horizontal span.
-     * @return A new GridData with the horizontal span.
-     */
-    private GridData newGridData(int horizSpan) {
-        GridData gd = new GridData();
-        gd.horizontalSpan = horizSpan;
-        return gd;
-    }
-
-    /**
-     * Helper method to create a new GridData with an horizontal span and a style.
-     *
-     * @param horizSpan The number of cells for the horizontal span.
-     * @param style The style, e.g. {@link GridData#FILL_HORIZONTAL}
-     * @return A new GridData with the horizontal span and the style.
-     */
-    private GridData newGridData(int horizSpan, int style) {
-        GridData gd = new GridData(style);
-        gd.horizontalSpan = horizSpan;
-        return gd;
-    }
-
-    /**
-     * Helper method that creates an empty cell in the parent composite.
-     *
-     * @param parent The parent composite.
-     */
-    private void emptyCell(Composite parent) {
-        new Label(parent, SWT.NONE);
-    }
-
-    /**
-     * Pads the parent with empty cells to match the number of columns of the parent grid.
-     *
-     * @param parent A grid layout with NUM_COL columns
-     * @param col The current number of columns used.
-     * @return 0, the new number of columns used, for convenience.
-     */
-    private int padWithEmptyCells(Composite parent, int col) {
-        for (; col < NUM_COL; ++col) {
-            emptyCell(parent);
-        }
-        col = 0;
-        return col;
-    }
-
-    /**
-     * Creates the project & filename fields.
-     * <p/>
-     * The parent must be a GridLayout with NUM_COL colums.
-     */
-    private void createProjectGroup(Composite parent) {
-        int col = 0;
-
-        // project name
-        String tooltip = "The Android Project where the new resource file will be created.";
-        Label label = new Label(parent, SWT.NONE);
-        label.setText("Project");
-        label.setToolTipText(tooltip);
-        ++col;
-
-        mProjectTextField = new Text(parent, SWT.BORDER);
-        mProjectTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mProjectTextField.setToolTipText(tooltip);
-        mProjectTextField.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onProjectFieldUpdated();
-            }
-        });
-        ++col;
-
-        mProjectBrowseButton = new Button(parent, SWT.NONE);
-        mProjectBrowseButton.setText("Browse...");
-        mProjectBrowseButton.setToolTipText("Allows you to select the Android project to modify.");
-        mProjectBrowseButton.addSelectionListener(new SelectionAdapter() {
-           @Override
-            public void widgetSelected(SelectionEvent e) {
-               onProjectBrowse();
-            }
-        });
-        mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
-        ++col;
-
-        col = padWithEmptyCells(parent, col);
-
-        // file name
-        tooltip = "The name of the resource file to create.";
-        label = new Label(parent, SWT.NONE);
-        label.setText("File");
-        label.setToolTipText(tooltip);
-        ++col;
-
-        mFileNameTextField = new Text(parent, SWT.BORDER);
-        mFileNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mFileNameTextField.setToolTipText(tooltip);
-        mFileNameTextField.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                validatePage();
-            }
-        });
-        ++col;
-
-        padWithEmptyCells(parent, col);
-    }
-
-    /**
-     * Creates the type field, {@link ConfigurationSelector} and the folder field.
-     * <p/>
-     * The parent must be a GridLayout with NUM_COL colums.
-     */
-    private void createTypeGroup(Composite parent) {
-        // separator
-        Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
-        label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL));
-
-        // label before type radios
-        label = new Label(parent, SWT.NONE);
-        label.setText("What type of resource would you like to create?");
-        label.setLayoutData(newGridData(NUM_COL));
-
-        // display the types on three columns of radio buttons.
-        emptyCell(parent);
-        Composite grid = new Composite(parent, SWT.NONE);
-        padWithEmptyCells(parent, 2);
-
-        grid.setLayout(new GridLayout(NUM_COL, true /*makeColumnsEqualWidth*/));
-
-        SelectionListener radioListener = new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                // single-click. Only do something if activated.
-                if (e.getSource() instanceof Button) {
-                    onRadioTypeUpdated((Button) e.getSource());
-                }
-            }
-        };
-
-        int n = sTypes.length;
-        int num_lines = (n + NUM_COL/2) / NUM_COL;
-        for (int line = 0, k = 0; line < num_lines; line++) {
-            for (int i = 0; i < NUM_COL; i++, k++) {
-                if (k < n) {
-                    TypeInfo type = sTypes[k];
-                    Button radio = new Button(grid, SWT.RADIO);
-                    type.setWidget(radio);
-                    radio.setSelection(false);
-                    radio.setText(type.getUiName());
-                    radio.setToolTipText(type.getTooltip());
-                    radio.addSelectionListener(radioListener);
-                } else {
-                    emptyCell(grid);
-                }
-            }
-        }
-
-        // label before configuration selector
-        label = new Label(parent, SWT.NONE);
-        label.setText("What type of resource configuration would you like?");
-        label.setLayoutData(newGridData(NUM_COL));
-
-        // configuration selector
-        emptyCell(parent);
-        mConfigSelector = new ConfigurationSelector(parent, false /* deviceMode*/);
-        GridData gd = newGridData(2, GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
-        gd.widthHint = ConfigurationSelector.WIDTH_HINT;
-        gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
-        mConfigSelector.setLayoutData(gd);
-        mConfigSelector.setOnChangeListener(new onConfigSelectorUpdated());
-        emptyCell(parent);
-
-        // folder name
-        String tooltip = "The folder where the file will be generated, relative to the project.";
-        label = new Label(parent, SWT.NONE);
-        label.setText("Folder");
-        label.setToolTipText(tooltip);
-
-        mWsFolderPathTextField = new Text(parent, SWT.BORDER);
-        mWsFolderPathTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mWsFolderPathTextField.setToolTipText(tooltip);
-        mWsFolderPathTextField.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onWsFolderPathUpdated();
-            }
-        });
-    }
-
-    /**
-     * Creates the root element combo.
-     * <p/>
-     * The parent must be a GridLayout with NUM_COL colums.
-     */
-    private void createRootGroup(Composite parent) {
-        // separator
-        Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
-        label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL));
-
-        // label before the root combo
-        String tooltip = "The root element to create in the XML file.";
-        label = new Label(parent, SWT.NONE);
-        label.setText("Select the root element for the XML file:");
-        label.setLayoutData(newGridData(NUM_COL));
-        label.setToolTipText(tooltip);
-
-        // root combo
-        emptyCell(parent);
-
-        mRootElementCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mRootElementCombo.setEnabled(false);
-        mRootElementCombo.select(0);
-        mRootElementCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mRootElementCombo.setToolTipText(tooltip);
-
-        padWithEmptyCells(parent, 2);
-    }
-
-    /**
-     * Called by {@link NewXmlFileWizard} to initialize the page with the selection
-     * received by the wizard -- typically the current user workbench selection.
-     * <p/>
-     * Things we expect to find out from the selection:
-     * <ul>
-     * <li>The project name, valid if it's an android nature.</li>
-     * <li>The current folder, valid if it's a folder under /res</li>
-     * <li>An existing filename, in which case the user will be asked whether to override it.</li>
-     * <ul>
-     *
-     * @param selection The selection when the wizard was initiated.
-     */
-    private void initializeFromSelection(IStructuredSelection selection) {
-        if (selection == null) {
-            return;
-        }
-
-        // Find the best match in the element list. In case there are multiple selected elements
-        // select the one that provides the most information and assign them a score,
-        // e.g. project=1 + folder=2 + file=4.
-        IProject targetProject = null;
-        String targetWsFolderPath = null;
-        String targetFileName = null;
-        int targetScore = 0;
-        for (Object element : selection.toList()) {
-            if (element instanceof IAdaptable) {
-                IResource res = (IResource) ((IAdaptable) element).getAdapter(IResource.class);
-                IProject project = res != null ? res.getProject() : null;
-
-                // Is this an Android project?
-                try {
-                    if (project == null || !project.hasNature(AndroidConstants.NATURE)) {
-                        continue;
-                    }
-                } catch (CoreException e) {
-                    // checking the nature failed, ignore this resource
-                    continue;
-                }
-
-                int score = 1; // we have a valid project at least
-
-                IPath wsFolderPath = null;
-                String fileName = null;
-                if (res.getType() == IResource.FOLDER) {
-                    wsFolderPath = res.getProjectRelativePath();
-                } else if (res.getType() == IResource.FILE) {
-                    fileName = res.getName();
-                    wsFolderPath = res.getParent().getProjectRelativePath();
-                }
-
-                // Disregard this folder selection if it doesn't point to /res/something
-                if (wsFolderPath != null &&
-                        wsFolderPath.segmentCount() > 1 &&
-                        SdkConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) {
-                    score += 2;
-                } else {
-                    wsFolderPath = null;
-                    fileName = null;
-                }
-
-                score += fileName != null ? 4 : 0;
-
-                if (score > targetScore) {
-                    targetScore = score;
-                    targetProject = project;
-                    targetWsFolderPath = wsFolderPath != null ? wsFolderPath.toString() : null;
-                    targetFileName = fileName;
-                }
-            }
-        }
-
-        // Now set the UI accordingly
-        if (targetScore > 0) {
-            mProject = targetProject;
-            mProjectTextField.setText(targetProject != null ? targetProject.getName() : ""); //$NON-NLS-1$
-            mFileNameTextField.setText(targetFileName != null ? targetFileName : ""); //$NON-NLS-1$
-            mWsFolderPathTextField.setText(targetWsFolderPath != null ? targetWsFolderPath : ""); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Initialize the root values of the type infos based on the current framework values.
-     */
-    private void initializeRootValues() {
-        for (TypeInfo type : sTypes) {
-            // Clear all the roots for this type
-            ArrayList<String> roots = type.getRoots();
-            if (roots.size() > 0) {
-                roots.clear();
-            }
-
-            // depending of the type of the seed, initialize the root in different ways
-            Object rootSeed = type.getRootSeed();
-
-            if (rootSeed instanceof String) {
-                // The seed is a single string, Add it as-is.
-                roots.add((String) rootSeed);
-            } else if (rootSeed instanceof String[]) {
-                // The seed is an array of strings. Add them as-is.
-                for (String value : (String[]) rootSeed) {
-                    roots.add(value);
-                }
-            } else if (rootSeed instanceof Integer && mProject != null) {
-                // The seed is a descriptor reference defined in AndroidTargetData.DESCRIPTOR_*
-                // In this case add all the children element descriptors defined, recursively,
-                // and avoid infinite recursion by keeping track of what has already been added.
-
-                // Note: if project is null, the root list will be empty since it has been
-                // cleared above.
-
-                // get the AndroidTargetData from the project
-                IAndroidTarget target = null;
-                AndroidTargetData data = null;
-
-                target = Sdk.getCurrent().getTarget(mProject);
-                if (target == null) {
-                    // A project should have a target. The target can be missing if the project
-                    // is an old project for which a target hasn't been affected or if the
-                    // target no longer exists in this SDK. Simply log the error and dismiss.
-
-                    AdtPlugin.log(IStatus.INFO,
-                            "NewXmlFile wizard: no platform target for project %s",  //$NON-NLS-1$
-                            mProject.getName());
-                    continue;
-                } else {
-                    data = Sdk.getCurrent().getTargetData(target);
-
-                    if (data == null) {
-                        // We should have both a target and its data.
-                        // However if the wizard is invoked whilst the platform is still being
-                        // loaded we can end up in a weird case where we have a target but it
-                        // doesn't have any data yet.
-                        // Lets log a warning and silently ignore this root.
-
-                        AdtPlugin.log(IStatus.INFO,
-                              "NewXmlFile wizard: no data for target %s, project %s",  //$NON-NLS-1$
-                              target.getName(), mProject.getName());
-                        continue;
-                    }
-                }
-
-                IDescriptorProvider provider = data.getDescriptorProvider((Integer)rootSeed);
-                ElementDescriptor descriptor = provider.getDescriptor();
-                if (descriptor != null) {
-                    HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>();
-                    initRootElementDescriptor(roots, descriptor, visited);
-                }
-
-                // Sort alphabetically.
-                Collections.sort(roots);
-            }
-        }
-    }
-
-    /**
-     * Helper method to recursively insert all XML names for the given {@link ElementDescriptor}
-     * into the roots array list. Keeps track of visited nodes to avoid infinite recursion.
-     * Also avoids inserting the top {@link DocumentDescriptor} which is generally synthetic
-     * and not a valid root element.
-     */
-    private void initRootElementDescriptor(ArrayList<String> roots,
-            ElementDescriptor desc, HashSet<ElementDescriptor> visited) {
-        if (!(desc instanceof DocumentDescriptor)) {
-            String xmlName = desc.getXmlName();
-            if (xmlName != null && xmlName.length() > 0) {
-                roots.add(xmlName);
-            }
-        }
-
-        visited.add(desc);
-
-        for (ElementDescriptor child : desc.getChildren()) {
-            if (!visited.contains(child)) {
-                initRootElementDescriptor(roots, child, visited);
-            }
-        }
-    }
-
-    /**
-     * Callback called when the user edits the project text field.
-     */
-    private void onProjectFieldUpdated() {
-        String project = mProjectTextField.getText();
-
-        // Is this a valid project?
-        IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null /*javaModel*/);
-        IProject found = null;
-        for (IJavaProject p : projects) {
-            if (p.getProject().getName().equals(project)) {
-                found = p.getProject();
-                break;
-            }
-        }
-
-        if (found != mProject) {
-            changeProject(found);
-        }
-    }
-
-    /**
-     * Callback called when the user uses the "Browse Projects" button.
-     */
-    private void onProjectBrowse() {
-        IJavaProject p = mProjectChooserHelper.chooseJavaProject(mProjectTextField.getText());
-        if (p != null) {
-            changeProject(p.getProject());
-            mProjectTextField.setText(mProject.getName());
-        }
-    }
-
-    /**
-     * Changes mProject to the given new project and update the UI accordingly.
-     * <p/>
-     * Note that this does not check if the new project is the same as the current one
-     * on purpose, which allows a project to be updated when its target has changed or
-     * when targets are loaded in the background.
-     */
-    private void changeProject(IProject newProject) {
-        mProject = newProject;
-
-        // enable types based on new API level
-        enableTypesBasedOnApi();
-
-        // update the folder name based on API level
-        resetFolderPath(false /*validate*/);
-
-        // update the Type with the new descriptors.
-        initializeRootValues();
-
-        // update the combo
-        updateRootCombo(getSelectedType());
-
-        validatePage();
-    }
-
-    /**
-     * Callback called when the Folder text field is changed, either programmatically
-     * or by the user.
-     */
-    private void onWsFolderPathUpdated() {
-        if (mInternalWsFolderPathUpdate) {
-            return;
-        }
-
-        String wsFolderPath = mWsFolderPathTextField.getText();
-
-        // This is a custom path, we need to sanitize it.
-        // First it should start with "/res/". Then we need to make sure there are no
-        // relative paths, things like "../" or "./" or even "//".
-        wsFolderPath = wsFolderPath.replaceAll("/+\\.\\./+|/+\\./+|//+|\\\\+|^/+", "/");  //$NON-NLS-1$ //$NON-NLS-2$
-        wsFolderPath = wsFolderPath.replaceAll("^\\.\\./+|^\\./+", "");                   //$NON-NLS-1$ //$NON-NLS-2$
-        wsFolderPath = wsFolderPath.replaceAll("/+\\.\\.$|/+\\.$|/+$", "");               //$NON-NLS-1$ //$NON-NLS-2$
-
-        ArrayList<TypeInfo> matches = new ArrayList<TypeInfo>();
-
-        // We get "res/foo" from selections relative to the project when we want a "/res/foo" path.
-        if (wsFolderPath.startsWith(RES_FOLDER_REL)) {
-            wsFolderPath = RES_FOLDER_ABS + wsFolderPath.substring(RES_FOLDER_REL.length());
-
-            mInternalWsFolderPathUpdate = true;
-            mWsFolderPathTextField.setText(wsFolderPath);
-            mInternalWsFolderPathUpdate = false;
-        }
-
-        if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
-            wsFolderPath = wsFolderPath.substring(RES_FOLDER_ABS.length());
-
-            int pos = wsFolderPath.indexOf(AndroidConstants.WS_SEP_CHAR);
-            if (pos >= 0) {
-                wsFolderPath = wsFolderPath.substring(0, pos);
-            }
-
-            String[] folderSegments = wsFolderPath.split(FolderConfiguration.QUALIFIER_SEP);
-
-            if (folderSegments.length > 0) {
-                String folderName = folderSegments[0];
-
-                // update config selector
-                mInternalConfigSelectorUpdate = true;
-                mConfigSelector.setConfiguration(folderSegments);
-                mInternalConfigSelectorUpdate = false;
-
-                boolean selected = false;
-                for (TypeInfo type : sTypes) {
-                    if (type.getResFolderName().equals(folderName)) {
-                        matches.add(type);
-                        selected |= type.getWidget().getSelection();
-                    }
-                }
-
-                if (matches.size() == 1) {
-                    // If there's only one match, select it if it's not already selected
-                    if (!selected) {
-                        selectType(matches.get(0));
-                    }
-                } else if (matches.size() > 1) {
-                    // There are multiple type candidates for this folder. This can happen
-                    // for /res/xml for example. Check to see if one of them is currently
-                    // selected. If yes, leave the selection unchanged. If not, deselect all type.
-                    if (!selected) {
-                        selectType(null);
-                    }
-                } else {
-                    // Nothing valid was selected.
-                    selectType(null);
-                }
-            }
-        }
-
-        validatePage();
-    }
-
-    /**
-     * Callback called when one of the type radio button is changed.
-     *
-     * @param typeWidget The type radio button that changed.
-     */
-    private void onRadioTypeUpdated(Button typeWidget) {
-        // Do nothing if this is an internal modification or if the widget has been
-        // de-selected.
-        if (mInternalTypeUpdate || !typeWidget.getSelection()) {
-            return;
-        }
-
-        // Find type info that has just been enabled.
-        TypeInfo type = null;
-        for (TypeInfo ti : sTypes) {
-            if (ti.getWidget() == typeWidget) {
-                type = ti;
-                break;
-            }
-        }
-
-        if (type == null) {
-            return;
-        }
-
-        // update the combo
-
-        updateRootCombo(type);
-
-        // update the folder path
-
-        String wsFolderPath = mWsFolderPathTextField.getText();
-        String newPath = null;
-
-        mConfigSelector.getConfiguration(mTempConfig);
-        ResourceQualifier qual = mTempConfig.getInvalidQualifier();
-        if (qual == null) {
-            // The configuration is valid. Reformat the folder path using the canonical
-            // value from the configuration.
-
-            newPath = RES_FOLDER_ABS + mTempConfig.getFolderName(type.getResFolderType(), mProject);
-        } else {
-            // The configuration is invalid. We still update the path but this time
-            // do it manually on the string.
-            if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
-                wsFolderPath.replaceFirst(
-                        "^(" + RES_FOLDER_ABS +")[^-]*(.*)",         //$NON-NLS-1$ //$NON-NLS-2$
-                        "\\1" + type.getResFolderName() + "\\2");   //$NON-NLS-1$ //$NON-NLS-2$
-            } else {
-                newPath = RES_FOLDER_ABS + mTempConfig.getFolderName(type.getResFolderType(),
-                        mProject);
-            }
-        }
-
-        if (newPath != null && !newPath.equals(wsFolderPath)) {
-            mInternalWsFolderPathUpdate = true;
-            mWsFolderPathTextField.setText(newPath);
-            mInternalWsFolderPathUpdate = false;
-        }
-
-        validatePage();
-    }
-
-    /**
-     * Helper method that fills the values of the "root element" combo box based
-     * on the currently selected type radio button. Also disables the combo is there's
-     * only one choice. Always select the first root element for the given type.
-     *
-     * @param type The currently selected {@link TypeInfo}. Cannot be null.
-     */
-    private void updateRootCombo(TypeInfo type) {
-        // reset all the values in the combo
-        mRootElementCombo.removeAll();
-
-        if (type != null) {
-            // get the list of roots. The list can be empty but not null.
-            ArrayList<String> roots = type.getRoots();
-
-            // enable the combo if there's more than one choice
-            mRootElementCombo.setEnabled(roots != null && roots.size() > 1);
-
-            for (String root : roots) {
-                mRootElementCombo.add(root);
-            }
-
-            int index = 0; // default is to select the first one
-            String defaultRoot = type.getDefaultRoot();
-            if (defaultRoot != null) {
-                index = roots.indexOf(defaultRoot);
-            }
-            mRootElementCombo.select(index < 0 ? 0 : index);
-        }
-    }
-
-    /**
-     * Callback called when the configuration has changed in the {@link ConfigurationSelector}.
-     */
-    private class onConfigSelectorUpdated implements Runnable {
-        public void run() {
-            if (mInternalConfigSelectorUpdate) {
-                return;
-            }
-
-            resetFolderPath(true /*validate*/);
-        }
-    }
-
-    /**
-     * Helper method to select on of the type radio buttons.
-     *
-     * @param type The TypeInfo matching the radio button to selected or null to deselect them all.
-     */
-    private void selectType(TypeInfo type) {
-        if (type == null || !type.getWidget().getSelection()) {
-            mInternalTypeUpdate = true;
-            mCurrentTypeInfo = type;
-            for (TypeInfo type2 : sTypes) {
-                type2.getWidget().setSelection(type2 == type);
-            }
-            updateRootCombo(type);
-            mInternalTypeUpdate = false;
-        }
-    }
-
-    /**
-     * Helper method to enable the type radio buttons depending on the current API level.
-     * <p/>
-     * A type radio button is enabled either if:
-     * - if mProject is null, API level 1 is considered valid
-     * - if mProject is !null, the project->target->API must be >= to the type's API level.
-     */
-    private void enableTypesBasedOnApi() {
-
-        IAndroidTarget target = mProject != null ? Sdk.getCurrent().getTarget(mProject) : null;
-        int currentApiLevel = 1;
-        if (target != null) {
-            currentApiLevel = target.getVersion().getApiLevel();
-        }
-
-        for (TypeInfo type : sTypes) {
-            type.getWidget().setEnabled(type.getTargetApiLevel() <= currentApiLevel);
-        }
-    }
-
-    /**
-     * Reset the current Folder path based on the UI selection
-     * @param validate if true, force a call to {@link #validatePage()}.
-     */
-    private void resetFolderPath(boolean validate) {
-        TypeInfo type = getSelectedType();
-
-        if (type != null) {
-            mConfigSelector.getConfiguration(mTempConfig);
-            StringBuffer sb = new StringBuffer(RES_FOLDER_ABS);
-            sb.append(mTempConfig.getFolderName(type.getResFolderType(), mProject));
-
-            mInternalWsFolderPathUpdate = true;
-            mWsFolderPathTextField.setText(sb.toString());
-            mInternalWsFolderPathUpdate = false;
-
-            if (validate) {
-                validatePage();
-            }
-        }
-    }
-
-    /**
-     * Validates the fields, displays errors and warnings.
-     * Enables the finish button if there are no errors.
-     */
-    private void validatePage() {
-        String error = null;
-        String warning = null;
-
-        // -- validate project
-        if (getProject() == null) {
-            error = "Please select an Android project.";
-        }
-
-        // -- validate filename
-        if (error == null) {
-            String fileName = getFileName();
-            if (fileName == null || fileName.length() == 0) {
-                error = "A destination file name is required.";
-            } else if (!fileName.endsWith(AndroidConstants.DOT_XML)) {
-                error = String.format("The filename must end with %1$s.", AndroidConstants.DOT_XML);
-            }
-        }
-
-        // -- validate type
-        if (error == null) {
-            TypeInfo type = getSelectedType();
-
-            if (type == null) {
-                error = "One of the types must be selected (e.g. layout, values, etc.)";
-            }
-        }
-
-        // -- validate type API level
-        if (error == null) {
-            IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
-            int currentApiLevel = 1;
-            if (target != null) {
-                currentApiLevel = target.getVersion().getApiLevel();
-            }
-
-            TypeInfo type = getSelectedType();
-
-            if (type.getTargetApiLevel() > currentApiLevel) {
-                error = "The API level of the selected type (e.g. AppWidget, etc.) is not " +
-                        "compatible with the API level of the project.";
-            }
-        }
-
-        // -- validate folder configuration
-        if (error == null) {
-            ConfigurationState state = mConfigSelector.getState();
-            if (state == ConfigurationState.INVALID_CONFIG) {
-                ResourceQualifier qual = mConfigSelector.getInvalidQualifier();
-                if (qual != null) {
-                    error = String.format("The qualifier '%1$s' is invalid in the folder configuration.",
-                            qual.getName());
-                }
-            } else if (state == ConfigurationState.REGION_WITHOUT_LANGUAGE) {
-                error = "The Region qualifier requires the Language qualifier.";
-            }
-        }
-
-        // -- validate generated path
-        if (error == null) {
-            String wsFolderPath = getWsFolderPath();
-            if (!wsFolderPath.startsWith(RES_FOLDER_ABS)) {
-                error = String.format("Target folder must start with %1$s.", RES_FOLDER_ABS);
-            }
-        }
-
-        // -- validate destination file doesn't exist
-        if (error == null) {
-            IFile file = getDestinationFile();
-            if (file != null && file.exists()) {
-                warning = "The destination file already exists";
-            }
-        }
-
-        // -- update UI & enable finish if there's no error
-        setPageComplete(error == null);
-        if (error != null) {
-            setMessage(error, WizardPage.ERROR);
-        } else if (warning != null) {
-            setMessage(warning, WizardPage.WARNING);
-        } else {
-            setErrorMessage(null);
-            setMessage(null);
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
deleted file mode 100644
index 9f4a518..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package com.android.ide.eclipse.adt.internal.wizards.newxmlfile;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.ui.INewWizard;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.ide.IDE;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * The "New Android XML File Wizard" provides the ability to create skeleton XML
- * resources files for Android projects.
- * <p/>
- * The wizard has one page, {@link NewXmlFileCreationPage}, used to select the project,
- * the resource folder, resource type and file name. It then creates the XML file.
- */
-public class NewXmlFileWizard extends Wizard implements INewWizard {
-
-    private static final String PROJECT_LOGO_LARGE = "android_large"; //$NON-NLS-1$
-    
-    protected static final String MAIN_PAGE_NAME = "newAndroidXmlFilePage"; //$NON-NLS-1$
-
-    private NewXmlFileCreationPage mMainPage;
-
-    public void init(IWorkbench workbench, IStructuredSelection selection) {
-        setHelpAvailable(false); // TODO have help
-        setWindowTitle("New Android XML File");
-        setImageDescriptor();
-
-        mMainPage = createMainPage();
-        mMainPage.setTitle("New Android XML File");
-        mMainPage.setDescription("Creates a new Android XML file.");
-        mMainPage.setInitialSelection(selection);
-    }
-    
-    /**
-     * Creates the wizard page.
-     * <p/>
-     * Please do NOT override this method.
-     * <p/>
-     * This is protected so that it can be overridden by unit tests.
-     * However the contract of this class is private and NO ATTEMPT will be made
-     * to maintain compatibility between different versions of the plugin.
-     */
-    protected NewXmlFileCreationPage createMainPage() {
-        return new NewXmlFileCreationPage(MAIN_PAGE_NAME);
-    }
-
-    // -- Methods inherited from org.eclipse.jface.wizard.Wizard --
-    //
-    // The Wizard class implements most defaults and boilerplate code needed by
-    // IWizard
-
-    /**
-     * Adds pages to this wizard.
-     */
-    @Override
-    public void addPages() {
-        addPage(mMainPage);
-    }
-
-    /**
-     * Performs any actions appropriate in response to the user having pressed
-     * the Finish button, or refuse if finishing now is not permitted: here, it
-     * actually creates the workspace project and then switch to the Java
-     * perspective.
-     *
-     * @return True
-     */
-    @Override
-    public boolean performFinish() {
-        IFile file = createXmlFile();
-        if (file == null) {
-            return false;
-        } else {
-            // Open the file in an editor
-            IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-            if (win != null) {
-                IWorkbenchPage page = win.getActivePage();
-                if (page != null) {
-                    try {
-                        IDE.openEditor(page, file);
-                    } catch (PartInitException e) {
-                        AdtPlugin.log(e, "Failed to create %1$s: missing type",  //$NON-NLS-1$
-                                file.getFullPath().toString());
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-    // -- Custom Methods --
-    
-    private IFile createXmlFile() {
-        IFile file = mMainPage.getDestinationFile();
-        String name = file.getFullPath().toString();
-        boolean need_delete = false;
-
-        if (file.exists()) {
-            if (!AdtPlugin.displayPrompt("New Android XML File",
-                String.format("Do you want to overwrite the file %1$s ?", name))) {
-                // abort if user selects cancel.
-                return null;
-            }
-            need_delete = true;
-        } else {
-            createWsParentDirectory(file.getParent());
-        }
-        
-        TypeInfo type = mMainPage.getSelectedType();
-        if (type == null) {
-            // this is not expected to happen
-            AdtPlugin.log(IStatus.ERROR, "Failed to create %1$s: missing type", name);  //$NON-NLS-1$
-            return null;
-        }
-        String xmlns = type.getXmlns();
-        String root = mMainPage.getRootElement();
-        if (root == null) {
-            // this is not expected to happen
-            AdtPlugin.log(IStatus.ERROR, "Failed to create %1$s: missing root element", //$NON-NLS-1$
-                    file.toString());
-            return null;
-        }
-        
-        StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");   //$NON-NLS-1$
-
-        sb.append('<').append(root);
-        if (xmlns != null) {
-            sb.append('\n').append("  xmlns:android=\"").append(xmlns).append("\"");  //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        
-        String attrs = type.getDefaultAttrs();
-        if (attrs != null) {
-            sb.append("\n  ");                       //$NON-NLS-1$
-            sb.append(attrs.replace("\n", "\n  "));  //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        
-        sb.append(">\n");                            //$NON-NLS-1$
-        sb.append("</").append(root).append(">\n");  //$NON-NLS-1$ //$NON-NLS-2$
-
-        String result = sb.toString();
-        String error = null;
-        try {
-            byte[] buf = result.getBytes("UTF8");
-            InputStream stream = new ByteArrayInputStream(buf);
-            if (need_delete) {
-                file.delete(IFile.KEEP_HISTORY | IFile.FORCE, null /*monitor*/);
-            }
-            file.create(stream, true /*force*/, null /*progres*/);
-            return file;
-        } catch (UnsupportedEncodingException e) {
-            error = e.getMessage();
-        } catch (CoreException e) {
-            error = e.getMessage();
-        }
-
-        error = String.format("Failed to generate %1$s: %2$s", name, error);
-        AdtPlugin.displayError("New Android XML File", error);
-        return null;
-    }
-
-    private boolean createWsParentDirectory(IContainer wsPath) {
-        if (wsPath.getType() == IContainer.FOLDER) {
-            if (wsPath == null || wsPath.exists()) {
-                return true;
-            }
-
-            IFolder folder = (IFolder) wsPath;
-            try {
-                if (createWsParentDirectory(wsPath.getParent())) {
-                    folder.create(true /* force */, true /* local */, null /* monitor */);
-                    return true;
-                }
-            } catch (CoreException e) {
-                e.printStackTrace();
-            }
-        }
-        
-        return false;
-    }
-
-    /**
-     * Returns an image descriptor for the wizard logo.
-     */
-    private void setImageDescriptor() {
-        ImageDescriptor desc = IconFactory.getInstance().getImageDescriptor(PROJECT_LOGO_LARGE);
-        setDefaultPageImageDescriptor(desc);
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/messages.properties
deleted file mode 100644
index 982bd84..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/messages.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-Dialog_Title_SDK_Location=Android SDK Location
-SDK_Not_Setup=The location of the Android SDK has not been setup. Please go to Preferences > Android and set it up
-Error_Check_Prefs=%1$s\nPlease check the Android plugin's preferences.
-Could_Not_Find_Folder=Could not find SDK folder '%1$s'.
-Could_Not_Find_Folder_In_SDK=Could not find folder '%1$s' inside SDK '%2$s'.
-Could_Not_Find=Could not find %1$s\!
-VersionCheck_SDK_Milestone_Too_Low=This version of ADT requires a SDK in version M%1$d or above.\n\nCurrent version is %2$s.\n\nPlease update your SDK to the latest version.
-VersionCheck_SDK_Build_Too_Low=This version of ADT requires a SDK in version %1$d (M%2$d) or above.\n\nCurrent version is %3$s.\n\nPlease update your SDK to the latest version.
-VersionCheck_Plugin_Version_Failed=Failed to get the required ADT version number from the SDK.\n\nThe Android Developer Toolkit may not work properly.
-VersionCheck_Unable_To_Parse_Version_s=Unable to parse sdk build version: %1$s
-VersionCheck_Plugin_Too_Old=This Android SDK requires Android Developer Toolkit version %1$d.%2$d.%3$d or above.\n\nCurrent version is %4$s.\n\nPlease update ADT to the latest version.
-AdtPlugin_Failed_To_Start_s=Failed to start %1$s
-AdtPlugin_Android_SDK_Content_Loader=Android SDK Content Loader
-AdtPlugin_Parsing_Resources=Parsing Resources
-AdtPlugin_Android_SDK_Resource_Parser=Android SDK Resource Parser
-AdtPlugin_Failed_To_Parse_s=Failed to parse:
-Console_Date_Tag=[%1$tF %1$tT]
-Console_Data_Project_Tag=[%1$tF %1$tT - %2$s]
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
deleted file mode 100644
index 5d57413..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="PACKAGE"
-      android:versionCode="1"
-      android:versionName="1.0">
-    <application android:icon="@drawable/icon" android:label="APPLICATION_NAME">
-ACTIVITIES
-TEST-USES-LIBRARY
-    </application>
-USES-SDK
-TEST-INSTRUMENTATION
-</manifest> 
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/activity.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/activity.template
deleted file mode 100644
index e91d602..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/activity.template
+++ /dev/null
@@ -1,7 +0,0 @@
-        <activity android:name=".ACTIVITY_NAME"
-                  android:label="APPLICATION_NAME">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-INTENT_FILTERS
-            </intent-filter>
-        </activity>
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_hdpi.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_hdpi.png
deleted file mode 100644
index 8074c4c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_hdpi.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_ldpi.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_ldpi.png
deleted file mode 100644
index 1095584..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_ldpi.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_mdpi.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_mdpi.png
deleted file mode 100644
index a07c69f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon_mdpi.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/java_file.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/java_file.template
deleted file mode 100644
index 173ff96..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/java_file.template
+++ /dev/null
@@ -1,13 +0,0 @@
-package PACKAGE;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class ACTIVITY_NAME extends Activity {
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/launcher_intent_filter.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/launcher_intent_filter.template
deleted file mode 100644
index f5681be..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/launcher_intent_filter.template
+++ /dev/null
@@ -1 +0,0 @@
-                <category android:name="android.intent.category.LAUNCHER" />
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/layout.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/layout.template
deleted file mode 100644
index 5f4c383..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/layout.template
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    >
-<TextView  
-    android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" 
-    android:text="@string/hello"
-    />
-</LinearLayout>
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/preference_intent_filter.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/preference_intent_filter.template
deleted file mode 100644
index 609bb2c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/preference_intent_filter.template
+++ /dev/null
@@ -1 +0,0 @@
-                <category android:name="android.intent.category.PREFERENCE" />
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/string.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/string.template
deleted file mode 100644
index 3a6e4b2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/string.template
+++ /dev/null
@@ -1 +0,0 @@
-    <string name="STRING_NAME">STRING_CONTENT</string>
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/strings.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/strings.template
deleted file mode 100644
index b980ace..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/strings.template
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-STRINGS
-</resources>
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_instrumentation.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_instrumentation.template
deleted file mode 100755
index c282fbc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_instrumentation.template
+++ /dev/null
@@ -1 +0,0 @@
-    <instrumentation android:targetPackage="TEST_TARGET_PCKG" android:name="android.test.InstrumentationTestRunner" />
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_uses-library.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_uses-library.template
deleted file mode 100755
index 28ae7a4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_uses-library.template
+++ /dev/null
@@ -1 +0,0 @@
-    <uses-library android:name="android.test.runner" />
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template
deleted file mode 100644
index 8adae71..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template
+++ /dev/null
@@ -1 +0,0 @@
-    <uses-sdk android:minSdkVersion="MIN_SDK_VERSION" />
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.classpath
deleted file mode 100644
index 280621c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="lib" path="libs/jfreechart-1.0.9.jar"/>
-	<classpathentry kind="lib" path="libs/jcommon-1.0.12.jar"/>
-	<classpathentry kind="lib" path="libs/jfreechart-1.0.9-swt.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.project b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.project
deleted file mode 100644
index 2e9f996..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ddms-plugin</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF
deleted file mode 100644
index 3d70ec0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,26 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Dalvik Debug Monitor Service
-Bundle-SymbolicName: com.android.ide.eclipse.ddms;singleton:=true
-Bundle-Version: 0.9.4.qualifier
-Bundle-Activator: com.android.ide.eclipse.ddms.DdmsPlugin
-Bundle-Vendor: The Android Open Source Project
-Bundle-Localization: plugin
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.runtime,
- org.eclipse.ui.console,
- org.eclipse.core.resources,
- org.eclipse.ui.ide,
- org.eclipse.core.filesystem
-Eclipse-LazyStart: true
-Export-Package: com.android.ddmlib,
- com.android.ddmlib.log,
- com.android.ddmlib.testrunner,
- com.android.ddmuilib,
- com.android.ddmuilib.console,
- com.android.ide.eclipse.ddms,
- com.android.ide.eclipse.ddms.views
-Bundle-ClassPath: libs/jcommon-1.0.12.jar,
- libs/jfreechart-1.0.9.jar,
- libs/jfreechart-1.0.9-swt.jar,
- .
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/MODULE_LICENSE_APACHE2 b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/build.properties b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/build.properties
deleted file mode 100644
index 1c4c896..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/build.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
-               icons/,\
-               plugin.xml,\
-               ., \
-               libs/jcommon-1.0.12.jar,\
-               libs/jfreechart-1.0.9-swt.jar,\
-               libs/jfreechart-1.0.9.jar
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/.gitignore b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/.gitignore
deleted file mode 100644
index f432e88..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-add.png
-backward.png
-clear.png
-d.png
-debug-attach.png
-debug-error.png
-debug-wait.png
-delete.png
-device.png
-down.png
-e.png
-edit.png
-empty.png
-emulator.png
-forward.png
-gc.png
-halt.png
-heap.png
-i.png
-importBug.png
-load.png
-pause.png
-play.png
-pull.png
-push.png
-save.png
-thread.png
-up.png
-v.png
-w.png
-warning.png
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/android.png b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/android.png
deleted file mode 100644
index 3779d4d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/android.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/capture.png b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/capture.png
deleted file mode 100644
index d75e7a9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/capture.png
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/libs/.gitignore b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/libs/.gitignore
deleted file mode 100644
index d392f0e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/libs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.jar
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/plugin.xml b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/plugin.xml
deleted file mode 100644
index 27fadf2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/plugin.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.2"?>
-<plugin>
-   <extension
-         point="org.eclipse.ui.views">
-      <category
-            name="Android"
-            id="com.android.ide.eclipse.ddms.views.category">
-      </category>
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.ddms.views.DeviceView"
-            icon="icons/device.png"
-            id="com.android.ide.eclipse.ddms.views.DeviceView"
-            name="Devices">
-      </view>
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.ddms.views.LogCatView"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.ddms.views.LogCatView"
-            name="LogCat"/>
-      <!-- Disabled for now due to AWT/SWT bridge issue on Leopard.
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.ddms.views.EventLogView"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.ddms.views.EventLogView"
-            name="Event Log"/> -->
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.ddms.views.ThreadView"
-            icon="icons/thread.png"
-            id="com.android.ide.eclipse.ddms.views.ThreadView"
-            name="Threads"/>
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.ddms.views.HeapView"
-            icon="icons/heap.png"
-            id="com.android.ide.eclipse.ddms.views.HeapView"
-            name="Heap"/>
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.ddms.views.FileExplorerView"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.ddms.views.FileExplorerView"
-            name="File Explorer"/>
-      <view
-            allowMultiple="false"
-            category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.ddms.views.EmulatorControlView"
-            icon="icons/emulator.png"
-            id="com.android.ide.eclipse.ddms.views.EmulatorControlView"
-            name="Emulator Control"/>
-   </extension>
-   <extension
-         point="org.eclipse.ui.perspectives">
-      <perspective
-            class="com.android.ide.eclipse.ddms.Perspective"
-            icon="icons/android.png"
-            id="com.android.ide.eclipse.ddms.Perspective"
-            name="DDMS"/>
-   </extension>
-   <extension
-         point="org.eclipse.core.runtime.preferences">
-      <initializer class="com.android.ide.eclipse.ddms.preferences.PreferenceInitializer"/>
-   </extension>
-   <extension
-         point="org.eclipse.ui.perspectiveExtensions">
-      <perspectiveExtension targetID="org.eclipse.jdt.ui.JavaPerspective">
-         <perspectiveShortcut id="com.android.ide.eclipse.ddms.Perspective"/>
-      </perspectiveExtension>
-      <perspectiveExtension targetID="org.eclipse.ui.resourcePerspective">
-         <perspectiveShortcut id="com.android.ide.eclipse.ddms.Perspective"/>
-      </perspectiveExtension>
-      <perspectiveExtension targetID="org.eclipse.debug.ui.DebugPerspective">
-         <perspectiveShortcut id="com.android.ide.eclipse.ddms.Perspective"/>
-         <view id="com.android.ide.eclipse.ddms.views.LogCatView"
-	         relative="org.eclipse.ui.views.ProblemView"
-	         relationship="stack" />
-      </perspectiveExtension>
-   </extension>
-   <extension
-         point="org.eclipse.ui.preferencePages">
-      <page
-            category="com.android.ide.eclipse.preferences.main"
-            class="com.android.ide.eclipse.ddms.preferences.PreferencePage"
-            id="com.android.ide.eclipse.ddms.preferences.PreferencePage"
-            name="DDMS"/>
-      <page
-            category="com.android.ide.eclipse.preferences.main"
-            class="com.android.ide.eclipse.ddms.preferences.LogCatPreferencePage"
-            id="com.android.ide.eclipse.ddms.preferences.LogCatPreferencePage"
-            name="LogCat"/>
-   </extension>
-</plugin>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/.gitignore b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/.gitignore
deleted file mode 100644
index 76d9981..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-ddmlib
-ddmuilib
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/CommonAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/CommonAction.java
deleted file mode 100644
index 30ca4cb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/CommonAction.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms;
-
-import com.android.ddmuilib.actions.ICommonAction;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.resource.ImageDescriptor;
-
-/**
- * Basic action extending the jFace Action class in order to implement
- * ICommonAction.
- */
-public class CommonAction extends Action implements ICommonAction {
-    
-    private Runnable mRunnable;
-
-    public CommonAction() {
-        super();
-    }
-
-    public CommonAction(String text) {
-        super(text);
-    }
-
-    /**
-     * @param text
-     * @param image
-     */
-    public CommonAction(String text, ImageDescriptor image) {
-        super(text, image);
-    }
-
-    /**
-     * @param text
-     * @param style
-     */
-    public CommonAction(String text, int style) {
-        super(text, style);
-    }
-    
-    @Override
-    public void run() {
-        if (mRunnable != null) {
-            mRunnable.run();
-        }
-    }
-    
-    /**
-     * Sets the {@link Runnable}.
-     * @see ICommonAction#setRunnable(Runnable)
-     */
-    public void setRunnable(Runnable runnable) {
-        mRunnable = runnable;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/DdmsPlugin.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/DdmsPlugin.java
deleted file mode 100644
index b59182b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/DdmsPlugin.java
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.DdmConstants;
-import com.android.ddmlib.DdmPreferences;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ddmlib.Log.ILogOutput;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmuilib.DdmUiPreferences;
-import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
-import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
-import com.android.ide.eclipse.ddms.views.DeviceView;
-
-import org.eclipse.core.runtime.Preferences;
-import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
-import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.console.ConsolePlugin;
-import org.eclipse.ui.console.IConsole;
-import org.eclipse.ui.console.MessageConsole;
-import org.eclipse.ui.console.MessageConsoleStream;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Calendar;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public final class DdmsPlugin extends AbstractUIPlugin implements IDeviceChangeListener,
-        IUiSelectionListener {
-
-
-    // The plug-in ID
-    public static final String PLUGIN_ID = "com.android.ide.eclipse.ddms"; // $NON-NLS-1$
-
-    private static final String ADB_LOCATION = PLUGIN_ID + ".adb"; // $NON-NLS-1$
-
-    /** The singleton instance */
-    private static DdmsPlugin sPlugin;
-
-    /** Location of the adb command line executable */
-    private static String sAdbLocation;
-    private static String sToolsFolder;
-    private static String sHprofConverter;
-
-    /**
-     * Debug Launcher for already running apps
-     */
-    private static IDebugLauncher sRunningAppDebugLauncher;
-
-
-    /** Console for DDMS log message */
-    private MessageConsole mDdmsConsole;
-
-    /** Image loader object */
-    private ImageLoader mLoader;
-
-    private IDevice mCurrentDevice;
-    private Client mCurrentClient;
-    private boolean mListeningToUiSelection = false;
-
-    private final ArrayList<ISelectionListener> mListeners = new ArrayList<ISelectionListener>();
-
-    private Color mRed;
-
-    private boolean mDdmlibInitialized;
-
-    /**
-     * Interface to provide debugger launcher for running apps.
-     */
-    public interface IDebugLauncher {
-        public boolean debug(String packageName, int port);
-    }
-
-    /**
-     * Classes which implement this interface provide methods that deals
-     * with {@link IDevice} and {@link Client} selectionchanges.
-     */
-    public interface ISelectionListener {
-
-        /**
-         * Sent when a new {@link Client} is selected.
-         * @param selectedClient The selected client. If null, no clients are selected.
-         */
-        public void selectionChanged(Client selectedClient);
-
-        /**
-         * Sent when a new {@link IDevice} is selected.
-         * @param selectedDevice the selected device. If null, no devices are selected.
-         */
-        public void selectionChanged(IDevice selectedDevice);
-    }
-
-    /**
-     * The constructor
-     */
-    public DdmsPlugin() {
-        sPlugin = this;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-     */
-    @Override
-    public void start(BundleContext context) throws Exception {
-        super.start(context);
-
-        final Display display = getDisplay();
-
-        // get the eclipse store
-        final IPreferenceStore eclipseStore = getPreferenceStore();
-
-        AndroidDebugBridge.addDeviceChangeListener(this);
-
-        DdmUiPreferences.setStore(eclipseStore);
-
-        //DdmUiPreferences.displayCharts();
-
-        // set the consoles.
-        mDdmsConsole = new MessageConsole("DDMS", null); // $NON-NLS-1$
-        ConsolePlugin.getDefault().getConsoleManager().addConsoles(
-                new IConsole[] {
-                    mDdmsConsole
-                });
-
-        final MessageConsoleStream consoleStream = mDdmsConsole.newMessageStream();
-        final MessageConsoleStream errorConsoleStream = mDdmsConsole.newMessageStream();
-        mRed = new Color(display, 0xFF, 0x00, 0x00);
-
-        // because this can be run, in some cases, by a non UI thread, and because
-        // changing the console properties update the UI, we need to make this change
-        // in the UI thread.
-        display.asyncExec(new Runnable() {
-            public void run() {
-                errorConsoleStream.setColor(mRed);
-            }
-        });
-
-        // set up the ddms log to use the ddms console.
-        Log.setLogOutput(new ILogOutput() {
-            public void printLog(LogLevel logLevel, String tag, String message) {
-                if (logLevel.getPriority() >= LogLevel.ERROR.getPriority()) {
-                    printToStream(errorConsoleStream, tag, message);
-                    ConsolePlugin.getDefault().getConsoleManager().showConsoleView(mDdmsConsole);
-                } else {
-                    printToStream(consoleStream, tag, message);
-                }
-            }
-
-            public void printAndPromptLog(final LogLevel logLevel, final String tag,
-                    final String message) {
-                printLog(logLevel, tag, message);
-                // dialog box only run in UI thread..
-                display.asyncExec(new Runnable() {
-                    public void run() {
-                        Shell shell = display.getActiveShell();
-                        if (logLevel == LogLevel.ERROR) {
-                            MessageDialog.openError(shell, tag, message);
-                        } else {
-                            MessageDialog.openWarning(shell, tag, message);
-                        }
-                    }
-                });
-            }
-
-        });
-
-        // create the loader that's able to load the images
-        mLoader = new ImageLoader(this);
-
-        // set the listener for the preference change
-        Preferences prefs = getPluginPreferences();
-        prefs.addPropertyChangeListener(new IPropertyChangeListener() {
-            public void propertyChange(PropertyChangeEvent event) {
-                // get the name of the property that changed.
-                String property = event.getProperty();
-
-                if (PreferenceInitializer.ATTR_DEBUG_PORT_BASE.equals(property)) {
-                    DdmPreferences.setDebugPortBase(
-                            eclipseStore.getInt(PreferenceInitializer.ATTR_DEBUG_PORT_BASE));
-                } else if (PreferenceInitializer.ATTR_SELECTED_DEBUG_PORT.equals(property)) {
-                    DdmPreferences.setSelectedDebugPort(
-                            eclipseStore.getInt(PreferenceInitializer.ATTR_SELECTED_DEBUG_PORT));
-                } else if (PreferenceInitializer.ATTR_THREAD_INTERVAL.equals(property)) {
-                    DdmUiPreferences.setThreadRefreshInterval(
-                            eclipseStore.getInt(PreferenceInitializer.ATTR_THREAD_INTERVAL));
-                } else if (PreferenceInitializer.ATTR_LOG_LEVEL.equals(property)) {
-                    DdmPreferences.setLogLevel(
-                            eclipseStore.getString(PreferenceInitializer.ATTR_LOG_LEVEL));
-                } else if (PreferenceInitializer.ATTR_TIME_OUT.equals(property)) {
-                    DdmPreferences.setTimeOut(
-                            eclipseStore.getInt(PreferenceInitializer.ATTR_TIME_OUT));
-                }
-            }
-        });
-
-        // read the adb location from the prefs to attempt to start it properly without
-        // having to wait for ADT to start
-        final boolean adbValid = setAdbLocation(eclipseStore.getString(ADB_LOCATION));
-
-        // start it in a thread to return from start() asap.
-        new Thread() {
-            @Override
-            public void run() {
-                // init ddmlib if needed
-                getDefault().initDdmlib();
-
-                // create and start the first bridge
-                if (adbValid) {
-                    AndroidDebugBridge.createBridge(sAdbLocation, true /* forceNewBridge */);
-                }
-            }
-        }.start();
-    }
-
-    public static Display getDisplay() {
-        IWorkbench bench = sPlugin.getWorkbench();
-        if (bench != null) {
-            return bench.getDisplay();
-        }
-        return null;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-     */
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        AndroidDebugBridge.removeDeviceChangeListener(this);
-
-        AndroidDebugBridge.terminate();
-
-        mRed.dispose();
-
-        sPlugin = null;
-        super.stop(context);
-    }
-
-    /**
-     * Returns the shared instance
-     *
-     * @return the shared instance
-     */
-    public static DdmsPlugin getDefault() {
-        return sPlugin;
-    }
-
-    /** Return the image loader for the plugin */
-    public static ImageLoader getImageLoader() {
-        if (sPlugin != null) {
-            return sPlugin.mLoader;
-        }
-        return null;
-    }
-
-    public static String getAdb() {
-        return sAdbLocation;
-    }
-
-    public static String getToolsFolder() {
-        return sToolsFolder;
-    }
-
-    public static String getHprofConverter() {
-        return sHprofConverter;
-    }
-
-    /**
-     * Stores the adb location. This returns true if the location is an existing file.
-     */
-    private static boolean setAdbLocation(String adbLocation) {
-        File adb = new File(adbLocation);
-        if (adb.isFile()) {
-            sAdbLocation = adbLocation;
-
-            File toolsFolder = adb.getParentFile();
-            sToolsFolder = toolsFolder.getAbsolutePath();
-
-            File hprofConverter = new File(toolsFolder, DdmConstants.FN_HPROF_CONVERTER);
-            sHprofConverter = hprofConverter.getAbsolutePath();
-
-            File traceview = new File(toolsFolder, DdmConstants.FN_TRACEVIEW);
-            DdmUiPreferences.setTraceviewLocation(traceview.getAbsolutePath());
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Set the location of the adb executable and optionally starts adb
-     * @param adb location of adb
-     * @param startAdb flag to start adb
-     */
-    public static void setAdb(String adb, boolean startAdb) {
-        if (adb != null) {
-            if (setAdbLocation(adb)) {
-                // store the location for future ddms only start.
-                sPlugin.getPreferenceStore().setValue(ADB_LOCATION, sAdbLocation);
-
-                // starts the server in a thread in case this is blocking.
-                if (startAdb) {
-                    new Thread() {
-                        @Override
-                        public void run() {
-                            // init ddmlib if needed
-                            getDefault().initDdmlib();
-
-                            // create and start the bridge
-                            AndroidDebugBridge.createBridge(sAdbLocation,
-                                    false /* forceNewBridge */);
-                        }
-                    }.start();
-                }
-            }
-        }
-    }
-
-    private synchronized void initDdmlib() {
-        if (mDdmlibInitialized == false) {
-            // set the preferences.
-            PreferenceInitializer.setupPreferences();
-
-            // init the lib
-            AndroidDebugBridge.init(true /* debugger support */);
-
-            mDdmlibInitialized = true;
-        }
-    }
-
-    /**
-     * Sets the launcher responsible for connecting the debugger to running applications.
-     * @param launcher The launcher.
-     */
-    public static void setRunningAppDebugLauncher(IDebugLauncher launcher) {
-        sRunningAppDebugLauncher = launcher;
-
-        // if the process view is already running, give it the launcher.
-        // This method could be called from a non ui thread, so we make sure to do that
-        // in the ui thread.
-        Display display = getDisplay();
-        if (display != null && display.isDisposed() == false) {
-            display.asyncExec(new Runnable() {
-                public void run() {
-                    DeviceView dv = DeviceView.getInstance();
-                    if (dv != null) {
-                        dv.setDebugLauncher(sRunningAppDebugLauncher);
-                    }
-                }
-            });
-        }
-    }
-
-    public static IDebugLauncher getRunningAppDebugLauncher() {
-        return sRunningAppDebugLauncher;
-    }
-
-    public synchronized void addSelectionListener(ISelectionListener listener) {
-        mListeners.add(listener);
-
-        // notify the new listener of the current selection
-       listener.selectionChanged(mCurrentDevice);
-       listener.selectionChanged(mCurrentClient);
-    }
-
-    public synchronized void removeSelectionListener(ISelectionListener listener) {
-        mListeners.remove(listener);
-    }
-
-    public synchronized void setListeningState(boolean state) {
-        mListeningToUiSelection = state;
-    }
-
-    /**
-     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceConnected(IDevice)
-     */
-    public void deviceConnected(IDevice device) {
-        // if we are listening to selection coming from the ui, then we do nothing, as
-        // any change in the devices/clients, will be handled by the UI, and we'll receive
-        // selection notification through our implementation of IUiSelectionListener.
-        if (mListeningToUiSelection == false) {
-            if (mCurrentDevice == null) {
-                handleDefaultSelection(device);
-            }
-        }
-    }
-
-    /**
-     * Sent when the a device is disconnected to the {@link AndroidDebugBridge}.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the new device.
-     *
-     * @see IDeviceChangeListener#deviceDisconnected(IDevice)
-     */
-    public void deviceDisconnected(IDevice device) {
-        // if we are listening to selection coming from the ui, then we do nothing, as
-        // any change in the devices/clients, will be handled by the UI, and we'll receive
-        // selection notification through our implementation of IUiSelectionListener.
-        if (mListeningToUiSelection == false) {
-            // test if the disconnected device was the default selection.
-            if (mCurrentDevice == device) {
-                // try to find a new device
-                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
-                if (bridge != null) {
-                    // get the device list
-                    IDevice[] devices = bridge.getDevices();
-
-                    // check if we still have devices
-                    if (devices.length == 0) {
-                        handleDefaultSelection((IDevice)null);
-                    } else {
-                        handleDefaultSelection(devices[0]);
-                    }
-                } else {
-                    handleDefaultSelection((IDevice)null);
-                }
-            }
-        }
-    }
-
-    /**
-     * Sent when a device data changed, or when clients are started/terminated on the device.
-     * <p/>
-     * This is sent from a non UI thread.
-     * @param device the device that was updated.
-     * @param changeMask the mask indicating what changed.
-     *
-     * @see IDeviceChangeListener#deviceChanged(IDevice)
-     */
-    public void deviceChanged(IDevice device, int changeMask) {
-        // if we are listening to selection coming from the ui, then we do nothing, as
-        // any change in the devices/clients, will be handled by the UI, and we'll receive
-        // selection notification through our implementation of IUiSelectionListener.
-        if (mListeningToUiSelection == false) {
-
-            // check if this is our device
-            if (device == mCurrentDevice) {
-                if (mCurrentClient == null) {
-                    handleDefaultSelection(device);
-                } else {
-                    // get the clients and make sure ours is still in there.
-                    Client[] clients = device.getClients();
-                    boolean foundClient = false;
-                    for (Client client : clients) {
-                        if (client == mCurrentClient) {
-                            foundClient = true;
-                            break;
-                        }
-                    }
-
-                    // if we haven't found our client, lets look for a new one
-                    if (foundClient == false) {
-                        mCurrentClient = null;
-                        handleDefaultSelection(device);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Sent when a new {@link IDevice} and {@link Client} are selected.
-     * @param selectedDevice the selected device. If null, no devices are selected.
-     * @param selectedClient The selected client. If null, no clients are selected.
-     */
-    public synchronized void selectionChanged(IDevice selectedDevice, Client selectedClient) {
-        if (mCurrentDevice != selectedDevice) {
-            mCurrentDevice = selectedDevice;
-
-            // notify of the new default device
-            for (ISelectionListener listener : mListeners) {
-                listener.selectionChanged(mCurrentDevice);
-            }
-        }
-
-        if (mCurrentClient != selectedClient) {
-            mCurrentClient = selectedClient;
-
-            // notify of the new default client
-            for (ISelectionListener listener : mListeners) {
-                listener.selectionChanged(mCurrentClient);
-            }
-        }
-    }
-
-    /**
-     * Handles a default selection of a {@link IDevice} and {@link Client}.
-     * @param device the selected device
-     */
-    private void handleDefaultSelection(final IDevice device) {
-        // because the listener expect to receive this from the UI thread, and this is called
-        // from the AndroidDebugBridge notifications, we need to run this in the UI thread.
-        try {
-            Display display = getDisplay();
-
-            display.asyncExec(new Runnable() {
-                public void run() {
-                    // set the new device if different.
-                    boolean newDevice = false;
-                    if (mCurrentDevice != device) {
-                        mCurrentDevice = device;
-                        newDevice = true;
-
-                        // notify of the new default device
-                        for (ISelectionListener listener : mListeners) {
-                            listener.selectionChanged(mCurrentDevice);
-                        }
-                    }
-
-                    if (device != null) {
-                        // if this is a device switch or the same device but we didn't find a valid
-                        // client the last time, we go look for a client to use again.
-                        if (newDevice || mCurrentClient == null) {
-                            // now get the new client
-                            Client[] clients =  device.getClients();
-                            if (clients.length > 0) {
-                                handleDefaultSelection(clients[0]);
-                            } else {
-                                handleDefaultSelection((Client)null);
-                            }
-                        }
-                    } else {
-                        handleDefaultSelection((Client)null);
-                    }
-                }
-            });
-        } catch (SWTException e) {
-            // display is disposed. Do nothing since we're quitting anyway.
-        }
-    }
-
-    private void handleDefaultSelection(Client client) {
-        mCurrentClient = client;
-
-        // notify of the new default client
-        for (ISelectionListener listener : mListeners) {
-            listener.selectionChanged(mCurrentClient);
-        }
-    }
-
-    /**
-     * Prints a message, associated with a project to the specified stream
-     * @param stream The stream to write to
-     * @param tag The tag associated to the message. Can be null
-     * @param message The message to print.
-     */
-    private static synchronized void printToStream(MessageConsoleStream stream, String tag,
-            String message) {
-        String dateTag = getMessageTag(tag);
-
-        stream.print(dateTag);
-        stream.println(message);
-    }
-
-    /**
-     * Creates a string containing the current date/time, and the tag
-     * @param tag The tag associated to the message. Can be null
-     * @return The dateTag
-     */
-    private static String getMessageTag(String tag) {
-        Calendar c = Calendar.getInstance();
-
-        if (tag == null) {
-            return String.format("[%1$tF %1$tT]", c);
-        }
-
-        return String.format("[%1$tF %1$tT - %2$s]", c, tag);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/ImageLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/ImageLoader.java
deleted file mode 100644
index a70405d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/ImageLoader.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms;
-
-import com.android.ddmuilib.IImageLoader;
-
-import org.eclipse.core.runtime.Plugin;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Implementation of the IImageLoader interface for the eclipse plugin.
- */
-public class ImageLoader implements IImageLoader  {
-
-    private URL mBaseUrl;
-
-    public ImageLoader(Plugin plugin) {
-        mBaseUrl = plugin.getBundle().getEntry("/"); // $NON-NLS-1$
-    }
-
-    /**
-     * default method. only need a filename. the 2 interface methods call this one.
-     * @param filename the filename of the image to load. The filename is searched for under /icons.
-     * @return
-     */
-    public ImageDescriptor loadDescriptor(String filename) {
-        try {
-            URL newUrl = new URL(mBaseUrl, "/icons/" + filename); // $NON-NLS-1$
-            return ImageDescriptor.createFromURL(newUrl);
-        } catch (MalformedURLException e) {
-            // we'll just return null;
-        }
-        return null;
-    }
-
-    public ImageDescriptor loadDescriptor(String filename, Display display) {
-        return loadDescriptor(filename);
-    }
-
-
-    public Image loadImage(String filename, Display display) {
-        ImageDescriptor descriptor = loadDescriptor(filename);
-        if (descriptor !=null) {
-            return descriptor.createImage();
-        }
-        return null;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/Perspective.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/Perspective.java
deleted file mode 100644
index 4c01e9b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/Perspective.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms;
-
-import com.android.ide.eclipse.ddms.views.DeviceView;
-import com.android.ide.eclipse.ddms.views.EmulatorControlView;
-import com.android.ide.eclipse.ddms.views.FileExplorerView;
-import com.android.ide.eclipse.ddms.views.HeapView;
-import com.android.ide.eclipse.ddms.views.LogCatView;
-import com.android.ide.eclipse.ddms.views.ThreadView;
-
-import org.eclipse.ui.IFolderLayout;
-import org.eclipse.ui.IPageLayout;
-import org.eclipse.ui.IPerspectiveFactory;
-
-public class Perspective implements IPerspectiveFactory {
-
-    public void createInitialLayout(IPageLayout layout) {
-        // create a default layout that looks like the stand alone DDMS.
-
-        // no editor window
-        layout.setEditorAreaVisible(false);
-
-        String editorArea = layout.getEditorArea();
-        IFolderLayout folder;
-
-        folder = layout.createFolder("logcat", IPageLayout.BOTTOM, 0.8f, //$NON-NLS-1$
-                editorArea);
-        folder.addPlaceholder(LogCatView.ID + ":*"); //$NON-NLS-1$
-        folder.addView(LogCatView.ID);
-
-        folder = layout.createFolder("devices", IPageLayout.LEFT, 0.3f, //$NON-NLS-1$
-                editorArea);
-        folder.addPlaceholder(DeviceView.ID + ":*"); //$NON-NLS-1$
-        folder.addView(DeviceView.ID);
-
-        folder = layout.createFolder("emulator", IPageLayout.BOTTOM, 0.5f, //$NON-NLS-1$
-                "devices");
-        folder.addPlaceholder(EmulatorControlView.ID + ":*"); //$NON-NLS-1$
-        folder.addView(EmulatorControlView.ID);
-
-        folder = layout.createFolder("ddms-detail", IPageLayout.RIGHT, 0.5f, //$NON-NLS-1$
-                editorArea);
-        folder.addPlaceholder(ThreadView.ID + ":*"); //$NON-NLS-1$
-        folder.addView(ThreadView.ID);
-        folder.addView(HeapView.ID);
-        folder.addView(FileExplorerView.ID);
-
-        layout.addPerspectiveShortcut("org.eclipse.ui.resourcePerspective"); //$NON-NLS-1$
-        layout.addPerspectiveShortcut("org.eclipse.debug.ui.DebugPerspective"); //$NON-NLS-1$
-        layout.addPerspectiveShortcut("org.eclipse.jdt.ui.JavaPerspective"); //$NON-NLS-1$
-
-        layout.addShowViewShortcut(DeviceView.ID);
-        layout.addShowViewShortcut(FileExplorerView.ID);
-        layout.addShowViewShortcut(HeapView.ID);
-        layout.addShowViewShortcut(LogCatView.ID);
-        layout.addShowViewShortcut(ThreadView.ID);
-
-        layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
-        layout.addShowViewShortcut(IPageLayout.ID_BOOKMARKS);
-        layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
-        layout.addShowViewShortcut(IPageLayout.ID_PROP_SHEET);
-        layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
-        layout.addShowViewShortcut(IPageLayout.ID_PROGRESS_VIEW);
-        layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java
deleted file mode 100644
index 909207d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.preferences;
-
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.views.LogCatView;
-
-import org.eclipse.core.runtime.Preferences;
-import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
-import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
-import org.eclipse.jface.preference.FieldEditorPreferencePage;
-import org.eclipse.jface.preference.FontFieldEditor;
-import org.eclipse.swt.SWTError;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-/**
- * Preference Pane for LogCat.
- */
-public class LogCatPreferencePage extends FieldEditorPreferencePage implements
-        IWorkbenchPreferencePage {
-
-    public LogCatPreferencePage() {
-        super(GRID);
-        setPreferenceStore(DdmsPlugin.getDefault().getPreferenceStore());
-    }
-
-    @Override
-    protected void createFieldEditors() {
-        FontFieldEditor ffe = new FontFieldEditor(PreferenceInitializer.ATTR_LOGCAT_FONT,
-                "Display Font:", getFieldEditorParent());
-        addField(ffe);
-
-        Preferences prefs = DdmsPlugin.getDefault().getPluginPreferences();
-        prefs.addPropertyChangeListener(new IPropertyChangeListener() {
-            public void propertyChange(PropertyChangeEvent event) {
-                // get the name of the property that changed.
-                String property = event.getProperty();
-
-                if (PreferenceInitializer.ATTR_LOGCAT_FONT.equals(property)) {
-                    try {
-                        FontData fdat = new FontData((String)event.getNewValue());
-                        LogCatView.setFont(new Font(getFieldEditorParent().getDisplay(), fdat));
-                    } catch (IllegalArgumentException e) {
-                        // Looks like the data from the store is not valid.
-                        // We do nothing (default font will be used).
-                    } catch (SWTError e2) {
-                        // Looks like the Font() constructor failed.
-                        // We do nothing in this case, the logcat view will use the default font.
-                    }
-                }
-            }
-        });
-    }
-
-    public void init(IWorkbench workbench) {
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java
deleted file mode 100644
index 751bc4f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.preferences;
-
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.views.DeviceView.HProfHandler;
-import com.android.ddmlib.DdmPreferences;
-import com.android.ddmuilib.DdmUiPreferences;
-
-import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.FontData;
-
-/**
- * Class used to initialize default preference values.
- */
-public class PreferenceInitializer extends AbstractPreferenceInitializer {
-
-    public final static String ATTR_LOG_LEVEL =
-        DdmsPlugin.PLUGIN_ID + ".logLevel"; //$NON-NLS-1$
-
-    public final static String ATTR_DEBUG_PORT_BASE =
-        DdmsPlugin.PLUGIN_ID + ".adbDebugBasePort"; //$NON-NLS-1$
-
-    public final static String ATTR_SELECTED_DEBUG_PORT =
-        DdmsPlugin.PLUGIN_ID + ".debugSelectedPort"; //$NON-NLS-1$
-
-    public final static String ATTR_DEFAULT_THREAD_UPDATE =
-        DdmsPlugin.PLUGIN_ID + ".defaultThreadUpdateEnabled"; //$NON-NLS-1$
-
-    public final static String ATTR_DEFAULT_HEAP_UPDATE =
-        DdmsPlugin.PLUGIN_ID + ".defaultHeapUpdateEnabled"; //$NON-NLS-1$
-
-    public final static String ATTR_THREAD_INTERVAL =
-        DdmsPlugin.PLUGIN_ID + ".threadStatusInterval"; //$NON-NLS-1$
-
-    public final static String ATTR_IMAGE_SAVE_DIR =
-        DdmsPlugin.PLUGIN_ID + ".imageSaveDir"; //$NON-NLS-1$
-
-    public final static String ATTR_LAST_IMAGE_SAVE_DIR =
-        DdmsPlugin.PLUGIN_ID + ".lastImageSaveDir"; //$NON-NLS-1$
-
-    public final static String ATTR_LOGCAT_FONT =
-        DdmsPlugin.PLUGIN_ID + ".logcatFont"; //$NON-NLS-1$
-
-    public final static String ATTR_HPROF_ACTION =
-        DdmsPlugin.PLUGIN_ID + ".hprofAction"; //$NON-NLS-1$
-
-    public final static String ATTR_TIME_OUT =
-        DdmsPlugin.PLUGIN_ID + ".timeOut"; //$NON-NLS-1$
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer
-     * #initializeDefaultPreferences()
-     */
-    @Override
-    public void initializeDefaultPreferences() {
-        IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
-
-        store.setDefault(ATTR_DEBUG_PORT_BASE, DdmPreferences.DEFAULT_DEBUG_PORT_BASE);
-
-        store.setDefault(ATTR_SELECTED_DEBUG_PORT, DdmPreferences.DEFAULT_SELECTED_DEBUG_PORT);
-
-        store.setDefault(ATTR_DEFAULT_THREAD_UPDATE, DdmPreferences.DEFAULT_INITIAL_THREAD_UPDATE);
-        store.setDefault(ATTR_DEFAULT_HEAP_UPDATE,
-                DdmPreferences.DEFAULT_INITIAL_HEAP_UPDATE);
-
-        store.setDefault(ATTR_THREAD_INTERVAL, DdmUiPreferences.DEFAULT_THREAD_REFRESH_INTERVAL);
-
-        String homeDir = System.getProperty("user.home"); //$NON-NLS-1$
-        store.setDefault(ATTR_IMAGE_SAVE_DIR, homeDir);
-
-        store.setDefault(ATTR_LOG_LEVEL, DdmPreferences.DEFAULT_LOG_LEVEL.getStringValue());
-
-        store.setDefault(ATTR_LOGCAT_FONT,
-                new FontData("Courier", 10, SWT.NORMAL).toString()); //$NON-NLS-1$
-
-        store.setDefault(ATTR_HPROF_ACTION, HProfHandler.ACTION_OPEN);
-
-        store.setDefault(ATTR_TIME_OUT, DdmPreferences.DEFAULT_TIMEOUT);
-    }
-
-    /**
-     * Initializes the preferences of ddmlib and ddmuilib with values from the eclipse store.
-     */
-    public synchronized static void setupPreferences() {
-        IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
-
-        DdmPreferences.setDebugPortBase(store.getInt(ATTR_DEBUG_PORT_BASE));
-        DdmPreferences.setSelectedDebugPort(store.getInt(ATTR_SELECTED_DEBUG_PORT));
-        DdmPreferences.setLogLevel(store.getString(ATTR_LOG_LEVEL));
-        DdmPreferences.setInitialThreadUpdate(store.getBoolean(ATTR_DEFAULT_THREAD_UPDATE));
-        DdmPreferences.setInitialHeapUpdate(store.getBoolean(ATTR_DEFAULT_HEAP_UPDATE));
-        DdmUiPreferences.setThreadRefreshInterval(store.getInt(ATTR_THREAD_INTERVAL));
-        DdmPreferences.setTimeOut(store.getInt(ATTR_TIME_OUT));
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferencePage.java
deleted file mode 100644
index fb852f5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferencePage.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.preferences;
-
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.views.DeviceView.HProfHandler;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmuilib.PortFieldEditor;
-
-import org.eclipse.jface.preference.BooleanFieldEditor;
-import org.eclipse.jface.preference.ComboFieldEditor;
-import org.eclipse.jface.preference.FieldEditorPreferencePage;
-import org.eclipse.jface.preference.IntegerFieldEditor;
-import org.eclipse.jface.preference.RadioGroupFieldEditor;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-public class PreferencePage extends FieldEditorPreferencePage implements
-        IWorkbenchPreferencePage {
-
-    public PreferencePage() {
-        super(GRID);
-        setPreferenceStore(DdmsPlugin.getDefault().getPreferenceStore());
-    }
-
-    /**
-     * Creates the field editors. Field editors are abstractions of the common
-     * GUI blocks needed to manipulate various types of preferences. Each field
-     * editor knows how to save and restore itself.
-     */
-    @Override
-    public void createFieldEditors() {
-        IntegerFieldEditor ife;
-
-        ife = new PortFieldEditor(PreferenceInitializer.ATTR_DEBUG_PORT_BASE,
-            "Base local debugger port:", getFieldEditorParent());
-        addField(ife);
-
-        BooleanFieldEditor bfe;
-
-        bfe = new BooleanFieldEditor(PreferenceInitializer.ATTR_DEFAULT_THREAD_UPDATE,
-            "Thread updates enabled by default", getFieldEditorParent());
-        addField(bfe);
-
-        bfe = new BooleanFieldEditor(PreferenceInitializer.ATTR_DEFAULT_HEAP_UPDATE,
-            "Heap updates enabled by default", getFieldEditorParent());
-        addField(bfe);
-
-        ife = new IntegerFieldEditor(PreferenceInitializer.ATTR_THREAD_INTERVAL,
-            "Thread status refresh interval (seconds):", getFieldEditorParent());
-        ife.setValidRange(1, 60);
-        addField(ife);
-
-        ComboFieldEditor cfe = new ComboFieldEditor(PreferenceInitializer.ATTR_HPROF_ACTION,
-                "HPROF Action:", new String[][] {
-                    { "Save to disk", HProfHandler.ACTION_SAVE },
-                    { "Open in Eclipse", HProfHandler.ACTION_OPEN },
-                }, getFieldEditorParent());
-        addField(cfe);
-
-        ife = new IntegerFieldEditor(PreferenceInitializer.ATTR_TIME_OUT,
-                "ADB connection time out (ms):", getFieldEditorParent());
-            addField(ife);
-
-        RadioGroupFieldEditor rgfe = new RadioGroupFieldEditor(PreferenceInitializer.ATTR_LOG_LEVEL,
-                "Logging Level", 1, new String[][] {
-                    { "Verbose", LogLevel.VERBOSE.getStringValue() },
-                    { "Debug", LogLevel.DEBUG.getStringValue() },
-                    { "Info", LogLevel.INFO.getStringValue() },
-                    { "Warning", LogLevel.WARN.getStringValue() },
-                    { "Error", LogLevel.ERROR.getStringValue() },
-                    { "Assert", LogLevel.ASSERT.getStringValue() }
-                    },
-                getFieldEditorParent(), true);
-        addField(rgfe);
-    }
-
-    public void init(IWorkbench workbench) {
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
deleted file mode 100644
index 71efb50..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.ClientData.IHprofDumpHandler;
-import com.android.ddmlib.ClientData.MethodProfilingStatus;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ddmuilib.handler.BaseFileHandler;
-import com.android.ddmuilib.handler.MethodProfilingHandler;
-import com.android.ddmuilib.DevicePanel;
-import com.android.ddmuilib.ScreenShotDialog;
-import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.DdmsPlugin.IDebugLauncher;
-import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
-
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.filesystem.IFileStore;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.ide.IDE;
-import org.eclipse.ui.part.ViewPart;
-
-import java.io.File;
-import java.io.IOException;
-
-public class DeviceView extends ViewPart implements IUiSelectionListener, IClientChangeListener {
-
-    private final static boolean USE_SELECTED_DEBUG_PORT = true;
-
-    public static final String ID =
-        "com.android.ide.eclipse.ddms.views.DeviceView"; //$NON-NLS-1$
-
-    private static DeviceView sThis;
-
-    private Shell mParentShell;
-    private DevicePanel mDeviceList;
-
-    private Action mResetAdbAction;
-    private Action mCaptureAction;
-    private Action mUpdateThreadAction;
-    private Action mUpdateHeapAction;
-    private Action mGcAction;
-    private Action mKillAppAction;
-    private Action mDebugAction;
-    private Action mHprofAction;
-    private Action mTracingAction;
-    private IDebugLauncher mDebugLauncher;
-
-    private ImageDescriptor mTracingStartImage;
-    private ImageDescriptor mTracingStopImage;
-
-    public class HProfHandler extends BaseFileHandler implements IHprofDumpHandler {
-        public final static String ACTION_SAVE ="hprof.save"; //$NON-NLS-1$
-        public final static String ACTION_OPEN = "hprof.open"; //$NON-NLS-1$
-
-        public final static String DOT_HPROF = ".hprof"; //$NON-NLS-1$
-
-        HProfHandler(Shell parentShell) {
-            super(parentShell);
-        }
-
-        public void onFailure(final Client client) {
-            mParentShell.getDisplay().asyncExec(new Runnable() {
-                public void run() {
-                    try {
-                        displayError("Unable to create HPROF file for application '%1$s'.\n" +
-                                "Check logcat for more information.",
-                                client.getClientData().getClientDescription());
-                    } finally {
-                        // this will make sure the dump hprof button is re-enabled for the
-                        // current selection. as the client is finished dumping an hprof file
-                        doSelectionChanged(mDeviceList.getSelectedClient());
-                    }
-                }
-            });
-        }
-
-        public void onSuccess(final String remoteFilePath, final Client client) {
-            mParentShell.getDisplay().asyncExec(new Runnable() {
-                public void run() {
-                    final IDevice device = client.getDevice();
-                    try {
-                        // get the sync service to pull the HPROF file
-                        final SyncService sync = client.getDevice().getSyncService();
-                        if (sync != null) {
-                            // get from the preference what action to take
-                            IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
-                            String value = store.getString(PreferenceInitializer.ATTR_HPROF_ACTION);
-
-                            SyncResult result = null;
-                            if (ACTION_OPEN.equals(value)) {
-                                File temp = File.createTempFile("android", DOT_HPROF); //$NON-NLS-1$
-                                String tempPath = temp.getAbsolutePath();
-                                result = pull(sync, tempPath, remoteFilePath);
-                                if (result != null && result.getCode() == SyncService.RESULT_OK) {
-                                    open(tempPath);
-                                }
-                            } else {
-                                // default action is ACTION_SAVE
-                                result = promptAndPull(sync,
-                                        client.getClientData().getClientDescription() + DOT_HPROF,
-                                        remoteFilePath, "Save HPROF file");
-
-                            }
-
-                            if (result != null && result.getCode() != SyncService.RESULT_OK) {
-                                displayError(
-                                        "Unable to download HPROF file from device '%1$s'.\n\n%2$s",
-                                        device.getSerialNumber(), result.getMessage());
-                            }
-                        } else {
-                            displayError("Unable to download HPROF file from device '%1$s'.",
-                                    device.getSerialNumber());
-                        }
-                    } catch (Exception e) {
-                        displayError("Unable to download HPROF file from device '%1$s'.",
-                                device.getSerialNumber());
-
-                    } finally {
-                        // this will make sure the dump hprof button is re-enabled for the
-                        // current selection. as the client is finished dumping an hprof file
-                        doSelectionChanged(mDeviceList.getSelectedClient());
-                    }
-                }
-            });
-        }
-
-        private void open(String path) throws IOException, InterruptedException, PartInitException {
-            // make a temp file to convert the hprof into something
-            // readable by normal tools
-            File temp = File.createTempFile("android", DOT_HPROF);
-            String tempPath = temp.getAbsolutePath();
-
-            String[] command = new String[3];
-            command[0] = DdmsPlugin.getHprofConverter();
-            command[1] = path;
-            command[2] = tempPath;
-
-            Process p = Runtime.getRuntime().exec(command);
-            p.waitFor();
-
-            IFileStore fileStore =  EFS.getLocalFileSystem().getStore(new Path(tempPath));
-            if (!fileStore.fetchInfo().isDirectory() && fileStore.fetchInfo().exists()) {
-                IDE.openEditorOnFileStore(
-                        getSite().getWorkbenchWindow().getActivePage(),
-                        fileStore);
-            }
-        }
-
-        private void displayError(String format, Object... args) {
-            MessageDialog.openError(mParentShell, "HPROF Error",
-                    String.format(format, args));
-        }
-    }
-
-
-    public DeviceView() {
-        // the view is declared with allowMultiple="false" so we
-        // can safely do this.
-        sThis = this;
-    }
-
-    public static DeviceView getInstance() {
-        return sThis;
-    }
-
-    /**
-     * Sets the {@link IDebugLauncher}.
-     * @param debugLauncher
-     */
-    public void setDebugLauncher(DdmsPlugin.IDebugLauncher debugLauncher) {
-        mDebugLauncher = debugLauncher;
-        if (mDebugAction != null && mDeviceList != null) {
-            Client currentClient = mDeviceList.getSelectedClient();
-            if (currentClient != null) {
-                mDebugAction.setEnabled(true);
-            }
-        }
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mParentShell = parent.getShell();
-        ClientData.setHprofDumpHandler(new HProfHandler(mParentShell));
-        AndroidDebugBridge.addClientChangeListener(this);
-        ClientData.setMethodProfilingHandler(new MethodProfilingHandler(mParentShell));
-
-        mDeviceList = new DevicePanel(DdmsPlugin.getImageLoader(), USE_SELECTED_DEBUG_PORT);
-        mDeviceList.createPanel(parent);
-        mDeviceList.addSelectionListener(this);
-
-        DdmsPlugin plugin = DdmsPlugin.getDefault();
-        mDeviceList.addSelectionListener(plugin);
-        plugin.setListeningState(true);
-
-        mCaptureAction = new Action("Screen Capture") {
-            @Override
-            public void run() {
-                ScreenShotDialog dlg = new ScreenShotDialog(
-                        DdmsPlugin.getDisplay().getActiveShell());
-                dlg.open(mDeviceList.getSelectedDevice());
-            }
-        };
-        mCaptureAction.setToolTipText("Screen Capture");
-        mCaptureAction.setImageDescriptor(
-                DdmsPlugin.getImageLoader().loadDescriptor("capture.png")); //$NON-NLS-1$
-
-        mResetAdbAction = new Action("Reset adb") {
-            @Override
-            public void run() {
-                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
-                if (bridge != null) {
-                    if (bridge.restart() == false) {
-                        // get the current Display
-                        final Display display = DdmsPlugin.getDisplay();
-
-                        // dialog box only run in ui thread..
-                        display.asyncExec(new Runnable() {
-                            public void run() {
-                                Shell shell = display.getActiveShell();
-                                MessageDialog.openError(shell, "Adb Error",
-                                        "Adb failed to restart!\n\nMake sure the plugin is properly configured.");
-                            }
-                        });
-                    }
-                }
-            }
-        };
-        mResetAdbAction.setToolTipText("Reset the adb host daemon");
-        mResetAdbAction.setImageDescriptor(PlatformUI.getWorkbench()
-                .getSharedImages().getImageDescriptor(
-                        ISharedImages.IMG_OBJS_WARN_TSK));
-
-        mKillAppAction = new Action() {
-            @Override
-            public void run() {
-                mDeviceList.killSelectedClient();
-            }
-        };
-
-        mKillAppAction.setText("Stop Process");
-        mKillAppAction.setToolTipText("Stop Process");
-        mKillAppAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor(DevicePanel.ICON_HALT));
-
-        mGcAction = new Action() {
-            @Override
-            public void run() {
-                mDeviceList.forceGcOnSelectedClient();
-            }
-        };
-
-        mGcAction.setText("Cause GC");
-        mGcAction.setToolTipText("Cause GC");
-        mGcAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor(DevicePanel.ICON_GC));
-
-        mHprofAction = new Action() {
-            @Override
-            public void run() {
-                mDeviceList.dumpHprof();
-                doSelectionChanged(mDeviceList.getSelectedClient());
-            }
-        };
-        mHprofAction.setText("Dump HPROF file");
-        mHprofAction.setToolTipText("Dump HPROF file");
-        mHprofAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor(DevicePanel.ICON_HPROF));
-
-        mUpdateHeapAction = new Action("Update Heap", IAction.AS_CHECK_BOX) {
-            @Override
-            public void run() {
-                boolean enable = mUpdateHeapAction.isChecked();
-                mDeviceList.setEnabledHeapOnSelectedClient(enable);
-            }
-        };
-        mUpdateHeapAction.setToolTipText("Update Heap");
-        mUpdateHeapAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor(DevicePanel.ICON_HEAP));
-
-        mUpdateThreadAction = new Action("Update Threads", IAction.AS_CHECK_BOX) {
-            @Override
-            public void run() {
-                boolean enable = mUpdateThreadAction.isChecked();
-                mDeviceList.setEnabledThreadOnSelectedClient(enable);
-            }
-        };
-        mUpdateThreadAction.setToolTipText("Update Threads");
-        mUpdateThreadAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor(DevicePanel.ICON_THREAD));
-
-        mTracingAction = new Action() {
-            @Override
-            public void run() {
-                mDeviceList.toggleMethodProfiling();
-            }
-        };
-        mTracingAction.setText("Start Method Profiling");
-        mTracingAction.setToolTipText("Start Method Profiling");
-        mTracingStartImage = DdmsPlugin.getImageLoader().loadDescriptor(
-                DevicePanel.ICON_TRACING_START);
-        mTracingStopImage = DdmsPlugin.getImageLoader().loadDescriptor(
-                DevicePanel.ICON_TRACING_STOP);
-        mTracingAction.setImageDescriptor(mTracingStartImage);
-
-        // check if there's already a debug launcher set up in the plugin class
-        mDebugLauncher = DdmsPlugin.getRunningAppDebugLauncher();
-
-        mDebugAction = new Action("Debug Process") {
-            @Override
-            public void run() {
-                if (mDebugLauncher != null) {
-                    Client currentClient = mDeviceList.getSelectedClient();
-                    if (currentClient != null) {
-                        ClientData clientData = currentClient.getClientData();
-
-                        // make sure the client can be debugged
-                        switch (clientData.getDebuggerConnectionStatus()) {
-                            case ERROR: {
-                                Display display = DdmsPlugin.getDisplay();
-                                Shell shell = display.getActiveShell();
-                                MessageDialog.openError(shell, "Process Debug",
-                                        "The process debug port is already in use!");
-                                return;
-                            }
-                            case ATTACHED: {
-                                Display display = DdmsPlugin.getDisplay();
-                                Shell shell = display.getActiveShell();
-                                MessageDialog.openError(shell, "Process Debug",
-                                        "The process is already being debugged!");
-                                return;
-                            }
-                        }
-
-                        // get the name of the client
-                        String packageName = clientData.getClientDescription();
-                        if (packageName != null) {
-                            if (mDebugLauncher.debug(packageName,
-                                    currentClient.getDebuggerListenPort()) == false) {
-
-                                // if we get to this point, then we failed to find a project
-                                // that matched the application to debug
-                                Display display = DdmsPlugin.getDisplay();
-                                Shell shell = display.getActiveShell();
-                                MessageDialog.openError(shell, "Process Debug",
-                                        String.format(
-                                                "No opened project found for %1$s. Debug session failed!",
-                                                packageName));
-                            }
-                        }
-                    }
-                }
-            }
-        };
-        mDebugAction.setToolTipText("Debug the selected process, provided its source project is present and opened in the workspace.");
-        mDebugAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor("debug-attach.png")); //$NON-NLS-1$
-        if (mDebugLauncher == null) {
-            mDebugAction.setEnabled(false);
-        }
-
-        placeActions();
-    }
-
-    @Override
-    public void setFocus() {
-        mDeviceList.setFocus();
-    }
-
-    /**
-     * Sent when a new {@link IDevice} and {@link Client} are selected.
-     * @param selectedDevice the selected device. If null, no devices are selected.
-     * @param selectedClient The selected client. If null, no clients are selected.
-     */
-    public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
-        // update the buttons
-        doSelectionChanged(selectedClient);
-        doSelectionChanged(selectedDevice);
-    }
-
-    private void doSelectionChanged(Client selectedClient) {
-        // update the buttons
-        if (selectedClient != null) {
-            if (USE_SELECTED_DEBUG_PORT) {
-                // set the client as the debug client
-                selectedClient.setAsSelectedClient();
-            }
-
-            mDebugAction.setEnabled(mDebugLauncher != null);
-            mKillAppAction.setEnabled(true);
-            mGcAction.setEnabled(true);
-
-            mUpdateHeapAction.setEnabled(true);
-            mUpdateHeapAction.setChecked(selectedClient.isHeapUpdateEnabled());
-
-            mUpdateThreadAction.setEnabled(true);
-            mUpdateThreadAction.setChecked(selectedClient.isThreadUpdateEnabled());
-
-            ClientData data = selectedClient.getClientData();
-
-            if (data.hasFeature(ClientData.FEATURE_HPROF)) {
-                mHprofAction.setEnabled(data.hasPendingHprofDump() == false);
-                mHprofAction.setToolTipText("Dump HPROF file");
-            } else {
-                mHprofAction.setEnabled(false);
-                mHprofAction.setToolTipText("Dump HPROF file (not supported by this VM)");
-            }
-
-            if (data.hasFeature(ClientData.FEATURE_PROFILING)) {
-                mTracingAction.setEnabled(true);
-                if (data.getMethodProfilingStatus() == MethodProfilingStatus.ON) {
-                    mTracingAction.setToolTipText("Stop Method Profiling");
-                    mTracingAction.setText("Stop Method Profiling");
-                    mTracingAction.setImageDescriptor(mTracingStopImage);
-                } else {
-                    mTracingAction.setToolTipText("Start Method Profiling");
-                    mTracingAction.setImageDescriptor(mTracingStartImage);
-                    mTracingAction.setText("Start Method Profiling");
-                }
-            } else {
-                mTracingAction.setEnabled(false);
-                mTracingAction.setImageDescriptor(mTracingStartImage);
-                mTracingAction.setToolTipText("Start Method Profiling (not supported by this VM)");
-                mTracingAction.setText("Start Method Profiling");
-            }
-        } else {
-            if (USE_SELECTED_DEBUG_PORT) {
-                // set the client as the debug client
-                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
-                if (bridge != null) {
-                    bridge.setSelectedClient(null);
-                }
-            }
-
-            mDebugAction.setEnabled(false);
-            mKillAppAction.setEnabled(false);
-            mGcAction.setEnabled(false);
-            mUpdateHeapAction.setChecked(false);
-            mUpdateHeapAction.setEnabled(false);
-            mUpdateThreadAction.setEnabled(false);
-            mUpdateThreadAction.setChecked(false);
-            mHprofAction.setEnabled(false);
-
-            mHprofAction.setEnabled(false);
-            mHprofAction.setToolTipText("Dump HPROF file");
-
-            mTracingAction.setEnabled(false);
-            mTracingAction.setImageDescriptor(mTracingStartImage);
-            mTracingAction.setToolTipText("Start Method Profiling");
-            mTracingAction.setText("Start Method Profiling");
-        }
-    }
-
-    private void doSelectionChanged(IDevice selectedDevice) {
-        mCaptureAction.setEnabled(selectedDevice != null);
-    }
-
-    /**
-     * Place the actions in the ui.
-     */
-    private final void placeActions() {
-        IActionBars actionBars = getViewSite().getActionBars();
-
-        // first in the menu
-        IMenuManager menuManager = actionBars.getMenuManager();
-        menuManager.removeAll();
-        menuManager.add(mDebugAction);
-        menuManager.add(new Separator());
-        menuManager.add(mUpdateHeapAction);
-        menuManager.add(mHprofAction);
-        menuManager.add(mGcAction);
-        menuManager.add(new Separator());
-        menuManager.add(mUpdateThreadAction);
-        menuManager.add(mTracingAction);
-        menuManager.add(new Separator());
-        menuManager.add(mKillAppAction);
-        menuManager.add(new Separator());
-        menuManager.add(mCaptureAction);
-        menuManager.add(new Separator());
-        menuManager.add(mResetAdbAction);
-
-        // and then in the toolbar
-        IToolBarManager toolBarManager = actionBars.getToolBarManager();
-        toolBarManager.removeAll();
-        toolBarManager.add(mDebugAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(mUpdateHeapAction);
-        toolBarManager.add(mHprofAction);
-        toolBarManager.add(mGcAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(mUpdateThreadAction);
-        toolBarManager.add(mTracingAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(mKillAppAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(mCaptureAction);
-    }
-
-    public void clientChanged(final Client client, int changeMask) {
-        if ((changeMask & Client.CHANGE_METHOD_PROFILING_STATUS) ==
-                Client.CHANGE_METHOD_PROFILING_STATUS) {
-            if (mDeviceList.getSelectedClient() == client) {
-                mParentShell.getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        // force refresh of the button enabled state.
-                        doSelectionChanged(client);
-                    }
-                });
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java
deleted file mode 100644
index ca9a691..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmuilib.EmulatorControlPanel;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-
-import org.eclipse.swt.widgets.Composite;
-
-public class EmulatorControlView extends SelectionDependentViewPart {
-
-    public static final String ID =
-        "com.android.ide.eclipse.ddms.views.EmulatorControlView"; //$NON-NLS-1$
-
-    private EmulatorControlPanel mPanel;
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mPanel = new EmulatorControlPanel(DdmsPlugin.getImageLoader());
-        mPanel.createPanel(parent);
-        setSelectionDependentPanel(mPanel);
-    }
-
-    @Override
-    public void setFocus() {
-        mPanel.setFocus();
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java
deleted file mode 100644
index 3a74e42..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmuilib.log.event.EventLogPanel;
-import com.android.ide.eclipse.ddms.CommonAction;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.ImageLoader;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.IActionBars;
-
-public class EventLogView extends SelectionDependentViewPart {
-    
-    private EventLogPanel mLogPanel;
-
-    @Override
-    public void createPartControl(Composite parent) {
-        ImageLoader loader = DdmsPlugin.getImageLoader();
-
-        // create the external actions
-        CommonAction optionsAction = new CommonAction("Options...");
-        optionsAction.setToolTipText("Opens the options panel");
-        optionsAction.setImageDescriptor(loader
-                .loadDescriptor("edit.png")); // $NON-NLS-1$
-
-        CommonAction clearLogAction = new CommonAction("Clear Log");
-        clearLogAction.setToolTipText("Clears the event log");
-        clearLogAction.setImageDescriptor(loader
-                .loadDescriptor("clear.png")); // $NON-NLS-1$
-
-        CommonAction saveAction = new CommonAction("Save Log");
-        saveAction.setToolTipText("Saves the event log");
-        saveAction.setImageDescriptor(loader
-                .loadDescriptor("save.png")); // $NON-NLS-1$
-
-        CommonAction loadAction = new CommonAction("Load Log");
-        loadAction.setToolTipText("Loads an event log");
-        loadAction.setImageDescriptor(loader
-                .loadDescriptor("load.png")); // $NON-NLS-1$
-
-        CommonAction importBugAction = new CommonAction("Import Bug Report Log");
-        importBugAction.setToolTipText("Imports a bug report.");
-        importBugAction.setImageDescriptor(loader
-                .loadDescriptor("importBug.png")); // $NON-NLS-1$
-
-        placeActions(optionsAction, clearLogAction, saveAction, loadAction, importBugAction);
-
-        mLogPanel = new EventLogPanel(DdmsPlugin.getImageLoader());
-        mLogPanel.setActions(optionsAction, clearLogAction, saveAction, loadAction, importBugAction);
-        mLogPanel.createPanel(parent);
-        setSelectionDependentPanel(mLogPanel);
-    }
-
-    @Override
-    public void setFocus() {
-        mLogPanel.setFocus();
-    }
-    
-    @Override
-    public void dispose() {
-        if (mLogPanel != null) {
-            mLogPanel.stopEventLog(true);
-        }
-    }
-    
-    /**
-     * Places the actions in the toolbar and in the menu.
-     * @param importBugAction 
-     */
-    private void placeActions(IAction optionAction, IAction clearAction, IAction saveAction,
-            IAction loadAction, CommonAction importBugAction) {
-        IActionBars actionBars = getViewSite().getActionBars();
-
-        // first in the menu
-        IMenuManager menuManager = actionBars.getMenuManager();
-        menuManager.add(clearAction);
-        menuManager.add(new Separator());
-        menuManager.add(saveAction);
-        menuManager.add(loadAction);
-        menuManager.add(importBugAction);
-        menuManager.add(new Separator());
-        menuManager.add(optionAction);
-
-        // and then in the toolbar
-        IToolBarManager toolBarManager = actionBars.getToolBarManager();
-        toolBarManager.add(clearAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(saveAction);
-        toolBarManager.add(loadAction);
-        toolBarManager.add(importBugAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(optionAction);
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java
deleted file mode 100644
index e79010c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.ddmuilib.explorer.DeviceExplorer;
-import com.android.ide.eclipse.ddms.CommonAction;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.DdmsPlugin.ISelectionListener;
-
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.swt.graphics.Device;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.ViewPart;
-
-public class FileExplorerView extends ViewPart implements ISelectionListener {
-
-    public static final String ID =
-        "com.android.ide.eclipse.ddms.views.FileExplorerView"; //$NON-NLS-1$
-
-    private final static String COLUMN_NAME =
-        DdmsPlugin.PLUGIN_ID + ".explorer.name"; //$NON-NLS-1S
-    private final static  String COLUMN_SIZE =
-        DdmsPlugin.PLUGIN_ID + ".explorer.size"; //$NON-NLS-1S
-    private final static String COLUMN_DATE =
-        DdmsPlugin.PLUGIN_ID + ".explorer.data"; //$NON-NLS-1S
-    private final static String COLUMN_TIME =
-        DdmsPlugin.PLUGIN_ID + ".explorer.time"; //$NON-NLS-1S
-    private final static String COLUMN_PERMISSIONS =
-        DdmsPlugin.PLUGIN_ID +".explorer.permissions"; //$NON-NLS-1S
-    private final static String COLUMN_INFO =
-        DdmsPlugin.PLUGIN_ID + ".explorer.info"; //$NON-NLS-1$
-
-    private DeviceExplorer mExplorer;
-
-    public FileExplorerView() {
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-        DeviceExplorer.COLUMN_NAME = COLUMN_NAME;
-        DeviceExplorer.COLUMN_SIZE = COLUMN_SIZE;
-        DeviceExplorer.COLUMN_DATE = COLUMN_DATE;
-        DeviceExplorer.COLUMN_TIME = COLUMN_TIME;
-        DeviceExplorer.COLUMN_PERMISSIONS = COLUMN_PERMISSIONS;
-        DeviceExplorer.COLUMN_INFO = COLUMN_INFO;
-
-        // device explorer
-        mExplorer = new DeviceExplorer();
-
-
-        mExplorer.setImages(PlatformUI.getWorkbench()
-                .getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE),
-                PlatformUI.getWorkbench() .getSharedImages().getImage(
-                        ISharedImages.IMG_OBJ_FOLDER),
-                DdmsPlugin.getImageLoader().loadDescriptor("android.png") //$NON-NLS-1$
-                        .createImage(),
-                PlatformUI.getWorkbench() .getSharedImages().getImage(
-                        ISharedImages.IMG_OBJ_ELEMENT));
-
-        // creates the actions
-        CommonAction pushAction = new CommonAction("Push File...") {
-            @Override
-            public void run() {
-                mExplorer.pushIntoSelection();
-            }
-        };
-        pushAction.setToolTipText("Push a file onto the device");
-        pushAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor("push.png")); //$NON-NLS-1$
-        pushAction.setEnabled(false);
-
-        CommonAction pullAction = new CommonAction("Pull File...") {
-            @Override
-            public void run() {
-                mExplorer.pullSelection();
-            }
-        };
-        pullAction.setToolTipText("Pull a file from the device");
-        pullAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor("pull.png")); //$NON-NLS-1$
-        pullAction.setEnabled(false);
-
-        CommonAction deleteAction = new CommonAction("Delete") {
-            @Override
-            public void run() {
-                mExplorer.deleteSelection();
-            }
-        };
-        deleteAction.setToolTipText("Delete the selection");
-        deleteAction.setImageDescriptor(DdmsPlugin.getImageLoader()
-                .loadDescriptor("delete.png")); //$NON-NLS-1$
-        deleteAction.setEnabled(false);
-
-        // set up the actions in the explorer
-        mExplorer.setActions(pushAction, pullAction, deleteAction);
-
-        // and in the ui
-        IActionBars actionBars = getViewSite().getActionBars();
-        IMenuManager menuManager = actionBars.getMenuManager();
-        IToolBarManager toolBarManager = actionBars.getToolBarManager();
-
-        menuManager.add(pullAction);
-        menuManager.add(pushAction);
-        menuManager.add(new Separator());
-        menuManager.add(deleteAction);
-
-        toolBarManager.add(pullAction);
-        toolBarManager.add(pushAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(deleteAction);
-
-        mExplorer.createPanel(parent);
-
-        DdmsPlugin.getDefault().addSelectionListener(this);
-    }
-
-    @Override
-    public void setFocus() {
-        mExplorer.setFocus();
-    }
-
-    /**
-     * Sent when a new {@link Client} is selected.
-     * @param selectedClient The selected client.
-     */
-    public void selectionChanged(Client selectedClient) {
-        // pass
-    }
-
-    /**
-     * Sent when a new {@link Device} is selected.
-     * @param selectedDevice the selected device.
-     */
-    public void selectionChanged(IDevice selectedDevice) {
-        mExplorer.switchDevice(selectedDevice);
-    }
-
-    /**
-     * Sent when there is no current selection.
-     */
-    public void selectionRemoved() {
-
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java
deleted file mode 100644
index 5745e8e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmuilib.HeapPanel;
-
-import org.eclipse.swt.widgets.Composite;
-
-public class HeapView extends TableView {
-
-    public static final String ID = "com.android.ide.eclipse.ddms.views.HeapView"; //$NON-NLS-1$
-    private HeapPanel mPanel;
-
-    public HeapView() {
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mPanel = new HeapPanel();
-        mPanel.createPanel(parent);
-
-        setSelectionDependentPanel(mPanel);
-
-        // listen to focus changes for table(s) of the panel.
-        setupTableFocusListener(mPanel, parent);
-    }
-
-    @Override
-    public void setFocus() {
-        mPanel.setFocus();
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
deleted file mode 100644
index d3053f1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ide.eclipse.ddms.CommonAction;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.ImageLoader;
-import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmuilib.logcat.LogColors;
-import com.android.ddmuilib.logcat.LogFilter;
-import com.android.ddmuilib.logcat.LogPanel;
-import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.actions.ActionFactory;
-
-import java.util.ArrayList;
-
-/**
- * The log cat view displays log output from the current device selection.
- *
- */
-public final class LogCatView extends SelectionDependentViewPart {
-
-    public static final String ID =
-        "com.android.ide.eclipse.ddms.views.LogCatView"; // $NON-NLS-1$
-
-    private static final String PREFS_COL_TIME =
-        DdmsPlugin.PLUGIN_ID + ".logcat.time"; // $NON-NLS-1$
-    private static final String PREFS_COL_LEVEL =
-        DdmsPlugin.PLUGIN_ID + ".logcat.level"; // $NON-NLS-1$
-    private static final String PREFS_COL_PID =
-        DdmsPlugin.PLUGIN_ID + ".logcat.pid"; // $NON-NLS-1$
-    private static final String PREFS_COL_TAG =
-        DdmsPlugin.PLUGIN_ID + ".logcat.tag"; // $NON-NLS-1$
-    private static final String PREFS_COL_MESSAGE =
-        DdmsPlugin.PLUGIN_ID + ".logcat.message"; // $NON-NLS-1$
-
-    private static final String PREFS_FILTERS =
-        DdmsPlugin.PLUGIN_ID + ".logcat.filters"; // $NON-NLS-1$
-
-    private static LogCatView sThis;
-    private LogPanel mLogPanel;
-
-    private CommonAction mCreateFilterAction;
-    private CommonAction mDeleteFilterAction;
-    private CommonAction mEditFilterAction;
-    private CommonAction mExportAction;
-
-    private CommonAction[] mLogLevelActions;
-    private String[] mLogLevelIcons = {
-            "v.png", //$NON-NLS-1S
-            "d.png", //$NON-NLS-1S
-            "i.png", //$NON-NLS-1S
-            "w.png", //$NON-NLS-1S
-            "e.png", //$NON-NLS-1S
-    };
-
-    private Action mClearAction;
-
-    private Clipboard mClipboard;
-
-    /**
-     * An implementation of {@link ILogFilterStorageManager} to bridge to the eclipse preference
-     * store, and saves the log filters.
-     */
-    private final class FilterStorage implements ILogFilterStorageManager {
-
-        public LogFilter[] getFilterFromStore() {
-            String filterPrefs = DdmsPlugin.getDefault().getPreferenceStore().getString(
-                    PREFS_FILTERS);
-
-            // split in a string per filter
-            String[] filters = filterPrefs.split("\\|"); // $NON-NLS-1$
-
-            ArrayList<LogFilter> list =
-                new ArrayList<LogFilter>(filters.length);
-
-            for (String f : filters) {
-                if (f.length() > 0) {
-                    LogFilter logFilter = new LogFilter();
-                    if (logFilter.loadFromString(f)) {
-                        list.add(logFilter);
-                    }
-                }
-            }
-
-            return list.toArray(new LogFilter[list.size()]);
-        }
-
-        public void saveFilters(LogFilter[] filters) {
-            StringBuilder sb = new StringBuilder();
-            for (LogFilter f : filters) {
-                String filterString = f.toString();
-                sb.append(filterString);
-                sb.append('|');
-            }
-
-            DdmsPlugin.getDefault().getPreferenceStore().setValue(PREFS_FILTERS, sb.toString());
-        }
-
-        public boolean requiresDefaultFilter() {
-            return true;
-        }
-    }
-
-    public LogCatView() {
-        sThis = this;
-        LogPanel.PREFS_TIME = PREFS_COL_TIME;
-        LogPanel.PREFS_LEVEL = PREFS_COL_LEVEL;
-        LogPanel.PREFS_PID = PREFS_COL_PID;
-        LogPanel.PREFS_TAG = PREFS_COL_TAG;
-        LogPanel.PREFS_MESSAGE = PREFS_COL_MESSAGE;
-    }
-
-    /**
-     * Returns the singleton instance.
-     */
-    public static LogCatView getInstance() {
-        return sThis;
-    }
-
-    /**
-     * Sets the display font.
-     * @param font The font.
-     */
-    public static void setFont(Font font) {
-        if (sThis != null && sThis.mLogPanel != null) {
-            sThis.mLogPanel.setFont(font);
-        }
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-        Display d = parent.getDisplay();
-        LogColors colors = new LogColors();
-
-        ImageLoader loader = DdmsPlugin.getImageLoader();
-
-        colors.infoColor = new Color(d, 0, 127, 0);
-        colors.debugColor = new Color(d, 0, 0, 127);
-        colors.errorColor = new Color(d, 255, 0, 0);
-        colors.warningColor = new Color(d, 255, 127, 0);
-        colors.verboseColor = new Color(d, 0, 0, 0);
-
-        mCreateFilterAction = new CommonAction("Create Filter") {
-            @Override
-            public void run() {
-                mLogPanel.addFilter();
-            }
-        };
-        mCreateFilterAction.setToolTipText("Create Filter");
-        mCreateFilterAction.setImageDescriptor(loader
-                .loadDescriptor("add.png")); // $NON-NLS-1$
-
-        mEditFilterAction = new CommonAction("Edit Filter") {
-            @Override
-            public void run() {
-                mLogPanel.editFilter();
-            }
-        };
-        mEditFilterAction.setToolTipText("Edit Filter");
-        mEditFilterAction.setImageDescriptor(loader
-                .loadDescriptor("edit.png")); // $NON-NLS-1$
-
-        mDeleteFilterAction = new CommonAction("Delete Filter") {
-            @Override
-            public void run() {
-                mLogPanel.deleteFilter();
-            }
-        };
-        mDeleteFilterAction.setToolTipText("Delete Filter");
-        mDeleteFilterAction.setImageDescriptor(loader
-                .loadDescriptor("delete.png")); // $NON-NLS-1$
-
-        mExportAction = new CommonAction("Export Selection As Text...") {
-            @Override
-            public void run() {
-                mLogPanel.save();
-            }
-        };
-        mExportAction.setToolTipText("Export Selection As Text...");
-        mExportAction.setImageDescriptor(loader.loadDescriptor("save.png")); // $NON-NLS-1$
-
-        LogLevel[] levels = LogLevel.values();
-        mLogLevelActions = new CommonAction[mLogLevelIcons.length];
-        for (int i = 0 ; i < mLogLevelActions.length; i++) {
-            String name = levels[i].getStringValue();
-            mLogLevelActions[i] = new CommonAction(name, IAction.AS_CHECK_BOX) {
-                @Override
-                public void run() {
-                    // disable the other actions and record current index
-                    for (int i = 0 ; i < mLogLevelActions.length; i++) {
-                        Action a = mLogLevelActions[i];
-                        if (a == this) {
-                            a.setChecked(true);
-
-                            // set the log level
-                            mLogPanel.setCurrentFilterLogLevel(i+2);
-                        } else {
-                            a.setChecked(false);
-                        }
-                    }
-                }
-            };
-
-            mLogLevelActions[i].setToolTipText(name);
-            mLogLevelActions[i].setImageDescriptor(loader.loadDescriptor(mLogLevelIcons[i]));
-        }
-
-        mClearAction = new Action("Clear Log") {
-            @Override
-            public void run() {
-                mLogPanel.clear();
-            }
-        };
-        mClearAction.setImageDescriptor(loader
-                .loadDescriptor("clear.png")); // $NON-NLS-1$
-
-
-        // now create the log view
-        mLogPanel = new LogPanel(loader, colors, new FilterStorage(), LogPanel.FILTER_MANUAL);
-        mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
-
-        // get the font
-        String fontStr = DdmsPlugin.getDefault().getPreferenceStore().getString(
-                PreferenceInitializer.ATTR_LOGCAT_FONT);
-        if (fontStr != null) {
-            FontData data = new FontData(fontStr);
-
-            if (fontStr != null) {
-                mLogPanel.setFont(new Font(parent.getDisplay(), data));
-            }
-        }
-
-        mLogPanel.createPanel(parent);
-        setSelectionDependentPanel(mLogPanel);
-
-        // place the actions.
-        placeActions();
-
-        // setup the copy action
-        mClipboard = new Clipboard(d);
-        IActionBars actionBars = getViewSite().getActionBars();
-        actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), new Action("Copy") {
-            @Override
-            public void run() {
-                mLogPanel.copy(mClipboard);
-            }
-        });
-
-        // setup the select all action
-        actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
-                new Action("Select All") {
-            @Override
-            public void run() {
-                mLogPanel.selectAll();
-            }
-        });
-    }
-
-    @Override
-    public void dispose() {
-        mLogPanel.stopLogCat(true);
-        mClipboard.dispose();
-    }
-
-    @Override
-    public void setFocus() {
-        mLogPanel.setFocus();
-    }
-
-    /**
-     * Place the actions in the ui.
-     */
-    private void placeActions() {
-        IActionBars actionBars = getViewSite().getActionBars();
-
-        // first in the menu
-        IMenuManager menuManager = actionBars.getMenuManager();
-        menuManager.add(mCreateFilterAction);
-        menuManager.add(mEditFilterAction);
-        menuManager.add(mDeleteFilterAction);
-        menuManager.add(new Separator());
-        menuManager.add(mClearAction);
-        menuManager.add(new Separator());
-        menuManager.add(mExportAction);
-
-        // and then in the toolbar
-        IToolBarManager toolBarManager = actionBars.getToolBarManager();
-        for (CommonAction a : mLogLevelActions) {
-            toolBarManager.add(a);
-        }
-        toolBarManager.add(new Separator());
-        toolBarManager.add(mCreateFilterAction);
-        toolBarManager.add(mEditFilterAction);
-        toolBarManager.add(mDeleteFilterAction);
-        toolBarManager.add(new Separator());
-        toolBarManager.add(mClearAction);
-    }
- }
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java
deleted file mode 100644
index ed5aacb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmuilib.NativeHeapPanel;
-
-import org.eclipse.swt.widgets.Composite;
-
-public class NativeHeapView extends TableView {
-
-    public static final String ID =
-        "com.android.ide.eclipse.ddms.views.NativeHeapView"; // $NON-NLS-1$
-    private NativeHeapPanel mPanel;
-
-    public NativeHeapView() {
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mPanel = new NativeHeapPanel();
-        mPanel.createPanel(parent);
-        
-        setSelectionDependentPanel(mPanel);
-
-        // listen to focus changes for table(s) of the panel.
-        setupTableFocusListener(mPanel, parent);
-    }
-
-    @Override
-    public void setFocus() {
-        mPanel.setFocus();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java
deleted file mode 100644
index 40dae43..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.ddmuilib.SelectionDependentPanel;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.ide.eclipse.ddms.DdmsPlugin.ISelectionListener;
-
-import org.eclipse.swt.graphics.Device;
-import org.eclipse.ui.part.ViewPart;
-
-/**
- * A Workbench {@link ViewPart} that requires {@link Device}/{@link Client} selection notifications
- * from {@link DdmsPlugin} through the {@link ISelectionListener} interface.
- */
-public abstract class SelectionDependentViewPart extends ViewPart implements ISelectionListener {
-
-    private SelectionDependentPanel mPanel;
-
-    protected final void setSelectionDependentPanel(SelectionDependentPanel panel) {
-        // remember the panel
-        mPanel = panel;
-
-        // and add ourself as listener of selection events.
-        DdmsPlugin.getDefault().addSelectionListener(this);
-    }
-
-    @Override
-    public void dispose() {
-        DdmsPlugin.getDefault().removeSelectionListener(this);
-        super.dispose();
-    }
-
-    /**
-     * Sent when a new {@link Client} is selected.
-     * @param selectedClient The selected client.
-     *
-     * @see ISelectionListener
-     */
-    public final void selectionChanged(Client selectedClient) {
-        mPanel.clientSelected(selectedClient);
-    }
-
-    /**
-     * Sent when a new {@link Device} is selected.
-     * @param selectedDevice the selected device.
-     *
-     * @see ISelectionListener
-     */
-    public final void selectionChanged(IDevice selectedDevice) {
-        mPanel.deviceSelected(selectedDevice);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java
deleted file mode 100644
index 0fda35d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmuilib.ITableFocusListener;
-import com.android.ddmuilib.TablePanel;
-import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.actions.ActionFactory;
-
-/**
- * Base class for view containing Table that needs to support copy, and select all.
- */
-public abstract class TableView extends SelectionDependentViewPart {
-
-    /** Activator for the current Table that has the focus */
-    IFocusedTableActivator mActivator = null;
-
-    private Clipboard mClipboard;
-
-    private Action mCopyAction;
-    private Action mSelectAllAction;
-
-    /**
-     * Setup the listener for the Table objects of <code>Panel</code>, and setup
-     * the copy and select all actions.
-     * @param panel The panel to setup
-     * @param parent The parent composite of the Panel's content.
-     */
-    void setupTableFocusListener(TablePanel panel, Composite parent) {
-        panel.setTableFocusListener(new ITableFocusListener() {
-            public void focusGained(IFocusedTableActivator activator) {
-                mActivator = activator;
-                mCopyAction.setEnabled(true);
-                mSelectAllAction.setEnabled(true);
-            }
-
-            public void focusLost(IFocusedTableActivator activator) {
-                if (activator == mActivator) {
-                    mActivator = null;
-                    mCopyAction.setEnabled(false);
-                    mSelectAllAction.setEnabled(false);
-                }
-            }
-        });
-
-        // setup the copy action
-        mClipboard = new Clipboard(parent.getDisplay());
-        IActionBars actionBars = getViewSite().getActionBars();
-        actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
-                mCopyAction = new Action("Copy") {
-            @Override
-            public void run() {
-                if (mActivator != null) {
-                    mActivator.copy(mClipboard);
-                }
-            }
-        });
-
-        // setup the select all action
-        actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
-                mSelectAllAction = new Action("Select All") {
-            @Override
-            public void run() {
-                if (mActivator != null) {
-                    mActivator.selectAll();
-                }
-            }
-        });
-
-    }
-
-    @Override
-    public void dispose() {
-        super.dispose();
-        mClipboard.dispose();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java
deleted file mode 100644
index cd24458..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.android.ide.eclipse.ddms.views;
-
-import com.android.ddmuilib.ThreadPanel;
-
-import org.eclipse.swt.widgets.Composite;
-
-public class ThreadView extends TableView {
-
-    public static final String ID =
-        "com.android.ide.eclipse.ddms.views.ThreadView"; // $NON-NLS-1$
-    private ThreadPanel mPanel;
-
-    public ThreadView() {
-    }
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mPanel = new ThreadPanel();
-        mPanel.createPanel(parent);
-
-        setSelectionDependentPanel(mPanel);
-
-        // listen to focus changes for table(s) of the panel.
-        setupTableFocusListener(mPanel, parent);
-    }
-
-    @Override
-    public void setFocus() {
-        mPanel.setFocus();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
deleted file mode 100644
index 1209191..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="unittests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="lib" path="/adt/sdklib.jar" sourcepath="/SdkLib"/>
-	<classpathentry kind="lib" path="/adt/sdkuilib.jar" sourcepath="/SdkUiLib"/>
-	<classpathentry kind="lib" path="/adt/layoutlib_api.jar" sourcepath="/layoutlib_api"/>
-	<classpathentry kind="lib" path="/adt/ninepatch.jar"/>
-	<classpathentry kind="lib" path="layoutlib.jar"/>
-	<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.gitignore b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.gitignore
deleted file mode 100644
index d392f0e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.jar
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project
deleted file mode 100644
index 99e4964..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>adt-tests</name>
-	<comment></comment>
-	<projects>
-		<project>SdkLib</project>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
deleted file mode 100644
index 0497d2c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,22 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Android Plugin Tests
-Bundle-SymbolicName: com.android.ide.eclipse.tests
-Bundle-Version: 0.9.4.qualifier
-Bundle-Activator: com.android.ide.eclipse.tests.AndroidTestPlugin
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.runtime,
- org.eclipse.core.resources,
- com.android.ide.eclipse.adt,
- org.junit,
- org.eclipse.jdt.core,
- org.eclipse.jdt.launching,
- org.eclipse.ui.views,
- com.android.ide.eclipse.ddms
-Bundle-ActivationPolicy: lazy
-Bundle-Vendor: The Android Open Source Project
-Bundle-ClassPath: kxml2-2.3.0.jar,
- .,
- layoutlib_api.jar,
- sdklib.jar,
- layoutlib.jar
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/MODULE_LICENSE_EPL b/tools/eclipse/plugins/com.android.ide.eclipse.tests/MODULE_LICENSE_EPL
deleted file mode 100644
index e69de29..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/MODULE_LICENSE_EPL
+++ /dev/null
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/NOTICE b/tools/eclipse/plugins/com.android.ide.eclipse.tests/NOTICE
deleted file mode 100644
index 49c101d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/NOTICE
+++ /dev/null
@@ -1,224 +0,0 @@
-*Eclipse Public License - v 1.0*
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
-PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
-THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-*1. DEFINITIONS*
-
-"Contribution" means:
-
-a) in the case of the initial Contributor, the initial code and
-documentation distributed under this Agreement, and
-b) in the case of each subsequent Contributor:
-
-i) changes to the Program, and
-
-ii) additions to the Program;
-
-where such changes and/or additions to the Program originate from and
-are distributed by that particular Contributor. A Contribution
-'originates' from a Contributor if it was added to the Program by such
-Contributor itself or anyone acting on such Contributor's behalf.
-Contributions do not include additions to the Program which: (i) are
-separate modules of software distributed in conjunction with the Program
-under their own license agreement, and (ii) are not derivative works of
-the Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents " mean patent claims licensable by a Contributor which
-are necessarily infringed by the use or sale of its Contribution alone
-or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this
-Agreement.
-
-"Recipient" means anyone who receives the Program under this Agreement,
-including all Contributors.
-
-*2. GRANT OF RIGHTS*
-
-a) Subject to the terms of this Agreement, each Contributor hereby
-grants Recipient a non-exclusive, worldwide, royalty-free copyright
-license to reproduce, prepare derivative works of, publicly display,
-publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and
-object code form.
-
-b) Subject to the terms of this Agreement, each Contributor hereby
-grants Recipient a non-exclusive, worldwide, royalty-free patent license
-under Licensed Patents to make, use, sell, offer to sell, import and
-otherwise transfer the Contribution of such Contributor, if any, in
-source code and object code form. This patent license shall apply to the
-combination of the Contribution and the Program if, at the time the
-Contribution is added by the Contributor, such addition of the
-Contribution causes such combination to be covered by the Licensed
-Patents. The patent license shall not apply to any other combinations
-which include the Contribution. No hardware per se is licensed hereunder.
-
-c) Recipient understands that although each Contributor grants the
-licenses to its Contributions set forth herein, no assurances are
-provided by any Contributor that the Program does not infringe the
-patent or other intellectual property rights of any other entity. Each
-Contributor disclaims any liability to Recipient for claims brought by
-any other entity based on infringement of intellectual property rights
-or otherwise. As a condition to exercising the rights and licenses
-granted hereunder, each Recipient hereby assumes sole responsibility to
-secure any other intellectual property rights needed, if any. For
-example, if a third party patent license is required to allow Recipient
-to distribute the Program, it is Recipient's responsibility to acquire
-that license before distributing the Program.
-
-d) Each Contributor represents that to its knowledge it has sufficient
-copyright rights in its Contribution, if any, to grant the copyright
-license set forth in this Agreement.
-
-*3. REQUIREMENTS*
-
-A Contributor may choose to distribute the Program in object code form
-under its own license agreement, provided that:
-
-a) it complies with the terms and conditions of this Agreement; and
-
-b) its license agreement:
-
-i) effectively disclaims on behalf of all Contributors all warranties
-and conditions, express and implied, including warranties or conditions
-of title and non-infringement, and implied warranties or conditions of
-merchantability and fitness for a particular purpose;
-
-ii) effectively excludes on behalf of all Contributors all liability for
-damages, including direct, indirect, special, incidental and
-consequential damages, such as lost profits;
-
-iii) states that any provisions which differ from this Agreement are
-offered by that Contributor alone and not by any other party; and
-
-iv) states that source code for the Program is available from such
-Contributor, and informs licensees how to obtain it in a reasonable
-manner on or through a medium customarily used for software exchange.
-
-When the Program is made available in source code form:
-
-a) it must be made available under this Agreement; and
-
-b) a copy of this Agreement must be included with each copy of the Program.
-
-Contributors may not remove or alter any copyright notices contained
-within the Program.
-
-Each Contributor must identify itself as the originator of its
-Contribution, if any, in a manner that reasonably allows subsequent
-Recipients to identify the originator of the Contribution.
-
-*4. COMMERCIAL DISTRIBUTION*
-
-Commercial distributors of software may accept certain responsibilities
-with respect to end users, business partners and the like. While this
-license is intended to facilitate the commercial use of the Program, the
-Contributor who includes the Program in a commercial product offering
-should do so in a manner which does not create potential liability for
-other Contributors. Therefore, if a Contributor includes the Program in
-a commercial product offering, such Contributor ("Commercial
-Contributor") hereby agrees to defend and indemnify every other
-Contributor ("Indemnified Contributor") against any losses, damages and
-costs (collectively "Losses") arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified
-Contributor to the extent caused by the acts or omissions of such
-Commercial Contributor in connection with its distribution of the
-Program in a commercial product offering. The obligations in this
-section do not apply to any claims or Losses relating to any actual or
-alleged intellectual property infringement. In order to qualify, an
-Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial
-Contributor to control, and cooperate with the Commercial Contributor
-in, the defense and any related settlement negotiations. The Indemnified
-Contributor may participate in any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial
-product offering, Product X. That Contributor is then a Commercial
-Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance
-claims and warranties are such Commercial Contributor's responsibility
-alone. Under this section, the Commercial Contributor would have to
-defend claims against the other Contributors related to those
-performance claims and warranties, and if a court requires any other
-Contributor to pay any damages as a result, the Commercial Contributor
-must pay those damages.
-
-*5. NO WARRANTY*
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
-ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
-EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES
-OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
-A PARTICULAR PURPOSE. Each Recipient is solely responsible for
-determining the appropriateness of using and distributing the Program
-and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program
-errors, compliance with applicable laws, damage to or loss of data,
-programs or equipment, and unavailability or interruption of operations.
-
-*6. DISCLAIMER OF LIABILITY*
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
-ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
-WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
-DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-*7. GENERAL*
-
-If any provision of this Agreement is invalid or unenforceable under
-applicable law, it shall not affect the validity or enforceability of
-the remainder of the terms of this Agreement, and without further action
-by the parties hereto, such provision shall be reformed to the minimum
-extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against any entity (including
-a cross-claim or counterclaim in a lawsuit) alleging that the Program
-itself (excluding combinations of the Program with other software or
-hardware) infringes such Recipient's patent(s), then such Recipient's
-rights granted under Section 2(b) shall terminate as of the date such
-litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it fails
-to comply with any of the material terms or conditions of this Agreement
-and does not cure such failure in a reasonable period of time after
-becoming aware of such noncompliance. If all Recipient's rights under
-this Agreement terminate, Recipient agrees to cease use and distribution
-of the Program as soon as reasonably practicable. However, Recipient's
-obligations under this Agreement and any licenses granted by Recipient
-relating to the Program shall continue and survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement,
-but in order to avoid inconsistency the Agreement is copyrighted and may
-only be modified in the following manner. The Agreement Steward reserves
-the right to publish new versions (including revisions) of this
-Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the
-initial Agreement Steward. The Eclipse Foundation may assign the
-responsibility to serve as the Agreement Steward to a suitable separate
-entity. Each new version of the Agreement will be given a distinguishing
-version number. The Program (including Contributions) may always be
-distributed subject to the version of the Agreement under which it was
-received. In addition, after a new version of the Agreement is
-published, Contributor may elect to distribute the Program (including
-its Contributions) under the new version. Except as expressly stated in
-Sections 2(a) and 2(b) above, Recipient receives no rights or licenses
-to the intellectual property of any Contributor under this Agreement,
-whether expressly, by implication, estoppel or otherwise. All rights in
-the Program not expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the
-intellectual property laws of the United States of America. No party to
-this Agreement will bring a legal action under this Agreement more than
-one year after the cause of action arose. Each party waives its rights
-to a jury trial in any resulting litigation.
-
- 
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/README.txt b/tools/eclipse/plugins/com.android.ide.eclipse.tests/README.txt
deleted file mode 100644
index fe69958..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/README.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-This project contains the tests for the Android Eclipse Plugins.
-
-You can do three things:
-1- Run the unit tests as a full "eclipse plugin" suite
-2- Run the unit tests as independent JUnit tests (not as plugin)
-3. Run the functional tests as a full "eclipse plugin" suite (require a real SDK)
-
-The unit tests are isolated tests that do not require external dependencies such as an SDK. 
-The functional tests are higher level tests that may require a real SDK.
-
-------------------------------------------
-1- Running the unit tests as a full "eclipse plugin" suite
-------------------------------------------
-
-Steps to run the test suite:
-
-A- In Eclipse, import following projects from development/tools/eclipse/plugins:
-	- adt-tests
-	- adt
-	- ddms
-
-B- Create a new "JUnit Plug-in Test" run configuration via the "Run > Open Run Dialog..." menu
-Set the launch configuration's data as follows:
-i. "Test" tab: 
-  Select "Run a single test"
-  Project: adt-tests 
-  Test class: com.android.ide.eclipse.tests.UnitTests
-  Test runner: JUnit 3
-ii. "Arguments" tab:
- Set "VM Arguments" to 
-"-Dtest_data=<adt>/plugins/com.android.ide.eclipse.tests/unittests/data/"
-replacing "<adt>" with absolute filesystem path to the android plugin source location
-
-All other fields can be left with their default values
-
-C. Run the newly created launch configuration
-
-Running the tests will run a secondary instance of Eclipse. 
-
-Please note the following constraints to be aware of when writing tests to run within a plugin environment:
-
-a. Access restrictions: cannot access package or protected members in a different
-plugin, even if they are in the same declared package 
-b. Using classloader.getResource or getResourceAsStream to access test data will 
-likely fail in the plugin environment. Instead, use AdtTestData to access test files
-in conjunction with the "test_data" environment variable mentioned above
-
-
--------------------------------------------
-2- Run the unit tests as independent JUnit tests (not plugin)
--------------------------------------------
-
-A- In Eclipse, import following projects from development/tools/eclipse/plugins:
-	- adt-tests
-	- adt
-	- ddms
-
-B- Select the "unittests" source folder, right-click and select
-	"Run As > JUnit Test" (i.e. not the plugin tests)
-
-This creates a debug configuration of type "JUnit Test" running all tests
-in the source folder "unittests". The runtime must be JUnit 3.
-
-Note: this method runs the tests within a regular JVM environment (ie not within
-an Eclipse instance). This method has the advantage of being quicker than running
-as a JUnit plugin test, and requires less potential set-up, but has the 
-disadvantage of not properly replicating how the tests will be run in the 
-continuous test environment. Tests that pass when run as "JUnit Tests" can
-fail when run as "JUnit Plugin Tests", due to the extra constraints imposed by
-running within an Eclipse plug-in noted in section 1.
-
-------------------------------------------
-3- Running the functional tests as a full "eclipse plugin" suite
-------------------------------------------
-
-Steps to run the test suite:
-
-A- In Eclipse, import following projects from development/tools/eclipse/plugins:
-	- adt-tests
-	- adt
-	- ddms
-
-B - Setup an SDK on host machine, that is compatible with the Eclipse ADT plugins under test
-
-C- Create a new "JUnit Plug-in Test" run configuration via the "Run > Open Run Dialog..." menu
-Set the launch configuration's data as follows:
-i. "Test" tab: 
-  Select "Run a single test"
-  Project: adt-tests 
-  Test class: com.android.ide.eclipse.tests.FuncTests
-  Test runner: JUnit 3
-ii. "Environment" tab:
- Add a "sdk_home" environment variable, setting its path to the SDK from step B
-
-All other fields can be left with their default values
-
-D. Run the newly created launch configuration
-
-Running the tests will run a secondary instance of Eclipse. 
-
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/build.properties b/tools/eclipse/plugins/com.android.ide.eclipse.tests/build.properties
deleted file mode 100644
index 290cad7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/build.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-source.. = src/,\
-           unittests/
-output.. = bin/
-bin.includes = META-INF/,\
-               .,\
-               test.xml,\
-               prefs.template,\
-               unittest.xml,\
-               kxml2-2.3.0.jar,\
-               unittests/data/,\
-               sdklib.jar,\
-               layoutlib_api.jar,\
-               layoutlib.jar,\
-               unittests/com/android/sdklib/testdata/,\
-               unittests/com/android/layoutlib/testdata/
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java
deleted file mode 100644
index 3cf1027..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 jar.example;
-
-public class Class1 {
-
-    public static final int sStaticField = 1;
-    
-    /** constructor */
-    public Class1() {
-        int a = 1;
-    }
-    
-    public static class InnerStaticClass1 {
-        
-    }
-
-    public class InnerClass2 {
-        
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java
deleted file mode 100644
index 4d15c47..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 jar.example;
-
-public class Class2 extends Class1 {
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/prefs.template b/tools/eclipse/plugins/com.android.ide.eclipse.tests/prefs.template
deleted file mode 100644
index e0037de..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/prefs.template
+++ /dev/null
@@ -1,3 +0,0 @@
-#Wed Feb 20 16:56:40 PST 2008
-com.android.ide.eclipse.adt.sdk=sdk_home
-eclipse.preferences.version=1
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegateTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegateTest.java
deleted file mode 100644
index f393ebf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegateTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.launch;
-
-import com.android.ide.eclipse.adt.internal.launch.JUnitLaunchConfigDelegate;
-
-import java.io.IOException;
-import java.util.Arrays;
-import junit.framework.TestCase;
-
-public class JUnitLaunchConfigDelegateTest extends TestCase {
-
-    public void testAbleToFetchJunitJar() throws IOException {
-        assertTrue(JUnitLaunchConfigDelegate.getJunitJarLocation().endsWith("junit.jar"));
-    }
-    
-    public void testFixBootpathExtWithAndroidJar() {
-        String[][] testArray = {
-                null,
-                { "android.jar"},
-                null,
-                { "some_other_jar.jar" },
-        };
-        
-        String[][] expectedArray = {
-                null,
-                null,
-                null,
-                { "some_other_jar.jar" },
-        };
-        
-       assertEqualsArrays(expectedArray, JUnitLaunchConfigDelegate.fixBootpathExt(testArray));
-    }
-
-    public void testFixBootpathExtWithNoAndroidJar() {
-        String[][] testArray = {
-                null,
-                { "somejar.jar"},
-                null,
-        };
-        
-        String[][] expectedArray = {
-                null,
-                { "somejar.jar"},
-                null,
-        };
-        
-        assertEqualsArrays(expectedArray, JUnitLaunchConfigDelegate.fixBootpathExt(testArray));
-    }
-
-    public void testFixClasspathWithJunitJar() throws IOException {
-        String[] testArray = {
-                JUnitLaunchConfigDelegate.getJunitJarLocation(),
-        };
-        
-        String[] expectedArray = {
-                JUnitLaunchConfigDelegate.getJunitJarLocation(),
-        };
-        
-        assertEqualsArrays(expectedArray, 
-                JUnitLaunchConfigDelegate.fixClasspath(testArray, "test"));
-    }
-    
-    public void testFixClasspathWithoutJunitJar() throws IOException {
-        String[] testArray = {
-                "random.jar",
-        };
-        
-        String[] expectedArray = {
-                "random.jar",
-                JUnitLaunchConfigDelegate.getJunitJarLocation(),
-        };
-        
-        assertEqualsArrays(expectedArray, 
-                JUnitLaunchConfigDelegate.fixClasspath(testArray, "test"));
-    }
-
-
-    public void testFixClasspathWithNoJars() throws IOException {
-        String[] testArray = {
-        };
-        
-        String[] expectedArray = {
-                JUnitLaunchConfigDelegate.getJunitJarLocation(),
-        };
-        
-        assertEqualsArrays(expectedArray, 
-                JUnitLaunchConfigDelegate.fixClasspath(testArray, "test"));
-    }
-
-    private void assertEqualsArrays(String[][] a1, String[][] a2) {
-        assertTrue(Arrays.deepEquals(a1, a2));        
-    }
-    
-    private void assertEqualsArrays(String[] a1, String[] a2) {
-        assertTrue(Arrays.deepEquals(a1, a2));        
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java
deleted file mode 100755
index 8aa8ee0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import java.io.InputStream;
-import java.io.StringReader;
-
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Validator;
-
-import junit.framework.TestCase;
-
-/**
- * Tests local validation of a Layout-Devices sample XMLs using an XML Schema validator.
- */
-public class TestLayoutDevicesXsd extends TestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * A SAX error handler that captures the errors and warnings.
-     * This allows us to capture *all* errors and just not get an exception on the first one.
-     */
-    private static class CaptureErrorHandler implements ErrorHandler {
-
-        private String mWarnings = "";
-        private String mErrors = "";
-
-        @SuppressWarnings("unused")
-        public String getErrors() {
-            return mErrors;
-        }
-
-        @SuppressWarnings("unused")
-        public String getWarnings() {
-            return mWarnings;
-        }
-
-        /**
-         * Verifies if the handler captures some errors or warnings.
-         * Prints them on stderr.
-         * Also fails the unit test if any error was generated.
-         */
-        public void verify() {
-            if (mWarnings.length() > 0) {
-                System.err.println(mWarnings);
-            }
-
-            if (mErrors.length() > 0) {
-                System.err.println(mErrors);
-                fail(mErrors);
-            }
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void error(SAXParseException ex) throws SAXException {
-            mErrors += "Error: " + ex.getMessage() + "\n";
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void fatalError(SAXParseException ex) throws SAXException {
-            mErrors += "Fatal Error: " + ex.getMessage() + "\n";
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void warning(SAXParseException ex) throws SAXException {
-            mWarnings += "Warning: " + ex.getMessage() + "\n";
-        }
-
-    }
-
-    // --- 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 = LayoutDevicesXsd.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 = LayoutDevicesXsd.getValidator(null);
-        validator.validate(source);
-        handler.verify();
-    }
-
-    // --- Tests ------------
-
-    /** Validate a valid sample using an InputStream */
-    public void testValidateLocalRepositoryFile() throws Exception {
-
-        InputStream xmlStream =
-            TestLayoutDevicesXsd.class.getResourceAsStream("config_sample.xml");
-        Source source = new StreamSource(xmlStream);
-
-        CaptureErrorHandler handler = new CaptureErrorHandler();
-        Validator validator = LayoutDevicesXsd.getValidator(handler);
-        validator.validate(source);
-        handler.verify();
-    }
-
-    /** A document should at least have a root to be valid */
-    public void testEmptyXml() throws Exception {
-        checkFailure(
-                // document
-                "<?xml version=\"1.0\"?>",
-
-                // expected failure
-                "Premature end of file.*");
-    }
-
-    /** A document with an unknown element. */
-    public void testUnknownContentXml() throws Exception {
-        checkFailure(
-                // document
-                "<?xml version=\"1.0\"?>" +
-                "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:unknown />" +
-                "</d:layout-devices>",
-
-                // 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 {
-        checkFailure(
-                // document
-                "<?xml version=\"1.0\"?>" +
-                "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:device />" +
-                "</d:layout-devices>",
-
-                // 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 {
-        checkFailure(
-                // document
-                "<?xml version=\"1.0\"?>" +
-                "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" />",
-
-                // expected failure
-                "cvc-complex-type.2.4.b: The content of element 'd:layout-devices' is not complete.*");
-    }
-
-    /** A document with an empty device element is not valid. */
-    public void testEmptyDeviceXml() throws Exception {
-        checkFailure(
-                // document
-                "<?xml version=\"1.0\"?>" +
-                "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:device name=\"foo\"/>" +
-                "</d:layout-devices>",
-
-                // 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 {
-        checkFailure(
-                // document
-                "<?xml version=\"1.0\"?>" +
-                "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:device name=\"foo\">" +
-                "  <d:default />" +
-                "  <d:default />" +
-                "</d:device>" +
-                "</d:layout-devices>",
-
-                // 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 {
-        checkFailure(
-                // document
-                "<?xml version=\"1.0\"?>" +
-                "<d:layout-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:device name=\"foo\">" +
-                "  <d:config name=\"must-be-after-default\" />" +
-                "  <d:default />" +
-                "</d:device>" +
-                "</d:layout-devices>",
-
-                // 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-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/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-devices>",
-
-                // 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-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/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-devices>",
-
-                // 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-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:device name=\"foo\">" +
-                "  <d:default>" +
-                "    <d:xdpi>0</d:xdpi>" +
-                "  </d:default>" +
-                "</d:device>" +
-                "</d:layout-devices>",
-
-                // 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-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:device name=\"foo\">" +
-                "  <d:default>" +
-                "    <d:xdpi>-3.1415926538</d:xdpi>" +
-                "  </d:default>" +
-                "</d:device>" +
-                "</d:layout-devices>",
-
-                // 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-devices xmlns:d=\"http://schemas.android.com/sdk/android/layout-devices/1\" >" +
-                "<d:device name=\"foo\">" +
-                "  <d:config name='foo'>" +
-                "    <d:screen-ratio>  \n long \r </d:screen-ratio>" +
-                "  </d:config>" +
-                "</d:device>" +
-                "</d:layout-devices>");
-    }
-
-}
-
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
deleted file mode 100755
index 56a753f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version="1.0"?>
-<!--
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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.
--->
-<d:layout-devices
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xmlns:d="http://schemas.android.com/sdk/android/layout-devices/1">
-
-    <d:device name="MyDevice">        <!-- 1..n -->
-        <d:default>                   <!-- 0..1 -->
-            <d:screen-size>small</d:screen-size>
-            <d:screen-ratio>long</d:screen-ratio>
-            <d:screen-orientation>port</d:screen-orientation>
-            <d:pixel-density>ldpi</d:pixel-density>
-            <d:touch-type>notouch</d:touch-type>
-            <d:keyboard-state>keysexposed</d:keyboard-state>
-            <d:text-input-method>nokeys</d:text-input-method>
-            <d:nav-method>dpad</d:nav-method>
-            <d:screen-dimension>
-                <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">
-            <d:keyboard-state>keyshidden</d:keyboard-state>
-            <d:screen-orientation>port</d:screen-orientation>
-        </d:config>
-        <d:config name="Landscape, closed">
-            <d:keyboard-state>keyshidden</d:keyboard-state>
-            <d:screen-orientation>land</d:screen-orientation>
-        </d:config>
-        <d:config name="Landscape, open">
-            <d:keyboard-state>keysexposed</d:keyboard-state>
-            <d:screen-orientation>land</d:screen-orientation>
-        </d:config>
-
-        <d:config name="screen-size-small">
-            <d:screen-size>small</d:screen-size>
-        </d:config>
-        <d:config name="screen-size-normal">
-            <d:screen-size>normal</d:screen-size>
-        </d:config>
-        <d:config name="screen-size-large">
-            <d:screen-size>large</d:screen-size>
-        </d:config>
-
-        <d:config name="screen-ratio-long">
-            <d:screen-ratio>long</d:screen-ratio>
-        </d:config>
-        <d:config name="screen-ratio-notlong">
-            <d:screen-ratio>notlong</d:screen-ratio>
-        </d:config>
-
-        <d:config name="screen-orientation-port">
-            <d:screen-orientation>port</d:screen-orientation>
-        </d:config>
-        <d:config name="screen-orientation-land">
-            <d:screen-orientation>land</d:screen-orientation>
-        </d:config>
-        <d:config name="screen-orientation-square">
-            <d:screen-orientation>square</d:screen-orientation>
-        </d:config>
-
-        <d:config name="pixel-density-ldpi">
-            <d:pixel-density>ldpi</d:pixel-density>
-        </d:config>
-        <d:config name="pixel-density-mdpi">
-            <d:pixel-density>mdpi</d:pixel-density>
-        </d:config>
-        <d:config name="pixel-density-hdpi">
-            <d:pixel-density>hdpi</d:pixel-density>
-        </d:config>
-
-        <d:config name="touch-type-notouch">
-            <d:touch-type>notouch</d:touch-type>
-        </d:config>
-        <d:config name="touch-type-stylus">
-            <d:touch-type>stylus</d:touch-type>
-        </d:config>
-        <d:config name="touch-type-finger">
-            <d:touch-type>finger</d:touch-type>
-        </d:config>
-
-        <d:config name="text-input-method-nokeys">
-            <d:text-input-method>nokeys</d:text-input-method>
-        </d:config>
-        <d:config name="text-input-method-qwerty">
-            <d:text-input-method>qwerty</d:text-input-method>
-        </d:config>
-        <d:config name="text-input-method-12key">
-            <d:text-input-method>12key</d:text-input-method>
-        </d:config>
-
-        <d:config name="nav-method-dpad">
-            <d:nav-method>dpad</d:nav-method>
-        </d:config>
-        <d:config name="nav-method-trackball">
-            <d:nav-method>trackball</d:nav-method>
-        </d:config>
-        <d:config name="nav-method-wheel">
-            <d:nav-method>wheel</d:nav-method>
-        </d:config>
-        <d:config name="nav-method-nonav">
-            <d:nav-method>nonav</d:nav-method>
-        </d:config>
-
-        <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">
-            <d:screen-size>normal</d:screen-size>
-        </d:config>
-    </d:device>
-
-</d:layout-devices>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectCreationPage.java
deleted file mode 100644
index 0ed9ed4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectCreationPage.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.adt.wizards.newproject;
-
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-
-/**
- * Stub class for project creation page.
- * <p/>
- * Returns canned responses for creating a sample project.
- */
-public class StubProjectCreationPage extends NewProjectCreationPage {
-
-    private final String mProjectName;
-    private final String mLocation;
-    private final IAndroidTarget mTarget;
-
-    public StubProjectCreationPage(String projectName, String projectLocation, IAndroidTarget target) {
-        super();
-        this.mProjectName = projectName;
-        this.mLocation = projectLocation;
-        this.mTarget = target;
-        // don't set test project info
-        setTestInfo(null);
-    }
-
-    @Override
-    public IMainInfo getMainInfo() {
-        return new IMainInfo() {
-            public String getProjectName() {
-                return mProjectName;
-            }
-
-            public String getPackageName() {
-                return "com.android.samples";
-            }
-
-            public String getActivityName() {
-                return mProjectName;
-            }
-
-            public String getApplicationName() {
-                return mProjectName;
-            }
-
-            public boolean isNewProject() {
-                return false;
-            }
-
-            public String getSourceFolder() {
-                return "src";
-            }
-
-            public IPath getLocationPath() {
-                return new Path(mLocation);
-            }
-
-            public String getMinSdkVersion() {
-                return null;
-            }
-
-            public IAndroidTarget getSdkTarget() {
-                return mTarget;
-            }
-
-            public boolean isCreateActivity() {
-                return false;
-            }
-
-            public boolean useDefaultLocation() {
-                return false;
-            }
-        };
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectWizard.java
deleted file mode 100644
index 18a29cc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectWizard.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.adt.wizards.newproject;
-
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectCreationPage;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.wizard.IWizardContainer;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.widgets.Shell;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Stub class for project creation wizard.
- * <p/>
- * Created so project creation logic can be run without UI creation/manipulation.
- */
-public class StubProjectWizard extends NewProjectWizard {
-
-    private final String mProjectName;
-    private final String mProjectLocation;
-    private final IAndroidTarget mTarget;
-
-    /**
-     * Constructor
-     *
-     * @param projectName
-     * @param projectLocation
-     * @parama target
-     */
-    public StubProjectWizard(String projectName, String projectLocation, IAndroidTarget target) {
-        this.mProjectName = projectName;
-        this.mProjectLocation = projectLocation;
-        this.mTarget = target;
-    }
-
-    /**
-     * Override parent to return stub page
-     */
-    @Override
-    protected NewProjectCreationPage createMainPage() {
-        return new StubProjectCreationPage(mProjectName, mProjectLocation, mTarget);
-    }
-
-    /**
-     * Override parent to return null page
-     */
-    @Override
-    protected NewTestProjectCreationPage createTestPage() {
-        return null;
-    }
-
-    /**
-     * Overrides parent to return dummy wizard container
-     */
-    @Override
-    public IWizardContainer getContainer() {
-        return new IWizardContainer() {
-
-            public IWizardPage getCurrentPage() {
-                return null;
-            }
-
-            public Shell getShell() {
-                return null;
-            }
-
-            public void showPage(IWizardPage page) {
-                // pass
-            }
-
-            public void updateButtons() {
-                // pass
-            }
-
-            public void updateMessage() {
-                // pass
-            }
-
-            public void updateTitleBar() {
-                // pass
-            }
-
-            public void updateWindowTitle() {
-                // pass
-            }
-
-            /**
-             * Executes runnable on current thread
-             */
-            public void run(boolean fork, boolean cancelable,
-                    IRunnableWithProgress runnable)
-                    throws InvocationTargetException, InterruptedException {
-                runnable.run(new NullProgressMonitor());
-            }
-
-        };
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtSdkTestCase.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtSdkTestCase.java
deleted file mode 100644
index d884f35..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtSdkTestCase.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-
-/**
- * A test case which uses the Sdk loaded by the Adt plugin.
- */
-public abstract class AdtSdkTestCase extends SdkTestCase {
-
-    protected AdtSdkTestCase() {
-    }
-
-    /**
-     * Gets the current Sdk from Adt, waiting if necessary.
-     */
-    @Override
-    protected Sdk loadSdk() {
-        AdtPlugin adt = AdtPlugin.getDefault();
-        Object sdkLock = adt.getSdkLockObject();
-        LoadStatus loadStatus = LoadStatus.LOADING;
-        // wait for Adt to load the Sdk on a separate thread
-        // loop max of 600 times * 200 ms =  2 minutes
-        final int maxWait = 600;
-        for (int i=0; i < maxWait && loadStatus == LoadStatus.LOADING; i++) {
-            try {
-                Thread.sleep(200);
-            }
-            catch (InterruptedException e) {
-                // ignore
-            }
-            synchronized(sdkLock) {
-                loadStatus = adt.getSdkLoadStatus();
-            }
-        }
-        Sdk sdk = null;
-        synchronized(sdkLock) {
-            assertEquals(LoadStatus.LOADED, loadStatus);
-            sdk = Sdk.getCurrent();
-        }
-        assertNotNull(sdk);
-        return sdk;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java
deleted file mode 100644
index 6d13737..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Platform;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.logging.Logger;
-
-/**
- * Helper class for retrieving test data
- * 
- * All tests which need to retrieve test data files should go through this class 
- *
- */
-public class AdtTestData {
-
-    /** singleton instance */
-    private static AdtTestData sInstance = null;
-    private static final Logger sLogger = Logger.getLogger(AdtTestData.class.getName());
-    
-    /** the absolute file path to the /data directory in this test 
-     * environment. 
-     */
-    private String mOsRootDataPath;
-    
-   
-    private AdtTestData() {
-        // can set test_data env variable to override default behavior of 
-        // finding data using class loader
-        // useful when running in plugin environment, where test data is inside 
-        // bundled jar, and must be extracted to temp filesystem location to be 
-        // accessed normally
-        mOsRootDataPath = System.getProperty("test_data");
-        if (mOsRootDataPath == null) {
-            sLogger.info("Cannot find test_data environment variable, init to class loader");
-            URL url = this.getClass().getClassLoader().getResource("data");  //$NON-NLS-1$
-
-                if (Platform.isRunning()) {
-                    sLogger.info("Running as an Eclipse Plug-in JUnit test, using FileLocator");
-                    try {
-                        mOsRootDataPath = FileLocator.resolve(url).getFile();
-                    } catch (IOException e) {
-                        sLogger.warning("IOException while using FileLocator, reverting to url");
-                        mOsRootDataPath = url.getFile();
-                    }
-                } else {
-                    sLogger.info("Running as an plain JUnit test, using url as-is");
-                    mOsRootDataPath = url.getFile();                        
-                }
-        }
-        
-        if (mOsRootDataPath.equals(AndroidConstants.WS_SEP + "data")) {
-            sLogger.warning("Resource data not found using class loader!, Defaulting to no path");
-        }
-        
-        if (!mOsRootDataPath.endsWith(File.separator)) {
-            sLogger.info("Fixing test_data env variable (does not end with path separator)");
-            mOsRootDataPath = mOsRootDataPath.concat(File.separator);
-        }
-    }
-    
-    /** Get the singleton instance of AdtTestData */
-    public static AdtTestData getInstance() {
-        if (sInstance == null) {
-            sInstance = new AdtTestData();
-        }
-        return sInstance;
-    }
-    
-    /** Returns the absolute file path to a file located in this plugins
-     * "data" directory
-     * @param osRelativePath - string path to file contained in /data. Must 
-     * use path separators appropriate to host OS
-     * @return String
-     */
-    public String getTestFilePath(String osRelativePath) {
-        return mOsRootDataPath + osRelativePath;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java
deleted file mode 100644
index fb5504c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import junit.framework.TestSuite;
-
-
-/**
- * Container TestSuite for all eclipse tests, both functional and unit
- */
-public class AllTests extends TestSuite {
-
-    public AllTests() {
-        
-    }
-    
-    /**
-     * Returns a suite of test cases to be run.
-     */
-    public static TestSuite suite() {
-        TestSuite suite = new TestSuite();
-        suite.addTest(FuncTests.suite());
-        suite.addTest(UnitTests.suite());
-        return suite;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AndroidTestPlugin.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AndroidTestPlugin.java
deleted file mode 100644
index 45a6fbc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AndroidTestPlugin.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public class AndroidTestPlugin extends AbstractUIPlugin {
-
-    // The plug-in ID
-    public static final String PLUGIN_ID = "com.android.ide.eclipse.adt.tests";
-
-    // The shared instance
-    private static AndroidTestPlugin sPlugin;
-
-    /**
-     * The constructor
-     */
-    public AndroidTestPlugin() {
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-     */
-    @Override
-    public void start(BundleContext context) throws Exception {
-        super.start(context);
-        sPlugin = this;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-     */
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        sPlugin = null;
-        super.stop(context);
-    }
-
-    /**
-     * Returns the shared instance
-     * 
-     * @return the shared instance
-     */
-    public static AndroidTestPlugin getDefault() {
-        return sPlugin;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java
deleted file mode 100644
index 5a413fa..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import org.eclipse.core.runtime.Plugin;
-
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.util.Enumeration;
-
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Class for collecting all test cases in an eclipse plugin
- * 
- */
-public class EclipseTestCollector {
-
-    /**
-     * Constructor
-     */
-    public EclipseTestCollector() {
-        
-    }
-
-    /**
-     * Searches through given plugin, adding all TestCase classes to given suite
-     * @param suite - TestSuite to add to
-     * @param plugin - Plugin to search for tests
-     * @param expectedPackage - expected package for tests. Only test classes 
-     *  that start with this package name will be added to suite
-     */
-    public void addTestCases(TestSuite suite, Plugin plugin, String expectedPackage) {
-        if (plugin != null) {
-            Enumeration<?> entries = plugin.getBundle().findEntries("/", "*.class", true);
-    
-            while (entries.hasMoreElements()) {
-                URL entry = (URL)entries.nextElement();
-                String filePath = entry.getPath().replace(".class", "");
-                try {
-                  Class<?> testClass = getClass(filePath, expectedPackage);
-                  if (isTestClass(testClass)) {
-                      suite.addTestSuite(testClass);
-                  }
-                } 
-                catch (ClassNotFoundException e) {
-                  // ignore, this is not the class we're looking for
-                  //sLogger.log(Level.INFO, "Could not load class " + filePath);
-              }
-            }
-        }
-    }
-    
-    /**
-     * Returns true if given class should be added to suite
-     */
-    protected boolean isTestClass(Class<?> testClass) {
-        return TestCase.class.isAssignableFrom(testClass) &&
-          Modifier.isPublic(testClass.getModifiers()) &&
-          hasPublicConstructor(testClass);
-    }
-    
-    /**
-     * Returns true if given class has a public constructor
-     */
-    protected boolean hasPublicConstructor(Class<?> testClass) {
-        try {
-            TestSuite.getTestConstructor(testClass);
-        } catch(NoSuchMethodException e) {
-            return false;
-        }
-        return true;
-    }
-    
-    /**
-     * Load the class given by the plugin aka bundle file path
-     * @param filePath - path of class in bundle
-     * @param expectedPackage - expected package of class
-     * @throws ClassNotFoundException
-     */
-    protected Class<?> getClass(String filePath, String expectedPackage) throws ClassNotFoundException {
-        String dotPath = filePath.replace('/', '.');
-        // remove the output folders, by finding where package name starts
-        int index = dotPath.indexOf(expectedPackage);
-        if (index == -1) {
-            throw new ClassNotFoundException();
-        }
-        String packagePath = dotPath.substring(index);
-        return Class.forName(packagePath);   
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
deleted file mode 100644
index 02c9247..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.ide.eclipse.tests.functests.layoutRendering.ApiDemosRenderingTest;
-import com.android.ide.eclipse.tests.functests.sampleProjects.SampleProjectTest;
-
-import junit.framework.TestSuite;
-
-/**
- * Container TestSuite for all eclipse tests to be run
- */
-
-public class FuncTests extends TestSuite {
-
-    static final String FUNC_TEST_PACKAGE = "com.android.ide.eclipse.tests.functests";
-
-    public FuncTests() {
-
-    }
-
-    /**
-     * Returns a suite of test cases to be run.
-     * Needed for JUnit3 compliant command line test runner
-     */
-    public static TestSuite suite() {
-        TestSuite suite = new TestSuite();
-
-        suite.addTestSuite(SampleProjectTest.class);
-        suite.addTestSuite(ApiDemosRenderingTest.class);
-
-        return suite;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkEnvTestCase.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkEnvTestCase.java
deleted file mode 100644
index 1039a7f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkEnvTestCase.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-
-
-/**
- * A test case that receives a specific Sdk to test via the "sdk_home" environment variable.
- */
-public abstract class SdkEnvTestCase extends SdkTestCase {
-
-    protected SdkEnvTestCase() {
-    }
-
-    /**
-     * Loads the {@link Sdk}.
-     * <p/>
-     * Fails test if environment variable "sdk_home" is not set.
-     */
-    @Override
-    protected Sdk loadSdk() {
-        String osSdkLocation = System.getProperty("sdk_home");
-        if (osSdkLocation == null) {
-            osSdkLocation = System.getenv("sdk_home");
-        }
-        if (osSdkLocation == null || osSdkLocation.length() < 1) {
-            fail("Environment variable sdk_home is not set");
-        }
-        return Sdk.loadSdk(osSdkLocation);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkTestCase.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkTestCase.java
deleted file mode 100644
index 322ce3e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkTestCase.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-
-import junit.framework.TestCase;
-
-/**
- * A test case that needs a reference to a SDK.
- */
-public abstract class SdkTestCase extends TestCase {
-
-    private Sdk mSdk;
-
-    protected SdkTestCase() {
-    }
-
-    /**
-     * Retrieve the {@link Sdk} under test.
-     */
-    protected Sdk getSdk() {
-        if (mSdk == null) {
-            mSdk = loadSdk();
-            assertNotNull(mSdk);
-            validateSdk(mSdk);
-        }
-        return mSdk;
-    }
-
-    /**
-     * Loads the {@link Sdk} to use for test
-     */
-    protected abstract Sdk loadSdk();
-
-    /**
-     * Checks that the provided sdk contains one or more valid targets.
-     * @param sdk the {@link Sdk} to validate.
-     */
-    private void validateSdk(Sdk sdk) {
-        assertTrue("sdk has no targets", sdk.getTargets().length > 0);
-        for (IAndroidTarget target : sdk.getTargets()) {
-            IStatus status = new AndroidTargetParser(target).run(new NullProgressMonitor());
-            if (status.getCode() != IStatus.OK) {
-                fail("Failed to parse targets data");
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java
deleted file mode 100644
index 6c1510c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * Container TestSuite for all eclipse unit tests to be run
- * 
- * Uses Eclipse OSGI to find and then run all junit.junit.framework.Tests in 
- * this plugin, excluding tests in the FuncTests.FUNC_TEST_PACKAGE package
- * 
- * Since it uses Eclipse OSGI, it must be run in a Eclipse plugin environment
- * i.e. from Eclipse workbench, this suite must be run using the 
- * "JUnit Plug-in Test" launch configuration as opposed to as a "JUnit Test"  
- * 
- */                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
-public class UnitTests {
-    private static final String TEST_PACKAGE = "com.android";
-    
-    public static Test suite() {
-        TestSuite suite = new TestSuite();
-
-        UnitTestCollector collector = new UnitTestCollector();
-        collector.addTestCases(suite, AndroidTestPlugin.getDefault(), TEST_PACKAGE);
-
-        return suite;
-    }
-
-    /**
-     * Specialized test collector which will skip adding functional tests
-     */
-    private static class UnitTestCollector extends EclipseTestCollector {
-        /**
-         * Override parent class to exclude functional tests
-         */
-        @Override
-        protected boolean isTestClass(Class<?> testClass) {
-            return super.isTestClass(testClass) &&
-            !testClass.getPackage().getName().startsWith(FuncTests.FUNC_TEST_PACKAGE);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
deleted file mode 100644
index 3b52789..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.ide.eclipse.tests.functests.layoutRendering;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
-import com.android.ide.eclipse.tests.SdkEnvTestCase;
-import com.android.layoutlib.api.ILayoutResult;
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IXmlPullParser;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.imageio.ImageIO;
-
-public class ApiDemosRenderingTest extends SdkEnvTestCase {
-
-    /**
-     * Custom parser that implements {@link IXmlPullParser} (which itself extends
-     * {@link XmlPullParser}).
-     */
-    private final static class TestParser extends KXmlParser implements IXmlPullParser {
-        /**
-         * Since we're not going to go through the result of the rendering/layout, we can return
-         * null for the View Key.
-         */
-        public Object getViewKey() {
-            return null;
-        }
-    }
-
-    private final static class ProjectCallBack implements IProjectCallback {
-        // resource id counter.
-        // We start at 0x7f000000 to avoid colliding with the framework id
-        // since we have no access to the project R.java and we need to generate them automatically.
-        private int mIdCounter = 0x7f000000;
-
-        // in some cases, the id that getResourceValue(String type, String name) returns
-        // will be sent back to get the type/name. This map stores the id/type/name we generate
-        // to be able to do the reverse resolution.
-        private Map<Integer, String[]> mResourceMap = new HashMap<Integer, String[]>();
-
-        private boolean mCustomViewAttempt = false;
-
-        public String getNamespace() {
-            // TODO: read from the ApiDemos manifest.
-            return "com.example.android.apis";
-        }
-
-        public Integer getResourceValue(String type, String name) {
-            Integer result = ++mIdCounter;
-            mResourceMap.put(result, new String[] { name, type });
-            return result;
-        }
-
-        @SuppressWarnings("unchecked")
-        public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
-                throws ClassNotFoundException, Exception {
-            mCustomViewAttempt = true;
-            return null;
-        }
-
-        public String[] resolveResourceValue(int id) {
-            return mResourceMap.get(id);
-        }
-
-        public String resolveResourceValue(int[] id) {
-            return null;
-        }
-
-    }
-
-    public void testApiDemos() throws IOException, XmlPullParserException {
-        findApiDemos();
-    }
-
-    private void findApiDemos() throws IOException, XmlPullParserException {
-        IAndroidTarget[] targets = getSdk().getTargets();
-
-        for (IAndroidTarget target : targets) {
-            String path = target.getPath(IAndroidTarget.SAMPLES);
-            File samples = new File(path);
-            if (samples.isDirectory()) {
-                File[] files = samples.listFiles();
-                for (File file : files) {
-                    if ("apidemos".equalsIgnoreCase(file.getName())) {
-                        testSample(target, file);
-                        return;
-                    }
-                }
-            }
-        }
-
-        fail("Failed to find ApiDemos!");
-    }
-
-    private void testSample(IAndroidTarget target, File sampleProject) throws IOException, XmlPullParserException {
-        AndroidTargetData data = getSdk().getTargetData(target);
-        if (data == null) {
-            fail("No AndroidData!");
-        }
-
-        LayoutBridge bridge = data.getLayoutBridge();
-        if (bridge.status != LoadStatus.LOADED || bridge.bridge == null) {
-            fail("Fail to load the bridge");
-        }
-
-        File resFolder = new File(sampleProject, SdkConstants.FD_RES);
-        if (resFolder.isDirectory() == false) {
-            fail("Sample project has no res folder!");
-        }
-
-        // look for the layout folder
-        File layoutFolder = new File(resFolder, SdkConstants.FD_LAYOUT);
-        if (layoutFolder.isDirectory() == false) {
-            fail("Sample project has no layout folder!");
-        }
-
-        // first load the project's target framework resource
-        ProjectResources framework = ResourceManager.getInstance().loadFrameworkResources(target);
-
-        // now load the project resources
-        ProjectResources project = new ProjectResources(false /* isFrameworkRepository */);
-        ResourceManager.getInstance().loadResources(project, resFolder);
-
-
-        // Create a folder configuration that will be used for the rendering:
-        FolderConfiguration config = getConfiguration();
-
-        // get the configured resources
-        Map<String, Map<String, IResourceValue>> configuredFramework =
-                framework.getConfiguredResources(config);
-        Map<String, Map<String, IResourceValue>> configuredProject =
-                project.getConfiguredResources(config);
-
-        boolean saveFiles = System.getenv("save_file") != null;
-
-        // loop on the layouts and render them
-        File[] layouts = layoutFolder.listFiles();
-        for (File layout : layouts) {
-            // create a parser for the layout file
-            TestParser parser = new TestParser();
-            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-            parser.setInput(new FileReader(layout));
-
-            System.out.println("Rendering " + layout.getName());
-
-            ProjectCallBack projectCallBack = new ProjectCallBack();
-
-            ILayoutResult result = bridge.bridge.computeLayout(
-                    parser,
-                    null /*projectKey*/,
-                    320,
-                    480,
-                    false, //renderFullSize
-                    160, //density
-                    160, //xdpi
-                    160, // ydpi
-                    "Theme", //themeName
-                    false, //isProjectTheme
-                    configuredProject,
-                    configuredFramework,
-                    projectCallBack,
-                    null //logger
-                    );
-
-            if (result.getSuccess() != ILayoutResult.SUCCESS) {
-                if (projectCallBack.mCustomViewAttempt == false) {
-                    System.out.println("FAILED");
-                    fail(String.format("Rendering %1$s: %2$s", layout.getName(),
-                            result.getErrorMessage()));
-                } else {
-                    System.out.println("Ignore custom views for now");
-                }
-            } else {
-                if (saveFiles) {
-                    File tmp = File.createTempFile(layout.getName(), ".png");
-                    ImageIO.write(result.getImage(), "png", tmp);
-                }
-                System.out.println("Success!");
-            }
-        }
-    }
-
-    /**
-     * Returns a config. This must be a valid config like a device would return. This is to
-     * prevent issues where some resources don't exist in all cases and not in the default
-     * (for instance only available in hdpi and mdpi but not in default).
-     * @return
-     */
-    private FolderConfiguration getConfiguration() {
-        FolderConfiguration config = new FolderConfiguration();
-
-        // this matches an ADP1.
-        config.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
-        config.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
-        config.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
-        config.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
-        config.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
-        config.addQualifier(new KeyboardStateQualifier(KeyboardState.HIDDEN));
-        config.addQualifier(new TextInputMethodQualifier(TextInputMethod.QWERTY));
-        config.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
-        config.addQualifier(new ScreenDimensionQualifier(480, 320));
-
-        return config;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java
deleted file mode 100644
index 495c3be..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests.functests.sampleProjects;
-
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.xml.AndroidManifest;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-/**
- * Helper class for modifying an AndroidManifest.
- * <p/>
- * TODO: consider merging this with AndroidManifestParser.
- */
-class AndroidManifestWriter {
-
-    private static final Logger sLogger = Logger.getLogger(AndroidManifestWriter.class.getName());
-
-    private final Document mDoc;
-    private final String mOsManifestFilePath;
-
-    private AndroidManifestWriter(Document doc, String osManifestFilePath) {
-        mDoc = doc;
-        mOsManifestFilePath = osManifestFilePath;
-    }
-
-    /**
-     * Sets the minimum SDK version for this manifest
-     * @param minSdkVersion - the minimim sdk version to use
-     * @returns <code>true</code> on success, false otherwise
-     */
-    public boolean setMinSdkVersion(String minSdkVersion) {
-        Element usesSdkElement = null;
-        NodeList nodeList = mDoc.getElementsByTagName(AndroidManifest.NODE_USES_SDK);
-        if (nodeList.getLength() > 0) {
-            usesSdkElement = (Element) nodeList.item(0);
-        } else {
-            usesSdkElement = mDoc.createElement(AndroidManifest.NODE_USES_SDK);
-            mDoc.getDocumentElement().appendChild(usesSdkElement);
-        }
-        Attr minSdkAttr = mDoc.createAttributeNS(SdkConstants.NS_RESOURCES,
-                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
-        String prefix = mDoc.lookupPrefix(SdkConstants.NS_RESOURCES);
-        minSdkAttr.setPrefix(prefix);
-        minSdkAttr.setValue(minSdkVersion);
-        usesSdkElement.setAttributeNodeNS(minSdkAttr);
-        return saveXmlToFile();
-    }
-
-    private boolean saveXmlToFile() {
-        try {
-            // Prepare the DOM document for writing
-            Source source = new DOMSource(mDoc);
-
-            // Prepare the output file
-            File file = new File(mOsManifestFilePath);
-            Result result = new StreamResult(file);
-
-            // Write the DOM document to the file
-            Transformer xformer = TransformerFactory.newInstance().newTransformer();
-            xformer.transform(source, result);
-        } catch (TransformerConfigurationException e) {
-            sLogger.log(Level.SEVERE, "Failed to write xml file", e);
-            return false;
-        } catch (TransformerException e) {
-            sLogger.log(Level.SEVERE, "Failed to write xml file", e);
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Parses the manifest file, and collects data.
-     *
-     * @param osManifestFilePath The OS path of the manifest file to parse.
-     * @return an {@link AndroidManifestParser} or null if parsing failed
-     */
-    public static AndroidManifestWriter parse(String osManifestFilePath) {
-        try {
-            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
-            docFactory.setNamespaceAware(true);
-            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
-            Document doc = docBuilder.parse(osManifestFilePath);
-            return new AndroidManifestWriter(doc, osManifestFilePath);
-        } catch (ParserConfigurationException e) {
-            sLogger.log(Level.SEVERE, "Error parsing file", e);
-            return null;
-        } catch (SAXException e) {
-            sLogger.log(Level.SEVERE, "Error parsing file", e);
-            return null;
-        } catch (IOException e) {
-            sLogger.log(Level.SEVERE, "Error parsing file", e);
-            return null;
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
deleted file mode 100644
index 89421ef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests.functests.sampleProjects;
-
-import com.android.ide.eclipse.adt.AndroidConstants;
-import com.android.ide.eclipse.adt.wizards.newproject.StubProjectWizard;
-import com.android.ide.eclipse.tests.AdtSdkTestCase;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.swt.widgets.Display;
-
-import java.io.File;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Test case that verifies all SDK sample projects can be imported, and built in
- * Eclipse.
- * <p/>
- * TODO: add support for deploying apps onto emulator and verifying successful
- * execution there
- *
- */
-public class SampleProjectTest extends AdtSdkTestCase {
-
-    private static final Logger sLogger = Logger.getLogger(SampleProjectTest.class.getName());
-
-    /**
-     * Finds all samples projects in set SDK and verify they can be built in Eclipse.
-     * <p/>
-     * TODO: add install and run on emulator test
-     * @throws CoreException
-     */
-    public void testSamples() throws CoreException {
-        // TODO: For reporting purposes, it would be better if a separate test success or failure
-        // could be reported for each sample
-        IAndroidTarget[] targets = getSdk().getTargets();
-        for (IAndroidTarget target : targets) {
-            doTestSamplesForTarget(target);
-        }
-    }
-
-    private void doTestSamplesForTarget(IAndroidTarget target) throws CoreException {
-        String path = target.getPath(IAndroidTarget.SAMPLES);
-        File samples = new File(path);
-        if (samples.isDirectory()) {
-            File[] files = samples.listFiles();
-            for (File file : files) {
-                if (file.isDirectory()) {
-                    doTestSampleProject(file.getName(), file.getAbsolutePath(), target);
-                }
-            }
-        }
-    }
-
-    /**
-     * Tests the sample project with the given name
-     *
-     * @param target - SDK target of project
-     * @param name - name of sample project to test
-     * @param path - absolute file system path
-     * @throws CoreException
-     */
-    private void doTestSampleProject(String name, String path, IAndroidTarget target)
-             throws CoreException {
-        IProject iproject = null;
-        try {
-            sLogger.log(Level.INFO, String.format("Testing sample %s for target %s", name,
-                    target.getName()));
-
-            prepareProject(path, target);
-
-            final StubProjectWizard newProjCreator = new StubProjectWizard(
-                    name, path, target);
-            newProjCreator.init(null, null);
-            // need to run finish on ui thread since it invokes a perspective switch
-            Display.getDefault().syncExec(new Runnable() {
-                public void run() {
-                    newProjCreator.performFinish();
-                }
-            });
-
-            iproject = validateProjectExists(name);
-            validateNoProblems(iproject);
-        }
-        catch (CoreException e) {
-            sLogger.log(Level.SEVERE,
-                    String.format("Unexpected exception when creating sample project %s " +
-                            "for target %s", name, target.getName()));
-            throw e;
-        } finally {
-            if (iproject != null) {
-                iproject.delete(false, true, new NullProgressMonitor());
-            }
-        }
-    }
-
-    private void prepareProject(String path, IAndroidTarget target) {
-        if (target.getVersion().isPreview()) {
-            // need to explicitly set preview's version in manifest for project to compile
-            final String manifestPath = path + File.separatorChar +
-                    AndroidConstants.FN_ANDROID_MANIFEST;
-            AndroidManifestWriter manifestWriter =
-                AndroidManifestWriter.parse(manifestPath);
-            assertNotNull(String.format("could not read manifest %s", manifestPath),
-                    manifestWriter);
-            assertTrue(manifestWriter.setMinSdkVersion(target.getVersion().getApiString()));
-        }
-    }
-
-    private IProject validateProjectExists(String name) {
-        IProject iproject = getIProject(name);
-        assertTrue(String.format("%s project not created", name), iproject.exists());
-        assertTrue(String.format("%s project not opened", name), iproject.isOpen());
-        return iproject;
-    }
-
-    private IProject getIProject(String name) {
-        IProject iproject = ResourcesPlugin.getWorkspace().getRoot()
-                .getProject(name);
-        return iproject;
-    }
-
-    private void validateNoProblems(IProject iproject) throws CoreException {
-        waitForBuild(iproject);
-
-        boolean hasErrors = false;
-        StringBuilder failureBuilder = new StringBuilder(String.format("%s project has errors:",
-                iproject.getName()));
-        IMarker[] markers = iproject.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
-        if (markers != null && markers.length > 0) {
-            // the project has marker(s). even though they are "problem" we
-            // don't know their severity. so we loop on them and figure if they
-            // are warnings or errors
-            for (IMarker m : markers) {
-                int s = m.getAttribute(IMarker.SEVERITY, -1);
-                if (s == IMarker.SEVERITY_ERROR) {
-                    hasErrors = true;
-                    failureBuilder.append("\n");
-                    failureBuilder.append(m.getAttribute(IMarker.MESSAGE, ""));
-                }
-            }
-        }
-        assertFalse(failureBuilder.toString(), hasErrors);
-    }
-
-    /**
-     * Waits for build to complete.
-     *
-     * @param iproject
-     */
-    private void waitForBuild(final IProject iproject) {
-
-        final BuiltProjectDeltaVisitor deltaVisitor = new BuiltProjectDeltaVisitor(iproject);
-        IResourceChangeListener newBuildListener = new IResourceChangeListener() {
-
-            public void resourceChanged(IResourceChangeEvent event) {
-                try {
-                    event.getDelta().accept(deltaVisitor);
-                }
-                catch (CoreException e) {
-                    fail();
-                }
-            }
-
-        };
-        iproject.getWorkspace().addResourceChangeListener(newBuildListener,
-          IResourceChangeEvent.POST_BUILD);
-
-        // poll build listener to determine when build is done
-        // loop max of 1200 times * 50 ms = 60 seconds
-        final int maxWait = 1200;
-        for (int i=0; i < maxWait; i++) {
-            if (deltaVisitor.isProjectBuilt()) {
-                return;
-            }
-            try {
-                Thread.sleep(50);
-            }
-            catch (InterruptedException e) {
-                // ignore
-            }
-           if (Display.getCurrent() != null) {
-               Display.getCurrent().readAndDispatch();
-           }
-        }
-
-        sLogger.log(Level.SEVERE, "expected build event never happened?");
-        fail(String.format("Expected build event never happened for %s", iproject.getName()));
-    }
-
-    /**
-     * Scans a given IResourceDelta looking for a "build event" change for given IProject
-     *
-     */
-    private class BuiltProjectDeltaVisitor implements IResourceDeltaVisitor {
-
-        private IProject mIProject;
-        private boolean  mIsBuilt;
-
-        public BuiltProjectDeltaVisitor(IProject iproject) {
-            mIProject = iproject;
-            mIsBuilt = false;
-        }
-
-        public boolean visit(IResourceDelta delta) {
-            if (mIProject.equals(delta.getResource())) {
-                setBuilt(true);
-                return false;
-            }
-            return true;
-        }
-
-        private synchronized void setBuilt(boolean b) {
-            mIsBuilt = b;
-        }
-
-        public synchronized boolean isProjectBuilt() {
-            return mIsBuilt;
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/test.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/test.xml
deleted file mode 100644
index 7fd3b0d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/test.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- test launcher file for Android Eclipse tests -->
-<project name="testsuite" default="run" basedir="."> 
-    <!--The following properties should be passed into this script, set to some default value for now -->
-    <property name="eclipse.home" value="/opt/eclipse" />
-    <property name="sdk_home" value="/tmp/sdk" />
-    <property name="eclipse_test" value="${eclipse.home}/plugins/org.eclipse.test_3.2.0" />
-	
-    <!-- eclipse scripts use an annoying mixture of eclipse-home and eclipse.home -->
-    <!-- lets define both...-->
-    <property name="eclipse-home" value="${eclipse.home}" />
-    <property name="test-folder" value="${eclipse.home}/test_folder" />
-        
-    <!-- sets the properties eclipse.home, and library-file -->
-    <property name="plugin-name" value="com.android.ide.eclipse.tests" />
-    <property name="library-file" value="${eclipse_test}/library.xml" />
-
-    <!-- location of adt preference file (within workspace) -->
-    <property name="prefs_path" value="${test-folder}/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs" />
-    <!-- location of pref template file relative to this file -->
-
-    <property name="prefs_template" value="prefs.template" />
-
-    <!-- This target holds all initialization code that needs to be done for -->
-    <!-- all tests that are to be run.         -->
-    <target name="init">
-        <tstamp />
-        <echo message="eclipse.home:  ${eclipse.home}" />
-        <echo message="libfile:  ${library-file}" />
-        
-        <!-- delete test eclipse workspace -->
-        <delete dir="${test-folder}" quiet="true" />
-    	
-    	<!-- delete test results dir -->
-    	<delete dir="${eclipse.home}/results" quiet="true" />
-
-        <!-- Copy a preference file into the test workspace. -->
-        <!-- This is done to ensure Android SDK preference is set on startup -->
-        <copy file="${prefs_template}" tofile="${prefs_path}" />
-        <!-- replace sdk path placeholder token with actual sdk path -->
-        <replace file="${prefs_path}" token="sdk_home" value="${sdk_home}" />
-        
-        <!-- if this is on windows, escape the drive and file separators -->
-        <replace file="${prefs_path}" token="\" value="\\" />
-        <replace file="${prefs_path}" token=":" value="\:" />
-    </target>
-
-    <!-- This target defines the tests that need to be run. -->
-    <target name="suite">
-        <!-- launch as ui-test ie as a test which needs Eclipse workbench -->
-        <ant target="ui-test" antfile="${library-file}" dir="${eclipse.home}">
-            <property name="data-dir" value="${test-folder}" />
-            <property name="plugin-name" value="${plugin-name}" />
-            <property name="classname" value="com.android.ide.eclipse.tests.AllTests" />
-            <!-- pass extra vm arg to set sdk_home env and test_data env variable -->
-            <property name="extraVMargs" value="-Dsdk_home=${sdk_home} -Dtest_data=${test_data}" />
-        </ant>
-    </target>
-
-    <!-- This target holds code to cleanup the testing environment after -->
-    <!-- after all of the tests have been run. You can use this target to -->
-    <!-- delete temporary files that have been created. -->
-    <target name="cleanup">
-    </target>
-
-    <!-- This target runs the test suite. Any actions that need to happen -->
-    <!-- after all the tests have been run should go here. -->
-    <target name="run" depends="init,suite,cleanup">
-        <ant target="collect" antfile="${library-file}" dir="${eclipse.home}/results">
-            <property name="includes" value="com*.xml" />
-            <property name="output-file" value="${plugin-name}.xml" />
-        </ant>
-    </target>
-</project>
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittest.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittest.xml
deleted file mode 100644
index 83e00ec..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittest.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- test launcher file for Android Eclipse unit tests -->
-<project name="testsuite" default="run" basedir="."> 
-    <!--The following properties should be passed into this script, set to some default value for now -->
-    <property name="eclipse.home" value="/opt/eclipse" />
-    <property name="eclipse_test" value="${eclipse.home}/plugins/org.eclipse.test_3.2.0" />
-
-    <!-- eclipse scripts use an annoying mixture of eclipse-home and eclipse.home -->
-    <!-- lets define both...-->
-    <property name="eclipse-home" value="${eclipse.home}" />
-    <property name="test-folder" value="${eclipse.home}/unittest_ws" />
-        
-    <!-- sets the properties eclipse.home, and library-file -->
-    <property name="plugin-name" value="com.android.ide.eclipse.tests" />
-    <property name="library-file" value="${eclipse_test}/library.xml" />
-	
-    <!-- This target holds all initialization code that needs to be done for -->
-    <!-- all tests that are to be run.         -->
-    <target name="init">
-    	<ant antfile="test.xml" target="init">
-    		<property name="test-folder" value="${test-folder}" />
-        </ant>
-    </target>
-
-    <!-- This target defines the tests that need to be run. -->
-    <target name="suite">
-        <!-- need to launch as ui-test since all ADT plugins depend on ui-->
-    	<!-- otherwise other plugins will not load -->
-        <ant target="ui-test" antfile="${library-file}" dir="${eclipse.home}">
-            <property name="data-dir" value="${test-folder}" />
-            <property name="plugin-name" value="${plugin-name}" />
-            <property name="classname" value="com.android.ide.eclipse.tests.UnitTests" />
-            <!-- pass extra vm arg to set test_data env variable -->
-            <property name="extraVMargs" value="-Dtest_data=${test_data}" />
-        </ant>
-    </target>
-
-    <!-- This target holds code to cleanup the testing environment after -->
-    <!-- after all of the tests have been run. You can use this target to -->
-    <!-- delete temporary files that have been created. -->
-    <target name="cleanup">
-    </target>
-
-    <!-- This target runs the test suite. Any actions that need to happen -->
-    <!-- after all the tests have been run should go here. -->
-    <target name="run" depends="init,suite,cleanup">
-        <ant target="collect" antfile="${library-file}" dir="${eclipse.home}/results">
-            <property name="includes" value="com*.xml" />
-            <property name="output-file" value="${plugin-name}.xml" />
-        </ant>
-    </target>
-</project>
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/build/BaseBuilderTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/build/BaseBuilderTest.java
deleted file mode 100644
index a1d658b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/build/BaseBuilderTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import junit.framework.TestCase;
-
-public class BaseBuilderTest extends TestCase {
-
-    public void testParseAaptOutput() {
-        Pattern p = Pattern.compile( "^(.+):(\\d+):\\s(.+)$"); //$NON-NLS-1$
-        String s = "C:\\java\\workspace-android\\AndroidApp\\res\\values\\strings.xml:11: WARNING: empty 'some warning text";
-
-        Matcher m = p.matcher(s);
-        assertEquals(true, m.matches());
-        assertEquals("C:\\java\\workspace-android\\AndroidApp\\res\\values\\strings.xml", m.group(1));
-        assertEquals("11", m.group(2));
-        assertEquals("WARNING: empty 'some warning text", m.group(3));
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtilsTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtilsTest.java
deleted file mode 100644
index 42bf7ae..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtilsTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.ide.eclipse.adt.internal.editors.descriptors;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for DescriptorsUtils in the editors plugin
- */
-public class DescriptorsUtilsTest extends TestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testPrettyAttributeUiName() {
-        assertEquals("", DescriptorsUtils.prettyAttributeUiName(""));
-
-        assertEquals("Max width for view",
-                DescriptorsUtils.prettyAttributeUiName("maxWidthForView"));
-
-        assertEquals("Layout width",
-                DescriptorsUtils.prettyAttributeUiName("layout_width"));
-
-        // X Y and Z are capitalized when used as single words (so "T" becomes "t")
-        assertEquals("Axis X", DescriptorsUtils.prettyAttributeUiName("axisX"));
-        assertEquals("Axis Y", DescriptorsUtils.prettyAttributeUiName("axisY"));
-        assertEquals("Axis Z", DescriptorsUtils.prettyAttributeUiName("axisZ"));
-        assertEquals("Axis t", DescriptorsUtils.prettyAttributeUiName("axisT"));
-
-        assertEquals("The X axis", DescriptorsUtils.prettyAttributeUiName("theXAxis"));
-        assertEquals("The Y axis", DescriptorsUtils.prettyAttributeUiName("theYAxis"));
-        assertEquals("The Z axis", DescriptorsUtils.prettyAttributeUiName("theZAxis"));
-        assertEquals("The t axis", DescriptorsUtils.prettyAttributeUiName("theTAxis"));
-    }
-
-    public void testCapitalize() {
-        assertEquals("UPPER", DescriptorsUtils.capitalize("UPPER"));
-        assertEquals("Lower", DescriptorsUtils.capitalize("lower"));
-        assertEquals("Capital", DescriptorsUtils.capitalize("Capital"));
-        assertEquals("CamelCase", DescriptorsUtils.capitalize("camelCase"));
-        assertEquals("", DescriptorsUtils.capitalize(""));
-    }
-
-    public void testFormatTooltip() {
-        assertEquals("", DescriptorsUtils.formatTooltip(""));
-
-        assertEquals("\"application\"",
-                DescriptorsUtils.formatTooltip(
-                        "<code>application</code>"));
-
-        assertEquals("android.content.Intent",
-                DescriptorsUtils.formatTooltip(
-                        "{@link android.content.Intent}"));
-        
-        assertEquals("FLAG_ACTIVITY_SINGLE_TOP",
-                DescriptorsUtils.formatTooltip(
-                        "{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}"));
-        
-        assertEquals("activity-alias",
-                DescriptorsUtils.formatTooltip(
-                        "{@link \t  #AndroidManifestActivityAlias  \tactivity-alias }"));
-        
-        assertEquals("\"permission\"",
-                DescriptorsUtils.formatTooltip(
-                        "{@link #AndroidManifestPermission &lt;permission&gt;}"));
-        
-        assertEquals("and etc.",
-                DescriptorsUtils.formatTooltip(
-                        "{@link #IntentCategory <category> and etc. }"));
-        
-        assertEquals("Activity.onNewIntent()",
-                DescriptorsUtils.formatTooltip(
-                        "{@link android.app.Activity#onNewIntent Activity.onNewIntent()}"));
-    }
-
-    public void testFormatFormText() {
-        ElementDescriptor desc = new ElementDescriptor("application");
-        desc.setSdkUrl(DescriptorsUtils.MANIFEST_SDK_URL + "TagApplication");
-        String docBaseUrl = "http://base";
-        assertEquals("<form><li style=\"image\" value=\"image\"></li></form>", DescriptorsUtils.formatFormText("", desc, docBaseUrl));
-
-        assertEquals("<form><li style=\"image\" value=\"image\"><a href=\"http://base/reference/android/R.styleable.html#TagApplication\">application</a></li></form>",
-                DescriptorsUtils.formatFormText(
-                        "<code>application</code>",
-                        desc, docBaseUrl));
-
-        assertEquals("<form><li style=\"image\" value=\"image\"><b>android.content.Intent</b></li></form>",
-                DescriptorsUtils.formatFormText(
-                        "{@link android.content.Intent}",
-                        desc, docBaseUrl));
-
-        assertEquals("<form><li style=\"image\" value=\"image\"><a href=\"http://base/reference/android/R.styleable.html#AndroidManifestPermission\">AndroidManifestPermission</a></li></form>",
-                DescriptorsUtils.formatFormText(
-                        "{@link #AndroidManifestPermission}",
-                        desc, docBaseUrl));
-
-        assertEquals("<form><li style=\"image\" value=\"image\"><a href=\"http://base/reference/android/R.styleable.html#AndroidManifestPermission\">\"permission\"</a></li></form>",
-                DescriptorsUtils.formatFormText(
-                        "{@link #AndroidManifestPermission &lt;permission&gt;}",
-                        desc, docBaseUrl));
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParserTest.java
deleted file mode 100644
index e234d6b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParserTest.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.layout;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.layout.UiElementPullParser;
-import com.android.ide.eclipse.adt.internal.editors.mock.MockXmlNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.sdklib.SdkConstants;
-
-import org.w3c.dom.Node;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.util.HashMap;
-
-import junit.framework.TestCase;
-
-public class UiElementPullParserTest extends TestCase {
-
-    private UiElementNode ui;
-    private HashMap<String, String> button1Map;
-    private HashMap<String, String> button2Map;
-    private HashMap<String, String> textMap;
-
-    @Override
-    protected void setUp() throws Exception {
-        // set up some basic descriptors.
-        // We have button, textview, linear layout, relative layout.
-        // only the layouts have children (all 4 descriptors possible)
-        // Also add some dummy attributes.
-        ElementDescriptor buttonDescriptor = new ElementDescriptor("Button", "Button", "", "",
-                new AttributeDescriptor[] {
-                    new TextAttributeDescriptor("name", "name", SdkConstants.NS_RESOURCES, ""),
-                    new TextAttributeDescriptor("text", "text", SdkConstants.NS_RESOURCES, ""),
-                    },
-                new ElementDescriptor[] {}, false);
-
-        ElementDescriptor textDescriptor = new ElementDescriptor("TextView", "TextView", "", "",
-                new AttributeDescriptor[] {
-                new TextAttributeDescriptor("name", "name", SdkConstants.NS_RESOURCES, ""),
-                new TextAttributeDescriptor("text", "text", SdkConstants.NS_RESOURCES, ""), },
-                new ElementDescriptor[] {}, false);
-
-        ElementDescriptor linearDescriptor = new ElementDescriptor("LinearLayout", "Linear Layout",
-                "", "",
-                new AttributeDescriptor[] {
-                    new TextAttributeDescriptor("orientation", "orientation",
-                            SdkConstants.NS_RESOURCES, ""),
-                },
-                new ElementDescriptor[] { }, false);
-
-        ElementDescriptor relativeDescriptor = new ElementDescriptor("RelativeLayout",
-                "Relative Layout", "", "",
-                new AttributeDescriptor[] {
-                    new TextAttributeDescriptor("orientation", "orientation",
-                            SdkConstants.NS_RESOURCES, ""),
-                },
-                new ElementDescriptor[] { }, false);
-
-        ElementDescriptor[] a = new ElementDescriptor[] {
-                buttonDescriptor, textDescriptor, linearDescriptor, relativeDescriptor
-        };
-        
-        linearDescriptor.setChildren(a);
-        relativeDescriptor.setChildren(a);
-
-        // document descriptor
-        ElementDescriptor rootDescriptor = new ElementDescriptor("root", "", "", "",
-                new AttributeDescriptor[] { }, a, false);
-
-        
-        ui = new UiElementNode(rootDescriptor);
-        
-        /* create a dummy XML file.
-         * <LinearLayout android:orientation="vertical">
-         *      <Button android:name="button1" android:text="button1text"/>
-         *      <RelativeLayout android:orientation="toto">
-         *          <Button android:name="button2" android:text="button2text"/>
-         *          <TextView android:name="text1" android:text="text1text"/>
-         *      </RelativeLayout>
-         * </LinearLayout>
-         */
-        MockXmlNode button1 = new MockXmlNode(null /* namespace */, "Button", Node.ELEMENT_NODE,
-                null);
-        button1.addAttributes(SdkConstants.NS_RESOURCES, "name", "button1");
-        button1.addAttributes(SdkConstants.NS_RESOURCES, "text", "button1text");
-        
-        // create a map of the attributes we add to the multi-attribute nodes so that
-        // we can more easily test the values when we parse the XML.
-        // This is due to some attributes showing in a certain order for a node and in a different
-        // order in another node. Since the order doesn't matter, we just simplify the test.
-        button1Map = new HashMap<String, String>();
-        button1Map.put("name", "button1");
-        button1Map.put("text", "button1text");
-
-        MockXmlNode button2 = new MockXmlNode(null /* namespace */, "Button", Node.ELEMENT_NODE,
-                null);
-        button2.addAttributes(SdkConstants.NS_RESOURCES, "name", "button2");
-        button2.addAttributes(SdkConstants.NS_RESOURCES, "text", "button2text");
-
-        button2Map = new HashMap<String, String>();
-        button2Map.put("name", "button2");
-        button2Map.put("text", "button2text");
-        
-        MockXmlNode text = new MockXmlNode(null /* namespace */, "TextView", Node.ELEMENT_NODE,
-                null);
-        text.addAttributes(SdkConstants.NS_RESOURCES, "name", "text1");
-        text.addAttributes(SdkConstants.NS_RESOURCES, "text", "text1text");
-
-        textMap = new HashMap<String, String>();
-        textMap.put("name", "text1");
-        textMap.put("text", "text1text");
-
-        MockXmlNode relative = new MockXmlNode(null /* namespace */, "RelativeLayout",
-                Node.ELEMENT_NODE, new MockXmlNode[] { button2, text });
-        relative.addAttributes(SdkConstants.NS_RESOURCES, "orientation", "toto");
-        
-        MockXmlNode linear = new MockXmlNode(null /* namespace */, "LinearLayout",
-                Node.ELEMENT_NODE, new MockXmlNode[] { button1, relative });
-        linear.addAttributes(SdkConstants.NS_RESOURCES, "orientation", "vertical");
-        
-        MockXmlNode root = new MockXmlNode(null /* namespace */, "root", Node.ELEMENT_NODE,
-                new MockXmlNode[] { linear });
-        
-        // put the namespace/prefix in place
-        root.setPrefix(SdkConstants.NS_RESOURCES, "android");
-
-        // load the xml into the UiElementNode
-        ui.loadFromXmlNode(root);
-
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-    
-    public void testParser() {
-        try {
-            // wrap the parser around the ui element node, and start parsing
-            UiElementPullParser parser = new UiElementPullParser(ui);
-            
-            assertEquals(XmlPullParser.START_DOCUMENT, parser.getEventType());
-            
-            // top level Linear layout
-            assertEquals(XmlPullParser.START_TAG, parser.next());
-            assertEquals("LinearLayout", parser.getName());
-            assertEquals(1, parser.getAttributeCount());
-            assertEquals("orientation", parser.getAttributeName(0));
-            assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(0));
-            assertEquals("android", parser.getAttributePrefix(0));
-            assertEquals("vertical", parser.getAttributeValue(0));
-            
-            // Button
-            assertEquals(XmlPullParser.START_TAG, parser.next());
-            assertEquals("Button", parser.getName());
-            assertEquals(2, parser.getAttributeCount());
-            check(parser, 0, button1Map);
-            check(parser, 1, button1Map);
-            // end of button
-            assertEquals(XmlPullParser.END_TAG, parser.next());
-
-            // Relative Layout
-            assertEquals(XmlPullParser.START_TAG, parser.next());
-            assertEquals("RelativeLayout", parser.getName());
-            assertEquals(1, parser.getAttributeCount());
-            assertEquals("orientation", parser.getAttributeName(0));
-            assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(0));
-            assertEquals("android", parser.getAttributePrefix(0));
-            assertEquals("toto", parser.getAttributeValue(0));
-
-            // Button
-            assertEquals(XmlPullParser.START_TAG, parser.next());
-            assertEquals("Button", parser.getName());
-            assertEquals(2, parser.getAttributeCount());
-            check(parser, 0, button2Map);
-            check(parser, 1, button2Map);
-            // end of button
-            assertEquals(XmlPullParser.END_TAG, parser.next());
-
-            // TextView
-            assertEquals(XmlPullParser.START_TAG, parser.next());
-            assertEquals("TextView", parser.getName());
-            assertEquals(2, parser.getAttributeCount());
-            check(parser, 0, textMap);
-            check(parser, 1, textMap);
-            // end of TextView
-            assertEquals(XmlPullParser.END_TAG, parser.next());
-            
-            // end of RelativeLayout
-            assertEquals(XmlPullParser.END_TAG, parser.next());
-
-            
-            // end of top level linear layout
-            assertEquals(XmlPullParser.END_TAG, parser.next());
-            
-            assertEquals(XmlPullParser.END_DOCUMENT, parser.next());
-        } catch (XmlPullParserException e) {
-            e.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Receives a {@link XmlPullParser} at the START_TAG level, and checks the i-th attribute
-     * to be present in the {@link HashMap} with the proper (name, value)
-     * @param parser
-     * @param i
-     * @param map
-     */
-    private void check(UiElementPullParser parser, int i, HashMap<String, String> map) {
-        String name = parser.getAttributeName(i);
-        String value = parser.getAttributeValue(i);
-        
-        String referenceValue = map.get(name);
-        assertNotNull(referenceValue);
-        assertEquals(referenceValue, value);
-        
-        assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(i));
-        assertEquals("android", parser.getAttributePrefix(i));
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiElementNodeTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiElementNodeTest.java
deleted file mode 100644
index ac3d8d5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiElementNodeTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.manifest.model;
-
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.mock.MockXmlNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-
-import org.w3c.dom.Node;
-
-import java.util.Iterator;
-
-import junit.framework.TestCase;
-
-public class UiElementNodeTest extends TestCase {
-
-    private ElementDescriptor e;
-    private UiElementNode ui;
-
-    @Override
-    protected void setUp() throws Exception {
-        e = new ElementDescriptor("manifest", new ElementDescriptor[] {
-                new ElementDescriptor("application", new ElementDescriptor[] {
-                    new ElementDescriptor("provider"), 
-                    new ElementDescriptor("activity", new ElementDescriptor[] {
-                        new ElementDescriptor("intent-filter")
-                    }), 
-                }), 
-                new ElementDescriptor("permission")
-            });
-        
-        ui = new UiElementNode(e);
-        
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        // pass
-    }
-
-    /**
-     * Check initialization values for ui node
-     */
-    public void testInit() {
-        assertSame(e, ui.getDescriptor());
-        assertNull(ui.getUiParent());
-        assertEquals(0, ui.getUiChildren().size());
-        assertEquals(0, ui.getUiAttributes().size());
-    }
-    
-    /**
-     * loadFrom() does nothing if the root node doesn't match what's expected
-     */
-    public void testLoadFrom_InvalidRoot() {
-        assertEquals(0, ui.getUiChildren().size());
-        MockXmlNode root = new MockXmlNode(null /* namespace */, "blah", Node.ELEMENT_NODE, null);
-        ui.loadFromXmlNode(root);
-        assertEquals(0, ui.getUiChildren().size());
-    }
-
-    /**
-     * UiElementNode.loadFrom should be used to populate an empty ui node from an
-     * existing XML node tree.
-     */
-    public void testLoadFrom_NewTree_1_Node() {
-        MockXmlNode root = new MockXmlNode(null /* namespace */, "manifest", Node.ELEMENT_NODE,
-            new MockXmlNode[] {
-                new MockXmlNode(null /* namespace */, "application", Node.ELEMENT_NODE, null)
-            });
-        
-        // get /manifest
-        ui.loadFromXmlNode(root);
-        assertEquals("manifest", ui.getDescriptor().getXmlName());
-        assertEquals(1, ui.getUiChildren().size());
-        assertEquals(0, ui.getUiAttributes().size());
-
-        // get /manifest/application
-        Iterator<UiElementNode> ui_child_it = ui.getUiChildren().iterator();
-        UiElementNode application = ui_child_it.next();
-        assertEquals("application", application.getDescriptor().getXmlName());
-        assertEquals(0, application.getUiChildren().size());
-        assertEquals(0, application.getUiAttributes().size());
-    }
-
-
-    public void testLoadFrom_NewTree_2_Nodes() {
-        MockXmlNode root = new MockXmlNode(null /* namespace */, "manifest", Node.ELEMENT_NODE,
-            new MockXmlNode[] {
-                new MockXmlNode(null /* namespace */, "application", Node.ELEMENT_NODE, null),
-                new MockXmlNode(null /* namespace */, "permission", Node.ELEMENT_NODE, null),
-            });
-        
-        // get /manifest
-        ui.loadFromXmlNode(root);
-        assertEquals("manifest", ui.getDescriptor().getXmlName());
-        assertEquals(2, ui.getUiChildren().size());
-        assertEquals(0, ui.getUiAttributes().size());
-
-        // get /manifest/application
-        Iterator<UiElementNode> ui_child_it = ui.getUiChildren().iterator();
-        UiElementNode application = ui_child_it.next();
-        assertEquals("application", application.getDescriptor().getXmlName());
-        assertEquals(0, application.getUiChildren().size());
-        assertEquals(0, application.getUiAttributes().size());
-
-        // get /manifest/permission
-        UiElementNode first_permission = ui_child_it.next();
-        assertEquals("permission", first_permission.getDescriptor().getXmlName());
-        assertEquals(0, first_permission.getUiChildren().size());
-        assertEquals(0, first_permission.getUiAttributes().size());
-    }
-
-    public void testLoadFrom_NewTree_N_Nodes() {
-        MockXmlNode root = new MockXmlNode(null /* namespace */, "manifest", Node.ELEMENT_NODE,
-            new MockXmlNode[] {
-                new MockXmlNode(null /* namespace */, "application", Node.ELEMENT_NODE,
-                    new MockXmlNode[] {
-                        new MockXmlNode(null /* namespace */, "activity", Node.ELEMENT_NODE,
-                            null),
-                        new MockXmlNode(null /* namespace */, "activity", Node.ELEMENT_NODE,
-                            new MockXmlNode[] {
-                                new MockXmlNode(null /* namespace */, "intent-filter",
-                                        Node.ELEMENT_NODE, null),
-                            }),
-                        new MockXmlNode(null /* namespace */, "provider", Node.ELEMENT_NODE,
-                                null),
-                        new MockXmlNode(null /* namespace */, "provider", Node.ELEMENT_NODE,
-                                null),
-                    }),
-                new MockXmlNode(null /* namespace */, "permission", Node.ELEMENT_NODE,
-                        null),
-                new MockXmlNode(null /* namespace */, "permission", Node.ELEMENT_NODE,
-                        null),
-            });
-        
-        // get /manifest
-        ui.loadFromXmlNode(root);
-        assertEquals("manifest", ui.getDescriptor().getXmlName());
-        assertEquals(3, ui.getUiChildren().size());
-        assertEquals(0, ui.getUiAttributes().size());
-
-        // get /manifest/application
-        Iterator<UiElementNode> ui_child_it = ui.getUiChildren().iterator();
-        UiElementNode application = ui_child_it.next();
-        assertEquals("application", application.getDescriptor().getXmlName());
-        assertEquals(4, application.getUiChildren().size());
-        assertEquals(0, application.getUiAttributes().size());
-
-        // get /manifest/application/activity #1
-        Iterator<UiElementNode> app_child_it = application.getUiChildren().iterator();
-        UiElementNode first_activity = app_child_it.next();
-        assertEquals("activity", first_activity.getDescriptor().getXmlName());
-        assertEquals(0, first_activity.getUiChildren().size());
-        assertEquals(0, first_activity.getUiAttributes().size());
-
-        // get /manifest/application/activity #2
-        UiElementNode second_activity = app_child_it.next();
-        assertEquals("activity", second_activity.getDescriptor().getXmlName());
-        assertEquals(1, second_activity.getUiChildren().size());
-        assertEquals(0, second_activity.getUiAttributes().size());
-
-        // get /manifest/application/activity #2/intent-filter #1
-        Iterator<UiElementNode> activity_child_it = second_activity.getUiChildren().iterator();
-        UiElementNode intent_filter = activity_child_it.next();
-        assertEquals("intent-filter", intent_filter.getDescriptor().getXmlName());
-        assertEquals(0, intent_filter.getUiChildren().size());
-        assertEquals(0, intent_filter.getUiAttributes().size());
-
-        // get /manifest/application/provider #1
-        UiElementNode first_provider = app_child_it.next();
-        assertEquals("provider", first_provider.getDescriptor().getXmlName());
-        assertEquals(0, first_provider.getUiChildren().size());
-        assertEquals(0, first_provider.getUiAttributes().size());
-
-        // get /manifest/application/provider #2
-        UiElementNode second_provider = app_child_it.next();
-        assertEquals("provider", second_provider.getDescriptor().getXmlName());
-        assertEquals(0, second_provider.getUiChildren().size());
-        assertEquals(0, second_provider.getUiAttributes().size());
-        
-        // get /manifest/permission #1
-        UiElementNode first_permission = ui_child_it.next();
-        assertEquals("permission", first_permission.getDescriptor().getXmlName());
-        assertEquals(0, first_permission.getUiChildren().size());
-        assertEquals(0, first_permission.getUiAttributes().size());
-
-        // get /manifest/permission #1
-        UiElementNode second_permission = ui_child_it.next();
-        assertEquals("permission", second_permission.getDescriptor().getXmlName());
-        assertEquals(0, second_permission.getUiChildren().size());
-        assertEquals(0, second_permission.getUiAttributes().size());
-    }
-    
-    
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNamedNodeMap.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNamedNodeMap.java
deleted file mode 100644
index cf05b2a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNamedNodeMap.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.mock;
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-class MockNamedNodeMap implements NamedNodeMap {
-    
-    /** map for access by namespace/name */
-    private final HashMap<String, HashMap<String, Node>> mNodeMap =
-        new HashMap<String, HashMap<String, Node>>();
-    
-    /** list for access by index */
-    private final ArrayList<Node> mNodeList = new ArrayList<Node>();
-     
-    public MockXmlNode addAttribute(String namespace, String localName, String value) {
-        MockXmlNode node = new MockXmlNode(namespace, localName, value);
-
-        if (namespace == null) {
-            namespace = ""; // no namespace
-        }
-        
-        // get the map for the namespace
-        HashMap<String, Node> map = mNodeMap.get(namespace);
-        if (map == null) {
-            map = new HashMap<String, Node>();
-            mNodeMap.put(namespace, map);
-        }
-        
-        
-        map.put(localName, node);
-        mNodeList.add(node);
-        
-        return node;
-    }
-    
-    // --------- NamedNodeMap -------
-
-    public int getLength() {
-        return mNodeList.size();
-    }
-
-    public Node getNamedItem(String name) {
-        HashMap<String, Node> map = mNodeMap.get(""); // no namespace
-        if (map != null) {
-            return map.get(name);
-        }
-        
-        return null;
-    }
-
-    public Node getNamedItemNS(String namespaceURI, String localName) throws DOMException {
-        if (namespaceURI == null) {
-            namespaceURI = ""; //no namespace
-        }
-        
-        HashMap<String, Node> map = mNodeMap.get(namespaceURI);
-        if (map != null) {
-            return map.get(localName);
-        }
-        
-        return null;
-    }
-
-    public Node item(int index) {
-        return mNodeList.get(index);
-    }
-
-    public Node removeNamedItem(String name) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public Node setNamedItem(Node arg) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public Node setNamedItemNS(Node arg) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNodeList.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNodeList.java
deleted file mode 100644
index def1993..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNodeList.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.mock;
-
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.util.ArrayList;
-
-
-/**
- * A quick mock implementation of NodeList on top of ArrayList.
- */
-public class MockNodeList implements NodeList {
-
-    ArrayList<MockXmlNode> mChildren;
-
-    /**
-    * Constructs a node list from a given children list.
-    * 
-    * @param children The children list. Can be null.
-     */
-    public MockNodeList(MockXmlNode[] children) {
-        mChildren = new ArrayList<MockXmlNode>();
-        if (children != null) {
-            for (MockXmlNode n : children) {
-                mChildren.add(n);
-            }
-        }
-    }
-
-    public int getLength() {
-        return mChildren.size();
-    }
-
-    public Node item(int index) {
-        if (index >= 0 && index < mChildren.size()) {
-            return mChildren.get(index);
-        }
-        return null;
-    }
-
-    public ArrayList<MockXmlNode> getArrayList() {
-        return mChildren;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockXmlNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockXmlNode.java
deleted file mode 100644
index 1ad7543..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockXmlNode.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.mock;
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.UserDataHandler;
-
-import java.util.HashMap;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-
-/**
- * A mock XML node with only a minimal set of information.
- */
-public class MockXmlNode implements Node {
-   
-    MockNodeList mNodeList;
-    private String mLocalName;
-    private String mNamespace;
-    private short mNodeType;
-    private MockXmlNode mParent;
-    private MockXmlNode mPreviousSibling;
-    private MockXmlNode mNextSibling;
-    private String mAttrValue;
-    private MockNamedNodeMap mAttributes;
-    
-    // namespace stuff only set in the root node
-    /** map from namespace to prefix. */
-    private HashMap<String, String> mNsMap = null;
-    
-    /**
-     * Constructs a node from a given children list.
-     * 
-     * @param namespace The namespace of the node or null if none
-     * @param localName The XML local node name.
-     * @param node_type One of Node.xxx_NODE constants, e.g. Node.ELEMENT_NODE
-     * @param children The children list. Can be null.
-     */
-    public MockXmlNode(String namespace, String localName, short node_type,
-            MockXmlNode[] children) {
-        mLocalName = localName;
-        mNamespace = namespace;
-        mNodeType = node_type;
-        mNodeList = new MockNodeList(children);
-        fixNavigation();
-    }
-
-    /**
-     * Constructs an attribute node
-     * 
-     * @param namespace The namespace of the node or null if none
-     * @param localName The XML local node name.
-     * @param value the value of the attribute
-     */
-    public MockXmlNode(String namespace, String localName, String value) {
-        mLocalName = localName;
-        mNamespace = namespace;
-        mAttrValue = value;
-        mNodeType = Node.ATTRIBUTE_NODE;
-        mNodeList = new MockNodeList(new MockXmlNode[0]);
-        fixNavigation();
-    }
-
-    private void fixNavigation() {
-        MockXmlNode prev = null;
-        for (MockXmlNode n : mNodeList.getArrayList()) {
-            n.mParent = this;
-            n.mPreviousSibling = prev;
-            if (prev != null) {
-                prev.mNextSibling = n;
-            }
-            n.fixNavigation();
-            prev = n;
-        }
-    }
-    
-    public void addAttributes(String namespaceURI, String localName, String value) {
-        if (mAttributes == null) {
-            mAttributes = new MockNamedNodeMap();
-        }
-        
-        MockXmlNode node = mAttributes.addAttribute(namespaceURI, localName, value);
-        node.mParent = this;
-    }
-    
-    public void setPrefix(String namespace, String prefix) {
-        if (mNsMap == null) {
-            mNsMap = new HashMap<String, String>();
-        }
-
-        mNsMap.put(namespace, prefix);
-    }
-    
-    public String getPrefix(String namespace) {
-        if (mNsMap != null) {
-            return mNsMap.get(namespace);
-        }
-        
-        return mParent.getPrefix(namespace);
-    }
-
-    
-    // ----------- Node methods
-
-    public Node appendChild(Node newChild) throws DOMException {
-        mNodeList.getArrayList().add((MockXmlNode) newChild);
-        return newChild;
-    }
-
-    public NamedNodeMap getAttributes() {
-        return mAttributes;
-    }
-
-    public NodeList getChildNodes() {
-        return mNodeList;
-    }
-
-    public Node getFirstChild() {
-        if (mNodeList.getLength() > 0) {
-            return mNodeList.item(0);
-        }
-        return null;
-    }
-
-    public Node getLastChild() {
-        if (mNodeList.getLength() > 0) {
-            return mNodeList.item(mNodeList.getLength() - 1);
-        }
-        return null;
-    }
-
-    public Node getNextSibling() {
-        return mNextSibling;
-    }
-
-    public String getNodeName() {
-        return mLocalName;
-    }
-    
-    public String getLocalName() {
-        return mLocalName;
-    }
-
-    public short getNodeType() {
-        return mNodeType;
-    }
-
-    public Node getParentNode() {
-        return mParent;
-    }
-
-    public Node getPreviousSibling() {
-        return mPreviousSibling;
-    }
-
-    public boolean hasChildNodes() {
-        return mNodeList.getLength() > 0;
-    }
-
-    public boolean hasAttributes() {
-        // TODO Auto-generated method stub
-        throw new NotImplementedException();
-        //return false;
-    }
-
-    public boolean isSameNode(Node other) {
-        return this == other;
-    }
-    
-    public String getNodeValue() throws DOMException {
-        return mAttrValue;
-    }
-    
-    public String getPrefix() {
-        return getPrefix(getNamespaceURI());
-    }
-
-    public String getNamespaceURI() {
-        return mNamespace;
-    }
-
-
-    // --- methods not implemented ---
-    
-    public Node cloneNode(boolean deep) {
-        throw new NotImplementedException();
-    }
-
-    public short compareDocumentPosition(Node other) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public String getBaseURI() {
-        throw new NotImplementedException();
-    }
-
-    public Object getFeature(String feature, String version) {
-        throw new NotImplementedException();
-    }
-
-    public Document getOwnerDocument() {
-        throw new NotImplementedException();
-    }
-
-    public String getTextContent() throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public Object getUserData(String key) {
-        throw new NotImplementedException();
-    }
-
-    public Node insertBefore(Node newChild, Node refChild)
-            throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isDefaultNamespace(String namespaceURI) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isEqualNode(Node arg) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isSupported(String feature, String version) {
-        throw new NotImplementedException();
-    }
-
-    public String lookupNamespaceURI(String prefix) {
-        throw new NotImplementedException();
-    }
-
-    public String lookupPrefix(String namespaceURI) {
-        throw new NotImplementedException();
-    }
-
-    public void normalize() {
-        throw new NotImplementedException();
-    }
-
-    public Node removeChild(Node oldChild) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public Node replaceChild(Node newChild, Node oldChild)
-            throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public void setNodeValue(String nodeValue) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public void setPrefix(String prefix) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public void setTextContent(String textContent) throws DOMException {
-        throw new NotImplementedException();
-    }
-
-    public Object setUserData(String key, Object data,
-            UserDataHandler handler) {
-        throw new NotImplementedException();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/CountryCodeQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/CountryCodeQualifierTest.java
deleted file mode 100644
index e0fe013..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/CountryCodeQualifierTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-
-import junit.framework.TestCase;
-
-public class CountryCodeQualifierTest extends TestCase {
-
-    private CountryCodeQualifier mccq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mccq = new CountryCodeQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mccq = null;
-        config = null;
-    }
-
-    public void testCheckAndSet() {
-        assertEquals(true, mccq.checkAndSet("mcc123", config));//$NON-NLS-1$
-        assertTrue(config.getCountryCodeQualifier() != null);
-        assertEquals(123, config.getCountryCodeQualifier().getCode());
-        assertEquals("mcc123", config.getCountryCodeQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, mccq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, mccq.checkAndSet("mcc", config));//$NON-NLS-1$
-        assertEquals(false, mccq.checkAndSet("MCC123", config));//$NON-NLS-1$
-        assertEquals(false, mccq.checkAndSet("123", config));//$NON-NLS-1$
-        assertEquals(false, mccq.checkAndSet("mccsdf", config));//$NON-NLS-1$
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/KeyboardStateQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/KeyboardStateQualifierTest.java
deleted file mode 100644
index 4953747..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/KeyboardStateQualifierTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
-
-import junit.framework.TestCase;
-
-public class KeyboardStateQualifierTest extends TestCase {
-
-    private KeyboardStateQualifier ksq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        ksq = new KeyboardStateQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        ksq = null;
-        config = null;
-    }
-
-    public void testExposed() {
-        assertEquals(true, ksq.checkAndSet("keysexposed", config)); //$NON-NLS-1$
-        assertTrue(config.getKeyboardStateQualifier() != null);
-        assertEquals(KeyboardStateQualifier.KeyboardState.EXPOSED,
-                config.getKeyboardStateQualifier().getValue());
-        assertEquals("keysexposed", config.getKeyboardStateQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testHidden() {
-        assertEquals(true, ksq.checkAndSet("keyshidden", config)); //$NON-NLS-1$
-        assertTrue(config.getKeyboardStateQualifier() != null);
-        assertEquals(KeyboardStateQualifier.KeyboardState.HIDDEN,
-                config.getKeyboardStateQualifier().getValue());
-        assertEquals("keyshidden", config.getKeyboardStateQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, ksq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, ksq.checkAndSet("KEYSEXPOSED", config));//$NON-NLS-1$
-        assertEquals(false, ksq.checkAndSet("other", config));//$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/LanguageQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/LanguageQualifierTest.java
deleted file mode 100644
index e4a9312..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/LanguageQualifierTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier;
-
-import junit.framework.TestCase;
-
-public class LanguageQualifierTest extends TestCase {
-    
-    private FolderConfiguration config;
-    private LanguageQualifier lq;
-
-    @Override
-    public void setUp()  throws Exception {
-        super.setUp();
-        config = new FolderConfiguration();
-        lq = new LanguageQualifier();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        config = null;
-        lq = null;
-    }
-    
-    public void testCheckAndSet() {
-        assertEquals(true, lq.checkAndSet("en", config)); //$NON-NLS-1$
-        assertTrue(config.getLanguageQualifier() != null);
-        assertEquals("en", config.getLanguageQualifier().toString()); //$NON-NLS-1$
-        
-    }
-    
-    public void testFailures() {
-        assertEquals(false, lq.checkAndSet("", config)); //$NON-NLS-1$
-        assertEquals(false, lq.checkAndSet("EN", config)); //$NON-NLS-1$
-        assertEquals(false, lq.checkAndSet("abc", config)); //$NON-NLS-1$
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NavigationMethodQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NavigationMethodQualifierTest.java
deleted file mode 100644
index 8e5d9ec..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NavigationMethodQualifierTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
-
-import junit.framework.TestCase;
-
-public class NavigationMethodQualifierTest extends TestCase {
-
-    private FolderConfiguration config;
-    private NavigationMethodQualifier nmq;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        config = new FolderConfiguration();
-        nmq = new NavigationMethodQualifier();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        config = null;
-        nmq = null;
-    }
-    
-    public void testDPad() {
-        assertEquals(true, nmq.checkAndSet("dpad", config)); //$NON-NLS-1$
-        assertTrue(config.getNavigationMethodQualifier() != null);
-        assertEquals(NavigationMethodQualifier.NavigationMethod.DPAD,
-                config.getNavigationMethodQualifier().getValue());
-        assertEquals("dpad", config.getNavigationMethodQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testTrackball() {
-        assertEquals(true, nmq.checkAndSet("trackball", config)); //$NON-NLS-1$
-        assertTrue(config.getNavigationMethodQualifier() != null);
-        assertEquals(NavigationMethodQualifier.NavigationMethod.TRACKBALL,
-                config.getNavigationMethodQualifier().getValue());
-        assertEquals("trackball", config.getNavigationMethodQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testWheel() {
-        assertEquals(true, nmq.checkAndSet("wheel", config)); //$NON-NLS-1$
-        assertTrue(config.getNavigationMethodQualifier() != null);
-        assertEquals(NavigationMethodQualifier.NavigationMethod.WHEEL,
-                config.getNavigationMethodQualifier().getValue());
-        assertEquals("wheel", config.getNavigationMethodQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, nmq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, nmq.checkAndSet("WHEEL", config));//$NON-NLS-1$
-        assertEquals(false, nmq.checkAndSet("other", config));//$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NetworkCodeQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NetworkCodeQualifierTest.java
deleted file mode 100644
index 7512305..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NetworkCodeQualifierTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier;
-
-import junit.framework.TestCase;
-
-public class NetworkCodeQualifierTest extends TestCase {
-
-    private NetworkCodeQualifier mncq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mncq = new NetworkCodeQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mncq = null;
-        config = null;
-    }
-
-    public void testCheckAndSet() {
-        assertEquals(true, mncq.checkAndSet("mnc123", config));//$NON-NLS-1$
-        assertTrue(config.getNetworkCodeQualifier() != null);
-        assertEquals(123, config.getNetworkCodeQualifier().getCode());
-        assertEquals("mnc123", config.getNetworkCodeQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, mncq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, mncq.checkAndSet("mnc", config));//$NON-NLS-1$
-        assertEquals(false, mncq.checkAndSet("MNC123", config));//$NON-NLS-1$
-        assertEquals(false, mncq.checkAndSet("123", config));//$NON-NLS-1$
-        assertEquals(false, mncq.checkAndSet("mncsdf", config));//$NON-NLS-1$
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/PixelDensityQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/PixelDensityQualifierTest.java
deleted file mode 100644
index 658d4d2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/PixelDensityQualifierTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
-
-import junit.framework.TestCase;
-
-public class PixelDensityQualifierTest extends TestCase {
-
-    private PixelDensityQualifier pdq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        pdq = new PixelDensityQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        pdq = null;
-        config = null;
-    }
-
-    public void testCheckAndSet() {
-        assertEquals(true, pdq.checkAndSet("ldpi", config));//$NON-NLS-1$
-        assertTrue(config.getPixelDensityQualifier() != null);
-        assertEquals(Density.LOW, config.getPixelDensityQualifier().getValue());
-        assertEquals("ldpi", config.getPixelDensityQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, pdq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, pdq.checkAndSet("dpi", config));//$NON-NLS-1$
-        assertEquals(false, pdq.checkAndSet("123dpi", config));//$NON-NLS-1$
-        assertEquals(false, pdq.checkAndSet("123", config));//$NON-NLS-1$
-        assertEquals(false, pdq.checkAndSet("sdfdpi", config));//$NON-NLS-1$
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/RegionQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/RegionQualifierTest.java
deleted file mode 100644
index a70a04b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/RegionQualifierTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier;
-
-import junit.framework.TestCase;
-
-public class RegionQualifierTest extends TestCase {
-
-    private RegionQualifier rq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        rq = new RegionQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        rq = null;
-        config = null;
-    }
-
-    public void testCheckAndSet() {
-        assertEquals(true, rq.checkAndSet("rUS", config));//$NON-NLS-1$
-        assertTrue(config.getRegionQualifier() != null);
-        assertEquals("US", config.getRegionQualifier().getValue()); //$NON-NLS-1$
-        assertEquals("rUS", config.getRegionQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, rq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, rq.checkAndSet("rus", config));//$NON-NLS-1$
-        assertEquals(false, rq.checkAndSet("rUSA", config));//$NON-NLS-1$
-        assertEquals(false, rq.checkAndSet("abc", config));//$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenDimensionQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenDimensionQualifierTest.java
deleted file mode 100644
index b25fb76..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenDimensionQualifierTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
-
-import junit.framework.TestCase;
-
-public class ScreenDimensionQualifierTest extends TestCase {
-
-    private ScreenDimensionQualifier sdq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        sdq = new ScreenDimensionQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        sdq = null;
-        config = null;
-    }
-    
-    public void testCheckAndSet() {
-        assertEquals(true, sdq.checkAndSet("400x200", config));//$NON-NLS-1$
-        assertTrue(config.getScreenDimensionQualifier() != null);
-        assertEquals(400, config.getScreenDimensionQualifier().getValue1());
-        assertEquals(200, config.getScreenDimensionQualifier().getValue2());
-        assertEquals("400x200", config.getScreenDimensionQualifier().toString()); //$NON-NLS-1$
-    }
-    
-    public void testFailures() {
-        assertEquals(false, sdq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, sdq.checkAndSet("400X200", config));//$NON-NLS-1$
-        assertEquals(false, sdq.checkAndSet("x200", config));//$NON-NLS-1$
-        assertEquals(false, sdq.checkAndSet("ax200", config));//$NON-NLS-1$
-        assertEquals(false, sdq.checkAndSet("400x", config));//$NON-NLS-1$
-        assertEquals(false, sdq.checkAndSet("400xa", config));//$NON-NLS-1$
-        assertEquals(false, sdq.checkAndSet("other", config));//$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenOrientationQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenOrientationQualifierTest.java
deleted file mode 100644
index 15d9686..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenOrientationQualifierTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
-
-import junit.framework.TestCase;
-
-public class ScreenOrientationQualifierTest extends TestCase {
-
-    private ScreenOrientationQualifier soq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        soq = new ScreenOrientationQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        soq = null;
-        config = null;
-    }
-
-    public void testPortrait() {
-        assertEquals(true, soq.checkAndSet("port", config)); //$NON-NLS-1$
-        assertTrue(config.getScreenOrientationQualifier() != null);
-        assertEquals(ScreenOrientationQualifier.ScreenOrientation.PORTRAIT,
-                config.getScreenOrientationQualifier().getValue());
-        assertEquals("port", config.getScreenOrientationQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testLanscape() {
-        assertEquals(true, soq.checkAndSet("land", config)); //$NON-NLS-1$
-        assertTrue(config.getScreenOrientationQualifier() != null);
-        assertEquals(ScreenOrientationQualifier.ScreenOrientation.LANDSCAPE,
-                config.getScreenOrientationQualifier().getValue());
-        assertEquals("land", config.getScreenOrientationQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testSquare() {
-        assertEquals(true, soq.checkAndSet("square", config)); //$NON-NLS-1$
-        assertTrue(config.getScreenOrientationQualifier() != null);
-        assertEquals(ScreenOrientationQualifier.ScreenOrientation.SQUARE,
-                config.getScreenOrientationQualifier().getValue());
-        assertEquals("square", config.getScreenOrientationQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, soq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, soq.checkAndSet("PORT", config));//$NON-NLS-1$
-        assertEquals(false, soq.checkAndSet("landscape", config));//$NON-NLS-1$
-        assertEquals(false, soq.checkAndSet("portrait", config));//$NON-NLS-1$
-        assertEquals(false, soq.checkAndSet("other", config));//$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TextInputMethodQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TextInputMethodQualifierTest.java
deleted file mode 100644
index c679295..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TextInputMethodQualifierTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
-
-import junit.framework.TestCase;
-
-public class TextInputMethodQualifierTest extends TestCase {
-    
-    private TextInputMethodQualifier timq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        timq = new TextInputMethodQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        timq = null;
-        config = null;
-    }
-
-    public void testQuerty() {
-        assertEquals(true, timq.checkAndSet("qwerty", config)); //$NON-NLS-1$
-        assertTrue(config.getTextInputMethodQualifier() != null);
-        assertEquals(TextInputMethodQualifier.TextInputMethod.QWERTY,
-                config.getTextInputMethodQualifier().getValue());
-        assertEquals("qwerty", config.getTextInputMethodQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void test12Key() {
-        assertEquals(true, timq.checkAndSet("12key", config)); //$NON-NLS-1$
-        assertTrue(config.getTextInputMethodQualifier() != null);
-        assertEquals(TextInputMethodQualifier.TextInputMethod.TWELVEKEYS,
-                config.getTextInputMethodQualifier().getValue());
-        assertEquals("12key", config.getTextInputMethodQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testNoKey() {
-        assertEquals(true, timq.checkAndSet("nokeys", config)); //$NON-NLS-1$
-        assertTrue(config.getTextInputMethodQualifier() != null);
-        assertEquals(TextInputMethodQualifier.TextInputMethod.NOKEY,
-                config.getTextInputMethodQualifier().getValue());
-        assertEquals("nokeys", config.getTextInputMethodQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, timq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, timq.checkAndSet("QWERTY", config));//$NON-NLS-1$
-        assertEquals(false, timq.checkAndSet("12keys", config));//$NON-NLS-1$
-        assertEquals(false, timq.checkAndSet("*12key", config));//$NON-NLS-1$
-        assertEquals(false, timq.checkAndSet("other", config));//$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TouchScreenQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TouchScreenQualifierTest.java
deleted file mode 100644
index b5d7933..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TouchScreenQualifierTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.configurations;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
-
-import junit.framework.TestCase;
-
-public class TouchScreenQualifierTest extends TestCase {
-
-    private TouchScreenQualifier tsq;
-    private FolderConfiguration config;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        tsq = new TouchScreenQualifier();
-        config = new FolderConfiguration();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        tsq = null;
-        config = null;
-    }
-
-    public void testNoTouch() {
-        assertEquals(true, tsq.checkAndSet("notouch", config)); //$NON-NLS-1$
-        assertTrue(config.getTouchTypeQualifier() != null);
-        assertEquals(TouchScreenQualifier.TouchScreenType.NOTOUCH,
-                config.getTouchTypeQualifier().getValue());
-        assertEquals("notouch", config.getTouchTypeQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFinger() {
-        assertEquals(true, tsq.checkAndSet("finger", config)); //$NON-NLS-1$
-        assertTrue(config.getTouchTypeQualifier() != null);
-        assertEquals(TouchScreenQualifier.TouchScreenType.FINGER,
-                config.getTouchTypeQualifier().getValue());
-        assertEquals("finger", config.getTouchTypeQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testStylus() {
-        assertEquals(true, tsq.checkAndSet("stylus", config)); //$NON-NLS-1$
-        assertTrue(config.getTouchTypeQualifier() != null);
-        assertEquals(TouchScreenQualifier.TouchScreenType.STYLUS,
-                config.getTouchTypeQualifier().getValue());
-        assertEquals("stylus", config.getTouchTypeQualifier().toString()); //$NON-NLS-1$
-    }
-
-    public void testFailures() {
-        assertEquals(false, tsq.checkAndSet("", config));//$NON-NLS-1$
-        assertEquals(false, tsq.checkAndSet("STYLUS", config));//$NON-NLS-1$
-        assertEquals(false, tsq.checkAndSet("other", config));//$NON-NLS-1$
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java
deleted file mode 100644
index c0533ed..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.resources.manager.SingleResourceFile;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IAbstractFolder;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IFileWrapper;
-import com.android.ide.eclipse.adt.internal.resources.manager.files.IFolderWrapper;
-import com.android.ide.eclipse.mock.FileMock;
-import com.android.ide.eclipse.mock.FolderMock;
-import com.android.sdklib.IAndroidTarget;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-public class ConfigMatchTest extends TestCase {
-    private static final String SEARCHED_FILENAME = "main.xml"; //$NON-NLS-1$
-    private static final String MISC1_FILENAME = "foo.xml"; //$NON-NLS-1$
-    private static final String MISC2_FILENAME = "bar.xml"; //$NON-NLS-1$
-
-    private ProjectResources mResources;
-    private ResourceQualifier[] mQualifierList;
-    private FolderConfiguration config4;
-    private FolderConfiguration config3;
-    private FolderConfiguration config2;
-    private FolderConfiguration config1;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        // create a Resource Manager to get a list of qualifier as instantiated by the real code.
-        // Thanks for QualifierListTest we know this contains all the qualifiers.
-        ResourceManager manager = ResourceManager.getInstance();
-        Field qualifierListField = ResourceManager.class.getDeclaredField("mQualifiers");
-        assertNotNull(qualifierListField);
-        qualifierListField.setAccessible(true);
-
-        // get the actual list.
-        mQualifierList = (ResourceQualifier[])qualifierListField.get(manager);
-
-        // create the project resources.
-        mResources = new ProjectResources(false /* isFrameworkRepository */);
-
-        // create 2 arrays of IResource. one with the filename being looked up, and one without.
-        // Since the required API uses IResource, we can use MockFolder for them.
-        FileMock[] validMemberList = new FileMock[] {
-                new FileMock(MISC1_FILENAME),
-                new FileMock(SEARCHED_FILENAME),
-                new FileMock(MISC2_FILENAME),
-        };
-        FileMock[] invalidMemberList = new FileMock[] {
-                new FileMock(MISC1_FILENAME),
-                new FileMock(MISC2_FILENAME),
-        };
-
-        // add multiple ResourceFolder to the project resource.
-        FolderConfiguration defaultConfig = getConfiguration(
-                null, // country code
-                null, // network code
-                null, // language
-                null, // region
-                null, // screen size
-                null, // screen ratio
-                null, // screen orientation
-                null, // dpi
-                null, // touch mode
-                null, // keyboard state
-                null, // text input
-                null, // navigation
-                null, // screen dimension
-                null);// version
-
-        addFolder(mResources, defaultConfig, validMemberList);
-
-        config1 = getConfiguration(
-                null, // country code
-                null, // network code
-                "en", // language
-                null, // region
-                null, // screen size
-                null, // screen ratio
-                null, // screen orientation
-                null, // dpi
-                null, // touch mode
-                KeyboardState.EXPOSED.getValue(), // keyboard state
-                null, // text input
-                null, // navigation
-                null, // screen dimension
-                null);// version
-
-        addFolder(mResources, config1, validMemberList);
-
-        config2 = getConfiguration(
-                null, // country code
-                null, // network code
-                "en", // language
-                null, // region
-                null, // screen size
-                null, // screen ratio
-                null, // screen orientation
-                null, // dpi
-                null, // touch mode
-                KeyboardState.HIDDEN.getValue(), // keyboard state
-                null, // text input
-                null, // navigation
-                null, // screen dimension
-                null);// version
-
-        addFolder(mResources, config2, validMemberList);
-
-        config3 = getConfiguration(
-                null, // country code
-                null, // network code
-                "en", // language
-                null, // region
-                null, // screen size
-                null, // screen ratio
-                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
-                null, // dpi
-                null, // touch mode
-                null, // keyboard state
-                null, // text input
-                null, // navigation
-                null, // screen dimension
-                null);// version
-
-        addFolder(mResources, config3, validMemberList);
-
-        config4 = getConfiguration(
-                "mcc310", // country code
-                "mnc435", // network code
-                "en", // language
-                "rUS", // region
-                "normal", // screen size
-                "notlong", // screen ratio
-                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
-                "mdpi", // dpi
-                TouchScreenType.FINGER.getValue(), // touch mode
-                KeyboardState.EXPOSED.getValue(), // keyboard state
-                TextInputMethod.QWERTY.getValue(), // text input
-                NavigationMethod.DPAD.getValue(), // navigation
-                "480x320", // screen dimension
-                "v3"); // version
-
-        addFolder(mResources, config4, invalidMemberList);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mResources = null;
-    }
-
-    public void test1() {
-        FolderConfiguration testConfig = getConfiguration(
-                "mcc310", // country code
-                "mnc435", // network code
-                "en", // language
-                "rUS", // region
-                "normal", // screen size
-                "notlong", // screen ratio
-                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
-                "mdpi", // dpi
-                TouchScreenType.FINGER.getValue(), // touch mode
-                KeyboardState.EXPOSED.getValue(), // keyboard state
-                TextInputMethod.QWERTY.getValue(), // text input
-                NavigationMethod.DPAD.getValue(), // navigation
-                "480x320", // screen dimension
-                "v3"); // version
-
-        ResourceFile result = mResources.getMatchingFile(SEARCHED_FILENAME,
-                ResourceFolderType.LAYOUT, testConfig);
-
-        boolean bresult = result.getFolder().getConfiguration().equals(config3);
-        assertEquals(bresult, true);
-    }
-
-    /**
-     * Creates a {@link FolderConfiguration}.
-     * @param qualifierValues The list of qualifier values. The length must equals the total number
-     * of Qualifiers. <code>null</code> is permitted and will make the FolderConfiguration not use
-     * this particular qualifier.
-     */
-    private FolderConfiguration getConfiguration(String... qualifierValues) {
-        FolderConfiguration config = new FolderConfiguration();
-
-        // those must be of the same length
-        assertEquals(qualifierValues.length, mQualifierList.length);
-
-        int index = 0;
-
-        for (ResourceQualifier qualifier : mQualifierList) {
-            String value = qualifierValues[index++];
-            if (value != null) {
-                assertTrue(qualifier.checkAndSet(value, config));
-            }
-        }
-
-        return config;
-    }
-
-    /**
-     * Adds a folder to the given {@link ProjectResources} with the given
-     * {@link FolderConfiguration}. The folder is filled with files from the provided list.
-     * @param resources the {@link ProjectResources} in which to add the folder.
-     * @param config the {@link FolderConfiguration} for the created folder.
-     * @param memberList the list of files for the folder.
-     */
-    private void addFolder(ProjectResources resources, FolderConfiguration config,
-            FileMock[] memberList) throws Exception {
-
-        // figure out the folder name based on the configuration
-        String folderName = config.getFolderName(ResourceFolderType.LAYOUT, (IAndroidTarget)null);
-
-        // create the folder mock
-        FolderMock folder = new FolderMock(folderName, memberList);
-
-        // add it to the resource, and get back a ResourceFolder object.
-        ResourceFolder resFolder = _addProjectResourceFolder(resources, config, folder);
-
-        // and fill it with files from the list.
-        for (FileMock file : memberList) {
-            resFolder.addFile(new SingleResourceFile(new IFileWrapper(file), resFolder));
-        }
-    }
-
-    /** Calls ProjectResource.add method via reflection to circumvent access
-     * restrictions that are enforced when running in the plug-in environment
-     * ie cannot access package or protected members in a different plug-in, even
-     * if they are in the same declared package as the accessor
-     */
-    private ResourceFolder _addProjectResourceFolder(ProjectResources resources,
-            FolderConfiguration config, FolderMock folder) throws Exception {
-
-        Method addMethod = ProjectResources.class.getDeclaredMethod("add",
-                ResourceFolderType.class, FolderConfiguration.class,
-                IAbstractFolder.class);
-        addMethod.setAccessible(true);
-        ResourceFolder resFolder = (ResourceFolder)addMethod.invoke(resources,
-                ResourceFolderType.LAYOUT, config, new IFolderWrapper(folder));
-        return resFolder;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/QualifierListTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/QualifierListTest.java
deleted file mode 100644
index 8932a00..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/QualifierListTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.resources.manager;
-
-import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-
-import java.lang.reflect.Field;
-
-import junit.framework.TestCase;
-
-public class QualifierListTest extends TestCase {
-    
-    private ResourceManager mManager;
-
-    @Override
-    public void setUp()  throws Exception {
-        super.setUp();
-        
-        mManager = ResourceManager.getInstance();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mManager = null;
-    }
-    
-    public void testQualifierList() {
-        try {
-            // get the list of qualifier in the resource manager
-            Field qualifierListField = ResourceManager.class.getDeclaredField("mQualifiers");
-            assertNotNull(qualifierListField);
-            qualifierListField.setAccessible(true);
-            
-            // get the actual list.
-            ResourceQualifier[] qualifierList =
-                (ResourceQualifier[])qualifierListField.get(mManager);
-            
-            // now get the number of qualifier in the FolderConfiguration
-            Field qualCountField = FolderConfiguration.class.getDeclaredField("INDEX_COUNT");
-            assertNotNull(qualCountField);
-            qualCountField.setAccessible(true);
-            
-            // get the constant value
-            Integer count = (Integer)qualCountField.get(null);
-            
-            // now compare
-            assertEquals(count.intValue(), qualifierList.length);
-        } catch (SecurityException e) {
-            assertTrue(false);
-        } catch (NoSuchFieldException e) {
-            assertTrue(false);
-        } catch (IllegalArgumentException e) {
-            assertTrue(false);
-        } catch (IllegalAccessException e) {
-            assertTrue(false);
-        }
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java
deleted file mode 100644
index b76e802..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity;
-import com.android.ide.eclipse.tests.AdtTestData;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link AndroidManifestParser}
- */
-public class AndroidManifestParserTest extends TestCase {
-    private AndroidManifestParser mManifestTestApp;
-    private AndroidManifestParser mManifestInstrumentation;
-    
-    private static final String INSTRUMENTATION_XML = "AndroidManifest-instrumentation.xml";  //$NON-NLS-1$
-    private static final String TESTAPP_XML = "AndroidManifest-testapp.xml";  //$NON-NLS-1$
-    private static final String PACKAGE_NAME =  "com.android.testapp"; //$NON-NLS-1$
-    private static final String ACTIVITY_NAME = "com.android.testapp.MainActivity"; //$NON-NLS-1$
-    private static final String LIBRARY_NAME = "android.test.runner"; //$NON-NLS-1$
-    private static final String INSTRUMENTATION_NAME = "android.test.InstrumentationTestRunner"; //$NON-NLS-1$
-    private static final String INSTRUMENTATION_TARGET = "com.android.AndroidProject"; //$NON-NLS-1$
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        
-        String testFilePath = AdtTestData.getInstance().getTestFilePath(
-                TESTAPP_XML);
-        mManifestTestApp = AndroidManifestParser.parseForData(testFilePath);
-        assertNotNull(mManifestTestApp);
-        
-        testFilePath = AdtTestData.getInstance().getTestFilePath(
-                INSTRUMENTATION_XML);
-        mManifestInstrumentation = AndroidManifestParser.parseForData(testFilePath);
-        assertNotNull(mManifestInstrumentation);
-    }
-
-    public void testGetInstrumentationInformation() {
-        assertEquals(1, mManifestInstrumentation.getInstrumentations().length);
-        assertEquals(INSTRUMENTATION_NAME, 
-                mManifestInstrumentation.getInstrumentations()[0].getName());
-        assertEquals(INSTRUMENTATION_TARGET, 
-                mManifestInstrumentation.getInstrumentations()[0].getTargetPackage());
-    }
-    
-    public void testGetPackage() {
-        assertEquals(PACKAGE_NAME, mManifestTestApp.getPackage());
-    }
-
-    public void testGetActivities() {
-        assertEquals(1, mManifestTestApp.getActivities().length);
-        AndroidManifestParser.Activity activity = mManifestTestApp.getActivities()[0];
-        assertEquals(ACTIVITY_NAME, activity.getName());
-        assertTrue(activity.hasAction());
-        assertTrue(activity.isHomeActivity());
-        assertTrue(activity.hasAction());
-        assertEquals(activity, mManifestTestApp.getActivities()[0]);
-    }
-
-    public void testGetLauncherActivity() {
-        Activity activity = mManifestTestApp.getLauncherActivity();
-        assertEquals(ACTIVITY_NAME, activity.getName());
-        assertTrue(activity.hasAction());
-        assertTrue(activity.isHomeActivity());
-    }
-    
-    private void assertEquals(Activity lhs, Activity rhs) {
-        assertTrue(lhs == rhs || (lhs != null && rhs != null));
-        if (lhs != null && rhs != null) {
-            assertEquals(lhs.getName(),        rhs.getName());
-            assertEquals(lhs.isExported(),     rhs.isExported());
-            assertEquals(lhs.hasAction(),      rhs.hasAction());
-            assertEquals(lhs.isHomeActivity(), rhs.isHomeActivity());
-        }
-    }
-
-    public void testGetUsesLibraries() {
-        assertEquals(1, mManifestTestApp.getUsesLibraries().length);
-        assertEquals(LIBRARY_NAME, mManifestTestApp.getUsesLibraries()[0]); 
-    }
-
-    public void testGetPackageName() {
-        assertEquals(PACKAGE_NAME, mManifestTestApp.getPackage());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/ProjectHelperTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/ProjectHelperTest.java
deleted file mode 100644
index 6080102..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/ProjectHelperTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.project;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.mock.ClasspathEntryMock;
-import com.android.ide.eclipse.mock.JavaProjectMock;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.JavaModelException;
-
-import junit.framework.TestCase;
-
-public class ProjectHelperTest extends TestCase {
-
-    /** The old container id */
-    private final static String OLD_CONTAINER_ID =
-        "com.android.ide.eclipse.adt.project.AndroidClasspathContainerInitializer"; //$NON-NLS-1$
-
-    /** The container id for the android framework jar file */
-    private final static String CONTAINER_ID =
-        "com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"; //$NON-NLS-1$
-    
-    @Override
-    public void setUp() throws Exception {
-        // pass for now
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        // pass for now
-    }
-    
-    public final void testFixProjectClasspathEntriesFromOldContainer() throws JavaModelException {
-        // create a project with a path to an android .zip
-        JavaProjectMock javaProject = new JavaProjectMock(
-                new IClasspathEntry[] {
-                        new ClasspathEntryMock(new Path("Project/src"), //$NON-NLS-1$
-                                IClasspathEntry.CPE_SOURCE),
-                        new ClasspathEntryMock(new Path(OLD_CONTAINER_ID),
-                                IClasspathEntry.CPE_CONTAINER),
-                },
-                new Path("Project/bin"));
-        
-        ProjectHelper.fixProjectClasspathEntries(javaProject);
-        
-        IClasspathEntry[] fixedEntries = javaProject.getRawClasspath();
-        assertEquals(3, fixedEntries.length);
-        assertEquals("Project/src", fixedEntries[0].getPath().toString());
-        assertEquals(OLD_CONTAINER_ID, fixedEntries[1].getPath().toString());
-        assertEquals(CONTAINER_ID, fixedEntries[2].getPath().toString());
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParserTest.java
deleted file mode 100644
index ac6ebf5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParserTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources;
-
-
-import com.android.ide.eclipse.adt.internal.resources.AttrsXmlParser;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo.Format;
-import com.android.ide.eclipse.tests.AdtTestData;
-
-import org.w3c.dom.Document;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-public class AttrsXmlParserTest extends TestCase {
-    
-    private AttrsXmlParser mParser;
-    private String mFilePath;
-
-    @Override
-    public void setUp() throws Exception {
-        mFilePath = AdtTestData.getInstance().getTestFilePath("mock_attrs.xml"); //$NON-NLS-1$
-        mParser = new AttrsXmlParser(mFilePath);
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-    }
-    
-    public final void testGetDocument() throws Exception {
-        assertNotNull(_getDocument());
-    }
-
-    public void testGetOsAttrsXmlPath() throws Exception {
-        assertEquals(mFilePath, mParser.getOsAttrsXmlPath());
-    }
-    
-    public final void testPreload() throws Exception {
-        assertSame(mParser, mParser.preload());
-    }
-    
-    
-    public final void testLoadViewAttributes() throws Exception {
-        mParser.preload();
-        ViewClassInfo info = new ViewClassInfo(
-                false /* isLayout */,
-                "mock_android.something.Theme",      //$NON-NLS-1$
-                "Theme");                            //$NON-NLS-1$
-        mParser.loadViewAttributes(info);
-        
-        assertEquals("These are the standard attributes that make up a complete theme.", //$NON-NLS-1$
-                info.getJavaDoc());
-        AttributeInfo[] attrs = info.getAttributes();
-        assertEquals(1, attrs.length);
-        assertEquals("scrollbarSize", info.getAttributes()[0].getName());
-        assertEquals(1, info.getAttributes()[0].getFormats().length);
-        assertEquals(Format.DIMENSION, info.getAttributes()[0].getFormats()[0]);
-    }
-    
-    public final void testEnumFlagValues() throws Exception {
-        /* The XML being read contains:
-            <!-- Standard orientation constant. -->
-            <attr name="orientation">
-                <!-- Defines an horizontal widget. -->
-                <enum name="horizontal" value="0" />
-                <!-- Defines a vertical widget. -->
-                <enum name="vertical" value="1" />
-            </attr>
-         */
-
-        mParser.preload();
-        Map<String, Map<String, Integer>> attrMap = mParser.getEnumFlagValues();
-        assertTrue(attrMap.containsKey("orientation"));
-        
-        Map<String, Integer> valueMap = attrMap.get("orientation");
-        assertTrue(valueMap.containsKey("horizontal"));
-        assertTrue(valueMap.containsKey("vertical"));
-        assertEquals(Integer.valueOf(0), valueMap.get("horizontal"));
-        assertEquals(Integer.valueOf(1), valueMap.get("vertical"));
-    }
-    
-    public final void testDeprecated() throws Exception {
-        mParser.preload();
-        
-        DeclareStyleableInfo dep = mParser.getDeclareStyleableList().get("DeprecatedTest");
-        assertNotNull(dep);
-        
-        AttributeInfo[] attrs = dep.getAttributes();
-        assertEquals(4, attrs.length);
-
-        assertEquals("deprecated-inline", attrs[0].getName());
-        assertEquals("In-line deprecated.", attrs[0].getDeprecatedDoc());
-        assertEquals("Deprecated comments using delimiters.", attrs[0].getJavaDoc());
-        
-        assertEquals("deprecated-multiline", attrs[1].getName());
-        assertEquals("Multi-line version of deprecated that works till the next tag.",
-                attrs[1].getDeprecatedDoc());
-        assertEquals("Deprecated comments on their own line.", attrs[1].getJavaDoc());
-        
-        assertEquals("deprecated-not", attrs[2].getName());
-        assertEquals(null, attrs[2].getDeprecatedDoc());
-        assertEquals("This attribute is not deprecated.", attrs[2].getJavaDoc());
-
-        assertEquals("deprecated-no-javadoc", attrs[3].getName());
-        assertEquals("There is no other javadoc here.", attrs[3].getDeprecatedDoc());
-        assertEquals("", attrs[3].getJavaDoc());
-    }
-
-    //---- access to private methods
-    
-    private Document _getDocument() throws Exception {
-        Method method = AttrsXmlParser.class.getDeclaredMethod("getDocument"); //$NON-NLS-1$
-        method.setAccessible(true);
-        return (Document) method.invoke(mParser);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoaderTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoaderTest.java
deleted file mode 100644
index 71c79be..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoaderTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.internal.sdk.AndroidJarLoader;
-import com.android.ide.eclipse.adt.internal.sdk.IAndroidClassLoader.IClassDescriptor;
-import com.android.ide.eclipse.tests.AdtTestData;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import junit.framework.TestCase;
-
-/**
- * Unit Test for {@link AndroidJarLoader}.
- * 
- * Uses the classes jar.example.Class1/Class2 stored in tests/data/jar_example.jar.
- */
-public class AndroidJarLoaderTest extends TestCase {
-
-    private AndroidJarLoader mFrameworkClassLoader;
-
-    /** Creates an instance of {@link AndroidJarLoader} on our test data JAR */ 
-    @Override
-    public void setUp() throws Exception {
-        String jarfilePath = AdtTestData.getInstance().getTestFilePath("jar_example.jar");  //$NON-NLS-1$
-        mFrameworkClassLoader = new AndroidJarLoader(jarfilePath);
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        mFrameworkClassLoader = null;
-        System.gc();
-    }
-
-    /** Preloads classes. They should load just fine. */
-    public final void testPreLoadClasses() throws Exception {
-        mFrameworkClassLoader.preLoadClasses("jar.example.", null, null); //$NON-NLS-1$
-        HashMap<String, Class<?>> map = getPrivateClassCache();
-        assertEquals(0, map.size());
-        HashMap<String,byte[]> data = getPrivateEntryCache();
-        assertTrue(data.containsKey("jar.example.Class1"));                    //$NON-NLS-1$
-        assertTrue(data.containsKey("jar.example.Class2"));                    //$NON-NLS-1$
-        assertTrue(data.containsKey("jar.example.Class1$InnerStaticClass1"));  //$NON-NLS-1$
-        assertTrue(data.containsKey("jar.example.Class1$InnerClass2"));  //$NON-NLS-1$
-        assertEquals(4, data.size());
-    }
-
-    /** Preloads a class not in the JAR. Preloading does nothing in this case. */
-    public final void testPreLoadClasses_classNotFound() throws Exception {
-        mFrameworkClassLoader.preLoadClasses("not.a.package.", null, null);  //$NON-NLS-1$
-        HashMap<String, Class<?>> map = getPrivateClassCache();
-        assertEquals(0, map.size());
-        HashMap<String,byte[]> data = getPrivateEntryCache();
-        assertEquals(0, data.size());
-    }
-
-    /** Finds a class we just preloaded. It should work. */
-    public final void testFindClass_classFound() throws Exception {
-        Class<?> c = _findClass(mFrameworkClassLoader, "jar.example.Class2");  //$NON-NLS-1$
-        assertEquals("jar.example.Class2", c.getName());              //$NON-NLS-1$
-        HashMap<String, Class<?>> map = getPrivateClassCache();
-        assertTrue(map.containsKey("jar.example.Class1"));            //$NON-NLS-1$
-        assertTrue(map.containsKey("jar.example.Class2"));            //$NON-NLS-1$
-        assertEquals(2, map.size());
-    }
-    
-    /** call the protected method findClass */
-    private Class<?> _findClass(AndroidJarLoader jarLoader, String name) throws Exception {
-        Method findClassMethod = AndroidJarLoader.class.getDeclaredMethod(
-                "findClass", String.class);  //$NON-NLS-1$
-        findClassMethod.setAccessible(true);
-        try {
-            return (Class<?>)findClassMethod.invoke(jarLoader, name);
-        }
-        catch (InvocationTargetException e) {
-           throw (Exception)e.getCause();
-        }
-    }
-
-    /** Trying to find a class that we fail to preload should throw a CNFE. */
-    public final void testFindClass_classNotFound() throws Exception {
-        try {
-            // Will throw ClassNotFoundException
-            _findClass(mFrameworkClassLoader, "not.a.valid.ClassName");  //$NON-NLS-1$
-        } catch (ClassNotFoundException e) {
-            // check the message in the CNFE
-            assertEquals("not.a.valid.ClassName", e.getMessage());  //$NON-NLS-1$
-            return;
-        }
-        // Exception not thrown - this is a failure
-        fail("Expected ClassNotFoundException not thrown");
-    }
-    
-    public final void testFindClassesDerivingFrom() throws Exception {
-        HashMap<String, ArrayList<IClassDescriptor>> found =
-            mFrameworkClassLoader.findClassesDerivingFrom("jar.example.", new String[] {  //$NON-NLS-1$
-                "jar.example.Class1",       //$NON-NLS-1$
-                "jar.example.Class2" });    //$NON-NLS-1$
-
-        assertTrue(found.containsKey("jar.example.Class1"));  //$NON-NLS-1$
-        assertTrue(found.containsKey("jar.example.Class2"));  //$NON-NLS-1$
-        assertEquals(2, found.size());  
-        // Only Class2 derives from Class1..
-        // Class1 and Class1$InnerStaticClass1 derive from Object and are thus ignored.
-        // Class1$InnerClass2 should never be seen either.
-        assertEquals("jar.example.Class2",  //$NON-NLS-1$
-                found.get("jar.example.Class1").get(0).getCanonicalName());  //$NON-NLS-1$
-        assertEquals(1, found.get("jar.example.Class1").size());      //$NON-NLS-1$
-        assertEquals(0, found.get("jar.example.Class2").size());      //$NON-NLS-1$
-    }
-
-    // --- Utilities ---
-    
-    /**
-     * Retrieves the private mFrameworkClassLoader.mClassCache field using reflection.
-     * 
-     * @throws NoSuchFieldException 
-     * @throws SecurityException 
-     * @throws IllegalAccessException 
-     * @throws IllegalArgumentException 
-     */
-    @SuppressWarnings("unchecked")
-    private HashMap<String, Class<?> > getPrivateClassCache()
-            throws SecurityException, NoSuchFieldException,
-                IllegalArgumentException, IllegalAccessException {
-        Field field = AndroidJarLoader.class.getDeclaredField("mClassCache");  //$NON-NLS-1$
-        field.setAccessible(true);
-        return (HashMap<String, Class<?>>) field.get(mFrameworkClassLoader);
-    }
-
-    /**
-     * Retrieves the private mFrameworkClassLoader.mEntryCache field using reflection.
-     * 
-     * @throws NoSuchFieldException 
-     * @throws SecurityException 
-     * @throws IllegalAccessException 
-     * @throws IllegalArgumentException 
-     */
-    @SuppressWarnings("unchecked")
-    private HashMap<String,byte[]> getPrivateEntryCache()
-            throws SecurityException, NoSuchFieldException,
-                IllegalArgumentException, IllegalAccessException {
-        Field field = AndroidJarLoader.class.getDeclaredField("mEntryCache");  //$NON-NLS-1$
-        field.setAccessible(true);
-        return (HashMap<String, byte[]>) field.get(mFrameworkClassLoader);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParserTest.java
deleted file mode 100644
index cf5f194..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParserTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.sdk;
-
-import com.android.ide.eclipse.adt.internal.resources.AttrsXmlParser;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
-import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo.LayoutParamsInfo;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidJarLoader;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
-import com.android.ide.eclipse.adt.internal.sdk.LayoutParamsParser;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidJarLoader.ClassWrapper;
-import com.android.ide.eclipse.adt.internal.sdk.IAndroidClassLoader.IClassDescriptor;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.TreeMap;
-
-import junit.framework.TestCase;
-
-/**
- * Test the inner private methods of PlatformDataParser.
- * 
- * Convention: method names that start with an underscore are actually local wrappers
- * that call private methods from {@link AndroidTargetParser} using reflection.
- * This is inspired by the Python coding rule which mandates underscores prefixes for
- * "private" methods.
- */
-public class LayoutParamsParserTest extends TestCase {
-
-    private static class MockFrameworkClassLoader extends AndroidJarLoader {
-        MockFrameworkClassLoader() {
-            super(null /* osFrameworkLocation */);
-        }
-        
-        @Override
-        public HashMap<String, ArrayList<IClassDescriptor>> findClassesDerivingFrom(
-                String rootPackage, String[] superClasses) throws ClassFormatError {
-            return new HashMap<String, ArrayList<IClassDescriptor>>();
-        }
-    }
-    
-    private static class MockAttrsXmlPath {
-        public String getPath() {
-            ClassLoader cl = this.getClass().getClassLoader();
-            URL res = cl.getResource("data/mock_attrs.xml");  //$NON-NLS-1$
-            return res.getFile();
-        }
-    }
-    
-    private static class MockLayoutParamsParser extends LayoutParamsParser {
-        public MockLayoutParamsParser() {
-            super(new MockFrameworkClassLoader(),
-                  new AttrsXmlParser(new MockAttrsXmlPath().getPath()).preload());
-
-            mTopViewClass = new ClassWrapper(mock_android.view.View.class);
-            mTopGroupClass = new ClassWrapper(mock_android.view.ViewGroup.class);
-            mTopLayoutParamsClass = new ClassWrapper(mock_android.view.ViewGroup.LayoutParams.class);
-
-            mViewList = new ArrayList<IClassDescriptor>();
-            mGroupList = new ArrayList<IClassDescriptor>();
-            mViewMap = new TreeMap<String, ExtViewClassInfo>();
-            mGroupMap = new TreeMap<String, ExtViewClassInfo>();
-            mLayoutParamsMap = new HashMap<String, LayoutParamsInfo>();
-        }
-    }
-
-    private MockLayoutParamsParser mParser;
-    
-    @Override
-    public void setUp() throws Exception {
-        mParser = new MockLayoutParamsParser();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-    }
-    
-    public final void testFindLayoutParams() throws Exception {
-        assertEquals(mock_android.view.ViewGroup.LayoutParams.class,
-            ((ClassWrapper)_findLayoutParams(mock_android.view.ViewGroup.class)).wrappedClass());
-
-        assertEquals(mock_android.widget.LinearLayout.LayoutParams.class,
-            ((ClassWrapper)_findLayoutParams(mock_android.widget.LinearLayout.class)).wrappedClass());
-
-        assertEquals(mock_android.widget.TableLayout.LayoutParams.class,
-            ((ClassWrapper)_findLayoutParams(mock_android.widget.TableLayout.class)).wrappedClass());
-    }
-    
-    public final void testGetLayoutParamsInfo() throws Exception {
-        LayoutParamsInfo info1 = _getLayoutParamsInfo(
-                mock_android.view.ViewGroup.LayoutParams.class);
-        assertNotNull(info1);
-        // ViewGroup.LayoutData has Object for superClass, which we don't map
-        assertNull(info1.getSuperClass());
-
-        LayoutParamsInfo info2 = _getLayoutParamsInfo(
-                mock_android.widget.LinearLayout.LayoutParams.class);
-        assertNotNull(info2);
-        // LinearLayout.LayoutData links to ViewGroup.LayoutParams
-        assertSame(info1, info2.getSuperClass());
-        
-        LayoutParamsInfo info3 = _getLayoutParamsInfo(
-                mock_android.widget.TableLayout.LayoutParams.class);
-        assertNotNull(info3);
-        // TableLayout.LayoutData does not link to ViewGroup.LayoutParams nor
-        // LinearLayout.LayoutParams
-        assertNotSame(info1, info3.getSuperClass());
-        assertNotSame(info2, info3.getSuperClass());
-        // TableLayout.LayoutParams => ViewGroup.MarginLayoutParams => ViewGroup.LayoutParams
-        assertSame(info1, info3.getSuperClass().getSuperClass());        
-    }
-
-    public final void testGetLayoutClasses() throws Exception {
-        // _getLayoutClasses();
-    }
-
-    //---- access to private methods
-    
-    /** Calls the private constructor of the parser */
-    @SuppressWarnings("unused")
-    private AndroidTargetParser _Constructor(String osJarPath) throws Exception {
-        Constructor<AndroidTargetParser> constructor =
-            AndroidTargetParser.class.getDeclaredConstructor(String.class);
-        constructor.setAccessible(true);
-        return constructor.newInstance(osJarPath);
-    }
-    
-    /** calls the private getLayoutClasses() of the parser */
-    @SuppressWarnings("unused")
-    private void _getLayoutClasses() throws Exception {
-        Method method = AndroidTargetParser.class.getDeclaredMethod("getLayoutClasses");  //$NON-NLS-1$
-        method.setAccessible(true);
-        method.invoke(mParser);
-    }
-    
-    /** calls the private addGroup() of the parser */
-    @SuppressWarnings("unused")
-    private ViewClassInfo _addGroup(Class<?> groupClass) throws Exception {
-        Method method = LayoutParamsParser.class.getDeclaredMethod("addGroup",  //$NON-NLS-1$
-                IClassDescriptor.class);
-        method.setAccessible(true);
-        return (ViewClassInfo) method.invoke(mParser, new ClassWrapper(groupClass));
-    }
-
-    /** calls the private addLayoutParams() of the parser */
-    @SuppressWarnings("unused")
-    private LayoutParamsInfo _addLayoutParams(Class<?> groupClass) throws Exception {
-        Method method = LayoutParamsParser.class.getDeclaredMethod("addLayoutParams",   //$NON-NLS-1$
-                IClassDescriptor.class);
-        method.setAccessible(true);
-        return (LayoutParamsInfo) method.invoke(mParser, new ClassWrapper(groupClass));
-    }
-
-    /** calls the private getLayoutParamsInfo() of the parser */
-    private LayoutParamsInfo _getLayoutParamsInfo(Class<?> layoutParamsClass) throws Exception {
-        Method method = LayoutParamsParser.class.getDeclaredMethod("getLayoutParamsInfo",   //$NON-NLS-1$
-                IClassDescriptor.class);
-        method.setAccessible(true);
-        return (LayoutParamsInfo) method.invoke(mParser, new ClassWrapper(layoutParamsClass));
-    }
-    
-    /** calls the private findLayoutParams() of the parser */
-    private IClassDescriptor _findLayoutParams(Class<?> groupClass) throws Exception {
-        Method method = LayoutParamsParser.class.getDeclaredMethod("findLayoutParams",  //$NON-NLS-1$
-                IClassDescriptor.class);
-        method.setAccessible(true);
-        return (IClassDescriptor) method.invoke(mParser, new ClassWrapper(groupClass));
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ClasspathEntryMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ClasspathEntryMock.java
deleted file mode 100644
index 010aadf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ClasspathEntryMock.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.mock;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.jdt.core.IAccessRule;
-import org.eclipse.jdt.core.IClasspathAttribute;
-import org.eclipse.jdt.core.IClasspathEntry;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-public class ClasspathEntryMock implements IClasspathEntry {
-
-    private int mKind;
-    private IPath mPath;
-
-    public ClasspathEntryMock(IPath path, int kind) {
-        mPath = path;
-        mKind = kind;
-    }
-    
-    public int getEntryKind() {
-        return mKind;
-    }
-    
-    public IPath getPath() {
-        return mPath;
-    }
-    
-    // -------- UNIMPLEMENTED METHODS ----------------
-
-    public boolean combineAccessRules() {
-        throw new NotImplementedException();
-    }
-
-    public IAccessRule[] getAccessRules() {
-        throw new NotImplementedException();
-    }
-
-    public int getContentKind() {
-        throw new NotImplementedException();
-    }
-
-    public IPath[] getExclusionPatterns() {
-        throw new NotImplementedException();
-    }
-
-    public IClasspathAttribute[] getExtraAttributes() {
-        throw new NotImplementedException();
-    }
-
-    public IPath[] getInclusionPatterns() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getOutputLocation() {
-        throw new NotImplementedException();
-    }
-
-    public IClasspathEntry getResolvedEntry() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getSourceAttachmentPath() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getSourceAttachmentRootPath() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isExported() {
-        throw new NotImplementedException();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FileMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FileMock.java
deleted file mode 100644
index 5739153..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FileMock.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.mock;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFileState;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
-import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourceAttributes;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.content.IContentDescription;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.Reader;
-import java.net.URI;
-import java.util.Map;
-
-/**
- * Mock implementation of {@link IFile}.
- * 
- * Optionally backed by an in-memory byte array
- * 
- * <p/>Supported methods:
- * <ul>
- *     <li>getName()</li>
- *     <li>getContents()</li>
- *     <li>getContents(boolean force)</li>
- * </ul>
- */
-public class FileMock implements IFile {
-
-    private String mName;
-    private byte[] mContentData; 
-
-    public FileMock(String name) {
-        this(name, new byte[0]);
-    }
-    
-    public FileMock(String name, byte[] fileData) {
-        mName = name;
-        mContentData = fileData;
-    }
-
-    // -------- MOCKED METHODS ----------------
-
-    public String getName() {
-        return mName;
-    }
-    
-    public InputStream getContents() throws CoreException {
-        return new ByteArrayInputStream(mContentData);
-    }
-
-    public InputStream getContents(boolean force) throws CoreException {
-        // ignore force
-        return getContents();
-    }
-    
-    // -------- UNIMPLEMENTED METHODS ----------------
-
-    public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void appendContents(InputStream source, boolean force, boolean keepHistory,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void create(InputStream source, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void create(InputStream source, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void createLink(URI location, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getCharset() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getCharset(boolean checkImplicit) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getCharsetFor(Reader reader) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IContentDescription getContentDescription() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public int getEncoding() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IPath getFullPath() {
-        throw new NotImplementedException();
-    }
-
-    public IFileState[] getHistory(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isReadOnly() {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, boolean force, boolean keepHistory, 
-            IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setCharset(String newCharset) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setContents(InputStream source, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setContents(IFileState source, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setContents(InputStream source, boolean force, boolean keepHistory,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setContents(IFileState source, boolean force, boolean keepHistory,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void clearHistory(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IPath destination, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IPath destination, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IMarker createMarker(String type) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResourceProxy createProxy() {
-        throw new NotImplementedException();
-    }
-
-    public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void deleteMarkers(String type, boolean includeSubtypes, int depth) 
-    throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean exists() {
-        throw new NotImplementedException();
-    }
-
-    public IMarker findMarker(long id) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getFileExtension() {
-        throw new NotImplementedException();
-    }
-
-    public long getLocalTimeStamp() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getLocation() {
-        return new Path(mName);
-    }
-
-    public URI getLocationURI() {
-        throw new NotImplementedException();
-    }
-
-    public IMarker getMarker(long id) {
-        throw new NotImplementedException();
-    }
-
-    public long getModificationStamp() {
-        throw new NotImplementedException();
-    }
-
-    public IContainer getParent() {
-        throw new NotImplementedException();
-    }
-
-    public String getPersistentProperty(QualifiedName key) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IProject getProject() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getProjectRelativePath() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getRawLocation() {
-        throw new NotImplementedException();
-    }
-
-    public URI getRawLocationURI() {
-        throw new NotImplementedException();
-    }
-
-    public ResourceAttributes getResourceAttributes() {
-        throw new NotImplementedException();
-    }
-
-    public Object getSessionProperty(QualifiedName key) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public int getType() {
-        throw new NotImplementedException();
-    }
-
-    public IWorkspace getWorkspace() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isAccessible() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isDerived() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLinked() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLinked(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLocal(int depth) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isPhantom() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isSynchronized(int depth) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isTeamPrivateMember() {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IProjectDescription description, boolean force, boolean keepHistory,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void revertModificationStamp(long value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDerived(boolean isDerived) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public long setLocalTimeStamp(long value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setPersistentProperty(QualifiedName key, String value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setReadOnly(boolean readOnly) {
-        throw new NotImplementedException();
-    }
-
-    public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void touch(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Object getAdapter(Class adapter) {
-        throw new NotImplementedException();
-    }
-
-    public boolean contains(ISchedulingRule rule) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isConflicting(ISchedulingRule rule) {
-        throw new NotImplementedException();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Map getPersistentProperties() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Map getSessionProperties() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isDerived(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isHidden() {
-        throw new NotImplementedException();
-    }
-
-    public void setHidden(boolean isHidden) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isHidden(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isTeamPrivateMember(int options) {
-        throw new NotImplementedException();
-    }
-}
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FolderMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FolderMock.java
deleted file mode 100644
index 26bf53e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FolderMock.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.mock;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
-import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourceAttributes;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-import java.net.URI;
-import java.util.Map;
-
-/**
- * Mock implementation of {@link IFolder}.
- * <p/>Supported methods:
- * <ul>
- * <li>{@link #getName()}</li>
- * <li>{@link #members()}</li>
- * </ul>
- */
-public final class FolderMock implements IFolder {
-    
-    private String mName;
-    private IResource[] mMembers;
-    
-    public FolderMock(String name) {
-        mName = name;
-        mMembers = new IResource[0];
-    }
-    
-    public FolderMock(String name, IResource[] members) {
-        mName = name;
-        mMembers = members;
-    }
-    
-    // -------- MOCKED METHODS ----------------
-    
-    public String getName() {
-        return mName;
-    }
-    
-    public IResource[] members() throws CoreException {
-        return mMembers;
-    }
-
-    // -------- UNIMPLEMENTED METHODS ----------------
-
-    public void create(boolean force, boolean local, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void create(int updateFlags, boolean local, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void createLink(URI location, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IFile getFile(String name) {
-        throw new NotImplementedException();
-    }
-
-    public IFolder getFolder(String name) {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, boolean force, boolean keepHistory,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean exists(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IFile[] findDeletedMembersWithHistory(int depth, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(String name) {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(String name, boolean includePhantoms) {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(IPath path, boolean includePhantoms) {
-        throw new NotImplementedException();
-    }
-
-    public String getDefaultCharset() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getDefaultCharset(boolean checkImplicit) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IFile getFile(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IFolder getFolder(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IResource[] members(boolean includePhantoms) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResource[] members(int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDefaultCharset(String charset) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDefaultCharset(String charset, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void clearHistory(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IPath destination, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IPath destination, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IMarker createMarker(String type) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResourceProxy createProxy() {
-        throw new NotImplementedException();
-    }
-
-    public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void deleteMarkers(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean exists() {
-        throw new NotImplementedException();
-    }
-
-    public IMarker findMarker(long id) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getFileExtension() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getFullPath() {
-        throw new NotImplementedException();
-    }
-
-    public long getLocalTimeStamp() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getLocation() {
-        throw new NotImplementedException();
-    }
-
-    public URI getLocationURI() {
-        throw new NotImplementedException();
-    }
-
-    public IMarker getMarker(long id) {
-        throw new NotImplementedException();
-    }
-
-    public long getModificationStamp() {
-        throw new NotImplementedException();
-    }
-
-    public IContainer getParent() {
-        throw new NotImplementedException();
-    }
-
-    public String getPersistentProperty(QualifiedName key) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IProject getProject() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getProjectRelativePath() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getRawLocation() {
-        throw new NotImplementedException();
-    }
-
-    public URI getRawLocationURI() {
-        throw new NotImplementedException();
-    }
-
-    public ResourceAttributes getResourceAttributes() {
-        throw new NotImplementedException();
-    }
-
-    public Object getSessionProperty(QualifiedName key) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public int getType() {
-        throw new NotImplementedException();
-    }
-
-    public IWorkspace getWorkspace() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isAccessible() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isDerived() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLinked() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLinked(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLocal(int depth) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isPhantom() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isReadOnly() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isSynchronized(int depth) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isTeamPrivateMember() {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IProjectDescription description, boolean force, boolean keepHistory,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void revertModificationStamp(long value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDerived(boolean isDerived) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public long setLocalTimeStamp(long value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setPersistentProperty(QualifiedName key, String value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setReadOnly(boolean readOnly) {
-        throw new NotImplementedException();
-    }
-
-    public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void touch(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Object getAdapter(Class adapter) {
-        throw new NotImplementedException();
-    }
-
-    public boolean contains(ISchedulingRule rule) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isConflicting(ISchedulingRule rule) {
-        throw new NotImplementedException();
-    }
-
-    public Map<?,?> getPersistentProperties() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public Map<?,?> getSessionProperties() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isDerived(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isHidden() {
-        throw new NotImplementedException();
-    }
-
-    public void setHidden(boolean isHidden) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isHidden(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isTeamPrivateMember(int options) {
-        throw new NotImplementedException();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/JavaProjectMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/JavaProjectMock.java
deleted file mode 100644
index f23d2c1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/JavaProjectMock.java
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.mock;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jdt.core.IBuffer;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IOpenable;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.IRegion;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.WorkingCopyOwner;
-import org.eclipse.jdt.core.eval.IEvaluationContext;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-import java.util.Map;
-
-public class JavaProjectMock implements IJavaProject {
-    
-    private IProject mProject;
-
-    private IClasspathEntry[] mEntries;
-    private IPath mOutputLocation;
-    private String mCompilerCompliance = "1.4"; //$NON-NLS-1
-    private String mCompilerSource = "1.4"; //$NON-NLS-1
-    private String mCompilerTarget = "1.4"; //$NON-NLS-1
-
-    public JavaProjectMock(IClasspathEntry[] entries, IPath outputLocation) {
-        mEntries = entries;
-        mOutputLocation = outputLocation;
-    }
-    
-    public IProject getProject() {
-        if (mProject == null) {
-            mProject = new ProjectMock();
-        }
-
-        return mProject;
-    }
-
-    
-    public void setRawClasspath(IClasspathEntry[] entries, IProgressMonitor monitor)
-            throws JavaModelException {
-        mEntries = entries;
-    }
-
-    public void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation,
-            IProgressMonitor monitor) throws JavaModelException {
-        mEntries = entries;
-        mOutputLocation = outputLocation;
-    }
-    
-    public IClasspathEntry[] getRawClasspath() throws JavaModelException {
-        return mEntries;
-    }
-    
-    public IPath getOutputLocation() throws JavaModelException {
-        return mOutputLocation;
-    }
-    
-    public String getOption(String optionName, boolean inheritJavaCoreOptions) {
-        if (optionName.equals(JavaCore.COMPILER_COMPLIANCE)) {
-            return mCompilerCompliance;
-        } else if (optionName.equals(JavaCore.COMPILER_SOURCE)) {
-            return mCompilerSource;
-        } else if (optionName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM)) {
-            return mCompilerTarget;
-        }
-        
-        return null;
-    }
-        
-    public void setOption(String optionName, String optionValue) {
-        if (optionName.equals(JavaCore.COMPILER_COMPLIANCE)) {
-            mCompilerCompliance = optionValue;
-        } else if (optionName.equals(JavaCore.COMPILER_SOURCE)) {
-            mCompilerSource = optionValue;
-        } else if (optionName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM)) {
-            mCompilerTarget = optionValue;
-        } else {
-            throw new NotImplementedException();
-        }
-    }
-
-
-    // -------- UNIMPLEMENTED METHODS ----------------
-    
-    public IClasspathEntry decodeClasspathEntry(String encodedEntry) {
-        throw new NotImplementedException();
-    }
-
-    public String encodeClasspathEntry(IClasspathEntry classpathEntry) {
-        throw new NotImplementedException();
-    }
-
-    public IJavaElement findElement(IPath path) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IJavaElement findElement(IPath path, WorkingCopyOwner owner) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragment findPackageFragment(IPath path) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragmentRoot findPackageFragmentRoot(IPath path) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String fullyQualifiedName) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String fullyQualifiedName, IProgressMonitor progressMonitor)
-            throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String fullyQualifiedName, WorkingCopyOwner owner)
-            throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String packageName, String typeQualifiedName) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String fullyQualifiedName, WorkingCopyOwner owner,
-            IProgressMonitor progressMonitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String packageName, String typeQualifiedName,
-            IProgressMonitor progressMonitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner)
-            throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner,
-            IProgressMonitor progressMonitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragmentRoot[] getAllPackageFragmentRoots() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public Object[] getNonJavaResources() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Map getOptions(boolean inheritJavaCoreOptions) {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragmentRoot getPackageFragmentRoot(String jarPath) {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragmentRoot[] getPackageFragmentRoots() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) {
-        throw new NotImplementedException();
-    }
-
-    public IPackageFragment[] getPackageFragments() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public String[] getRequiredProjectNames() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry)
-            throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public boolean hasBuildState() {
-        throw new NotImplementedException();
-    }
-
-    public boolean hasClasspathCycle(IClasspathEntry[] entries) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isOnClasspath(IJavaElement element) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isOnClasspath(IResource resource) {
-        throw new NotImplementedException();
-    }
-
-    public IEvaluationContext newEvaluationContext() {
-        throw new NotImplementedException();
-    }
-
-    public ITypeHierarchy newTypeHierarchy(IRegion region, IProgressMonitor monitor)
-            throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public ITypeHierarchy newTypeHierarchy(IRegion region, WorkingCopyOwner owner,
-            IProgressMonitor monitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public ITypeHierarchy newTypeHierarchy(IType type, IRegion region, IProgressMonitor monitor)
-            throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public ITypeHierarchy newTypeHierarchy(IType type, IRegion region, WorkingCopyOwner owner,
-            IProgressMonitor monitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IPath readOutputLocation() {
-        throw new NotImplementedException();
-    }
-
-    public IClasspathEntry[] readRawClasspath() {
-        throw new NotImplementedException();
-    }
-
-    @SuppressWarnings("unchecked")
-    public void setOptions(Map newOptions) {
-        throw new NotImplementedException();
-    }
-
-    public void setOutputLocation(IPath path, IProgressMonitor monitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public void setRawClasspath(IClasspathEntry[] entries, boolean canModifyResources,
-            IProgressMonitor monitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation,
-            boolean canModifyResources, IProgressMonitor monitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IJavaElement[] getChildren() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public boolean hasChildren() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public boolean exists() {
-        throw new NotImplementedException();
-    }
-
-    public IJavaElement getAncestor(int ancestorType) {
-        throw new NotImplementedException();
-    }
-
-    public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IResource getCorrespondingResource() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public String getElementName() {
-        throw new NotImplementedException();
-    }
-
-    public int getElementType() {
-        throw new NotImplementedException();
-    }
-
-    public String getHandleIdentifier() {
-        throw new NotImplementedException();
-    }
-
-    public IJavaModel getJavaModel() {
-        throw new NotImplementedException();
-    }
-
-    public IJavaProject getJavaProject() {
-        throw new NotImplementedException();
-    }
-
-    public IOpenable getOpenable() {
-        throw new NotImplementedException();
-    }
-
-    public IJavaElement getParent() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getPath() {
-        throw new NotImplementedException();
-    }
-
-    public IJavaElement getPrimaryElement() {
-        throw new NotImplementedException();
-    }
-
-    public IResource getResource() {
-        throw new NotImplementedException();
-    }
-
-    public ISchedulingRule getSchedulingRule() {
-        throw new NotImplementedException();
-    }
-
-    public IResource getUnderlyingResource() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isReadOnly() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isStructureKnown() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Object getAdapter(Class adapter) {
-        throw new NotImplementedException();
-    }
-
-    public void close() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public String findRecommendedLineSeparator() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public IBuffer getBuffer() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public boolean hasUnsavedChanges() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isConsistent() throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isOpen() {
-        throw new NotImplementedException();
-    }
-
-    public void makeConsistent(IProgressMonitor progress) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public void open(IProgressMonitor progress) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-    public void save(IProgressMonitor progress, boolean force) throws JavaModelException {
-        throw new NotImplementedException();
-    }
-
-	public IJavaElement findElement(String bindingKey, WorkingCopyOwner owner)
-			throws JavaModelException {
-        throw new NotImplementedException();
-	}
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ProjectMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ProjectMock.java
deleted file mode 100644
index 6c32d0f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ProjectMock.java
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.mock;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IProjectNature;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
-import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourceAttributes;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IPluginDescriptor;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.content.IContentTypeMatcher;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
-
-import java.net.URI;
-import java.util.Map;
-
-/**
- * Mock implementation of {@link IProject}.
- * <p/>Supported methods:
- * <ul>
- * <li>{@link #build(int kind, IProgressMonitor monitor)}</li>
- * <li>{@link #members(int kind, String builderName, Map args, IProgressMonitor monitor)}</li>
- * </ul>
- */
-@SuppressWarnings("deprecation")
-public class ProjectMock implements IProject {
-
-    public void build(int kind, IProgressMonitor monitor) throws CoreException {
-        // pass
-    }
-
-    @SuppressWarnings("unchecked")
-    public void build(int kind, String builderName, Map args, IProgressMonitor monitor)
-            throws CoreException {
-        // pass
-    }
-    
-    // -------- UNIMPLEMENTED METHODS ----------------
-
-
-    public void close(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void create(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void create(IProjectDescription description, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void delete(boolean deleteContent, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IContentTypeMatcher getContentTypeMatcher() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IProjectDescription getDescription() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IFile getFile(String name) {
-        throw new NotImplementedException();
-    }
-
-    public IFolder getFolder(String name) {
-        throw new NotImplementedException();
-    }
-
-    public IProjectNature getNature(String natureId) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IPath getPluginWorkingLocation(IPluginDescriptor plugin) {
-        throw new NotImplementedException();
-    }
-
-    public IProject[] getReferencedProjects() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IProject[] getReferencingProjects() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getWorkingLocation(String id) {
-        throw new NotImplementedException();
-    }
-
-    public boolean hasNature(String natureId) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isNatureEnabled(String natureId) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isOpen() {
-        throw new NotImplementedException();
-    }
-
-    public void move(IProjectDescription description, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void open(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void open(int updateFlags, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDescription(IProjectDescription description, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDescription(IProjectDescription description, int updateFlags,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean exists(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IFile[] findDeletedMembersWithHistory(int depth, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(String name) {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(String name, boolean includePhantoms) {
-        throw new NotImplementedException();
-    }
-
-    public IResource findMember(IPath path, boolean includePhantoms) {
-        throw new NotImplementedException();
-    }
-
-    public String getDefaultCharset() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getDefaultCharset(boolean checkImplicit) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IFile getFile(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IFolder getFolder(IPath path) {
-        throw new NotImplementedException();
-    }
-
-    public IResource[] members() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResource[] members(boolean includePhantoms) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResource[] members(int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDefaultCharset(String charset) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDefaultCharset(String charset, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void clearHistory(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IPath destination, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IPath destination, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IMarker createMarker(String type) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IResourceProxy createProxy() {
-        throw new NotImplementedException();
-    }
-
-    public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void deleteMarkers(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean exists() {
-        throw new NotImplementedException();
-    }
-
-    public IMarker findMarker(long id) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public String getFileExtension() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getFullPath() {
-        throw new NotImplementedException();
-    }
-
-    public long getLocalTimeStamp() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getLocation() {
-        throw new NotImplementedException();
-    }
-
-    public URI getLocationURI() {
-        throw new NotImplementedException();
-    }
-
-    public IMarker getMarker(long id) {
-        throw new NotImplementedException();
-    }
-
-    public long getModificationStamp() {
-        throw new NotImplementedException();
-    }
-
-    public String getName() {
-        throw new NotImplementedException();
-    }
-
-    public IContainer getParent() {
-        throw new NotImplementedException();
-    }
-
-    public String getPersistentProperty(QualifiedName key) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public IProject getProject() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getProjectRelativePath() {
-        throw new NotImplementedException();
-    }
-
-    public IPath getRawLocation() {
-        throw new NotImplementedException();
-    }
-
-    public URI getRawLocationURI() {
-        throw new NotImplementedException();
-    }
-
-    public ResourceAttributes getResourceAttributes() {
-        throw new NotImplementedException();
-    }
-
-    public Object getSessionProperty(QualifiedName key) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public int getType() {
-        throw new NotImplementedException();
-    }
-
-    public IWorkspace getWorkspace() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isAccessible() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isDerived() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLinked() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLinked(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isLocal(int depth) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isPhantom() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isReadOnly() {
-        throw new NotImplementedException();
-    }
-
-    public boolean isSynchronized(int depth) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isTeamPrivateMember() {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, boolean force, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IPath destination, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
-            throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void move(IProjectDescription description, boolean force, boolean keepHistory,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void revertModificationStamp(long value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setDerived(boolean isDerived) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public long setLocalTimeStamp(long value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setPersistentProperty(QualifiedName key, String value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setReadOnly(boolean readOnly) {
-        throw new NotImplementedException();
-    }
-
-    public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public void touch(IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    
-    @SuppressWarnings("unchecked")
-    public Object getAdapter(Class adapter) {
-        throw new NotImplementedException();
-    }
-
-    public boolean contains(ISchedulingRule rule) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isConflicting(ISchedulingRule rule) {
-        throw new NotImplementedException();
-    }
-
-    public void create(IProjectDescription description, int updateFlags,
-            IProgressMonitor monitor) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public Map<?,?> getPersistentProperties() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public Map<?,?> getSessionProperties() throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isDerived(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isHidden() {
-        throw new NotImplementedException();
-    }
-
-    public void setHidden(boolean isHidden) throws CoreException {
-        throw new NotImplementedException();
-    }
-
-    public boolean isHidden(int options) {
-        throw new NotImplementedException();
-    }
-
-    public boolean isTeamPrivateMember(int options) {
-        throw new NotImplementedException();
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/AndroidManifest-instrumentation.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/AndroidManifest-instrumentation.xml
deleted file mode 100644
index b380f96..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/AndroidManifest-instrumentation.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.AndroidProject.tests">
-
-    <!--
-    This declares that this app uses the instrumentation test runner targeting
-    the package of com.android.samples.  To run the tests use the command:
-    "adb shell am instrument -w com.android.samples.tests/android.test.InstrumentationTestRunner"
-    -->
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-                     android:targetPackage="com.android.AndroidProject"
-                     android:label="Sample test for deployment."/>
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-</manifest>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/AndroidManifest-testapp.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/AndroidManifest-testapp.xml
deleted file mode 100644
index 8ae7012..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/AndroidManifest-testapp.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.testapp">
-  <application android:icon="@drawable/icon">
-    <activity android:name="com.android.testapp.MainActivity"
-              android:label="@string/app_name">
-      <intent-filter>
-        <action android:name="android.intent.action.MAIN" />
-          <category android:name="android.intent.category.LAUNCHER" />"
-          <category android:name="android.intent.category.DEFAULT" />
-      </intent-filter>
-    </activity>
-    <uses-library android:name="android.test.runner"/>
-  </application>"
-  <instrumentation android:name="android.test.InstrumentationTestRunner"
-                   android:targetPackage="com.example.android.apis"
-                   android:label="Tests for Api Demos."/>
-</manifest>
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jar b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jar
deleted file mode 100644
index f95b595..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jar
+++ /dev/null
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jardesc b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jardesc
deleted file mode 100644
index 14cd44f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jardesc
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
-<jardesc>
-    <jar path="jar_example.jar"/>
-    <options buildIfNeeded="true" compress="true" descriptionLocation="/common/tests/data/jar_example.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
-    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
-    <selectedProjects/>
-    <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
-        <sealing sealJar="false">
-            <packagesToSeal/>
-            <packagesToUnSeal/>
-        </sealing>
-    </manifest>
-    <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
-        <javaElement handleIdentifier="=common/tests&lt;jar.example"/>
-    </selectedElements>
-</jardesc>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml
deleted file mode 100644
index aa9a1f7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml
+++ /dev/null
@@ -1,340 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<resources>
-    <!-- WARNING !!! THIS IS A MOCK FILE. DO NOT USE FOR DOCUMENTATION PURPOSES.
-         This file has been trimmed down to only extract a number of interesting cases 
-         for unit tests.
-         
-         What this contains:
-         - View
-         - ViewGroup
-         - some attributes which format are defined in Theme
-         - orientation, gravity and layout_gravity defined before they are used
-         - ViewGroup_Layout
-         - ViewGroup_MarginLayout
-         - LinearLayout
-         - LinearLayout_Layout
-         - TableLayout
-         
-         Note that TableLayout does not have a TableLayout_Layout definition here
-         where these is a class TableLayout.LayoutData.
-    -->
-
-    <!-- These are the standard attributes that make up a complete theme. -->
-    <declare-styleable name="Theme">
-
-        <!-- Defines the scrollbars size. -->
-        <attr name="scrollbarSize" format="dimension" />
-
-    </declare-styleable>
-
-        
-    <!-- Standard orientation constant. -->
-    <attr name="orientation">
-        <!-- Defines an horizontal widget. -->
-        <enum name="horizontal" value="0" />
-        <!-- Defines a vertical widget. -->
-        <enum name="vertical" value="1" />
-    </attr>
-
-    <!-- Specifies how to place an object, both
-         its x and y axis, within a larger containing object. -->
-    <attr name="gravity">
-        <!-- Push object to the top of its container, not changing its size. -->
-        <flag name="top" value="0x30" />
-        <!-- Push object to the bottom of its container, not changing its size. -->
-        <flag name="bottom" value="0x50" />
-        <!-- Push object to the left of its container, not changing its size. -->
-        <flag name="left" value="0x03" />
-        <!-- Push object to the right of its container, not changing its size. -->
-        <flag name="right" value="0x05" />
-        <!-- Place object in the vertical center of its container, not changing its size. -->
-        <flag name="center_vertical" value="0x10" />
-        <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
-        <flag name="fill_vertical" value="0x70" />
-        <!-- Place object in the horizontal center of its container, not changing its size. -->
-        <flag name="center_horizontal" value="0x01" />
-        <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
-        <flag name="fill_horizontal" value="0x07" />
-        <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
-        <flag name="center" value="0x11" />
-        <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
-        <flag name="fill" value="0x77" />
-    </attr>
-
-    <!-- Standard gravity constant that a child can supply to its parent.
-         Defines how to place an object, both
-         its x and y axis, within a larger containing object. -->
-    <attr name="layout_gravity">
-        <!-- Push object to the top of its container, not changing its size. -->
-        <flag name="top" value="0x30" />
-        <!-- Push object to the bottom of its container, not changing its size. -->
-        <flag name="bottom" value="0x50" />
-        <!-- Push object to the left of its container, not changing its size. -->
-        <flag name="left" value="0x03" />
-        <!-- Push object to the right of its container, not changing its size. -->
-        <flag name="right" value="0x05" />
-        <!-- Place object in the vertical center of its container, not changing its size. -->
-        <flag name="center_vertical" value="0x10" />
-        <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
-        <flag name="fill_vertical" value="0x70" />
-        <!-- Place object in the horizontal center of its container, not changing its size. -->
-        <flag name="center_horizontal" value="0x01" />
-        <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
-        <flag name="fill_horizontal" value="0x07" />
-        <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
-        <flag name="center" value="0x11" />
-        <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
-        <flag name="fill" value="0x77" />
-    </attr>
-
-    <declare-styleable name="View">
-    <!-- NOTE: View does not have a javadoc. Do not place a comment BEFORE View to make sure it
-         is NOT interpreted as Javadoc -->
-    
-        <!-- Supply an identifier name for this view, to later retrieve it
-             with {@link android.view.View#findViewById View.findViewById()} or
-             {@link android.app.Activity#findViewById Activity.findViewById()}.
-             This must be a
-             resource reference; typically you set this using the
-             <code>@+</code> syntax to create a new ID resources.
-             For example: <code>android:id="@+id/my_id"</code> which
-             allows you to later retrieve the view
-             with <code>findViewById(R.id.my_id)</code>. -->
-        <attr name="id" format="reference" />
-        
-        <!-- Supply a tag for this view containing a String, to be retrieved
-             later with {@link android.view.View#getTag View.getTag()} or
-             searched for with {@link android.view.View#findViewWithTag
-             View.findViewWithTag()}.  It is generally preferable to use
-             IDs (through the android:id attribute) instead of tags because
-             they are faster and allow for compile-time type checking. -->
-        <attr name="tag" format="string" />
-        
-        <!-- The initial horizontal scroll offset, in pixels.-->
-        <attr name="scrollX" format="dimension" />
-
-        <!-- The initial vertical scroll offset, in pixels. -->
-        <attr name="scrollY" format="dimension" />
-
-        <!-- A drawable to use as the background.  This can be either a reference
-             to a full drawable resource (such as a PNG image, 9-patch,
-             XML state list description, etc), or a solid color such as "#ff000000"
-            (black). -->
-        <attr name="background" format="reference|color" />
-
-        <!-- Boolean that controls whether a view can take focus.  By default the user can not
-             move focus to a view; by setting this attribute to true the view is
-             allowed to take focus.  This value does not impact the behavior of
-             directly calling {@link android.view.View#requestFocus}, which will
-             always request focus regardless of this view.  It only impacts where
-             focus navigation will try to move focus. -->
-        <attr name="focusable" format="boolean" />
-
-        <!-- Sets the circumstances under which this view will take focus. There are
-             two choices: "weak" or "normal". The default value is "normal" for
-             any focusable views. The focus type only applies if the view
-             has been set to be focusable. -->
-        <attr name="focusType">
-            <!-- This view is focusable, but only if none of its descendants are already focused. -->
-            <enum name="normal" value="0" />
-            <!-- This view will always claim to be focusable. -->
-            <enum name="weak" value="1" />
-        </attr>
-        
-        <!-- Controls the initial visibility of the view.  -->
-        <attr name="visibility">
-            <!-- Visible on screen; the default value. -->
-            <enum name="visible" value="0" />
-            <!-- Not displayed, but taken into account during layout (space is left for it). -->
-            <enum name="invisible" value="1" />
-            <!-- Completely hidden, as if the view had not been added. -->
-            <enum name="gone" value="2" />
-        </attr>
-
-        <!-- Defines which scrollbars should be displayed on scrolling or not. -->
-        <attr name="scrollbars">
-            <!-- No scrollbar is displayed. -->
-            <flag name="none" value="0x00000000" />
-            <!-- Displays horizontal scrollbar only. -->
-            <flag name="horizontal" value="0x00000100" />
-            <!-- Displays vertical scrollbar only. -->
-            <flag name="vertical" value="0x00000200" />
-        </attr>
-
-        <!-- Sets the width of vertical scrollbars and height of horizontal scrollbars. -->
-        <attr name="scrollbarSize" />
-        
-        <!-- Text to display. (copied from TextView for the extra localization) -->
-        <attr name="text" format="string" localization="suggested" />
-        
-    </declare-styleable>
-
-    <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
-         of its subclasses.  Also see {@link #ViewGroup_Layout} for
-         attributes that this class processes in its children. -->
-    <declare-styleable name="ViewGroup">
-        <!-- Defines whether a child is limited to draw inside of its bounds or not.
-             This is useful with animations that scale the size of the children to more
-             than 100% for instance. In such a case, this property should be set to false
-             to allow the children to draw outside of their bounds. The default value of
-             this property is true. -->
-        <attr name="clipChildren" format="boolean" />
-        <!-- Defines the layout animation to use the first time the ViewGroup is laid out.
-             Layout animations can also be started manually after the first layout. -->
-        <attr name="layoutAnimation" format="reference" />
-        <!-- Defines whether a child's animation should be kept when it is over. Keeping
-             the animations is useful with animation whose final state is different from
-             the initial state of the View. This is particularly useful with animation
-             whose fillAfter property is enabled. This property is set to false by default. -->
-        <attr name="persistentDrawingCache">
-            <!-- The drawing cache is not persisted after use. -->
-            <flag name="none" value="0x0" />
-            <!-- The drawing cache is persisted after a layout animation. -->
-            <flag name="animation" value="0x1" />
-            <!-- The drawing cache is persisted after a scroll. -->
-            <flag name="scrolling" value="0x2" />
-            <!-- The drawing cache is always persisted. -->            
-            <flag name="all" value="0x3" />
-        </attr>
-    </declare-styleable>
-
-    <!-- This is the basic set of layout attributes that are common to all
-         layout managers.  These attributes are specified with the rest of
-         a view's normal attributes (such as {@link android.R.attr#background},
-         but will be parsed by the view's parent and ignored by the child.
-        <p>The values defined here correspond to the base layout attribute
-        class {@link android.view.ViewGroup.LayoutParams}. -->
-    <declare-styleable name="ViewGroup_Layout">
-        <!-- Specifies the basic width of the view.  This is a required attribute
-             for any view inside of a containing layout manager.  Its value may
-             be a dimension (such as "12dip") for a constant width or one of
-             the special constants. -->
-        <attr name="layout_width" format="dimension">
-            <!-- The view should be as big as its parent (minus padding). -->
-            <enum name="fill_parent" value="-1" />
-            <!-- The view should be only big enough to enclose its content (plus padding). -->
-            <enum name="wrap_content" value="-2" />
-        </attr>
-
-        <!-- Specifies the basic height of the view.  This is a required attribute
-             for any view inside of a containing layout manager.  Its value may
-             be a dimension (such as "12dip") for a constant height or one of
-             the special constants. -->
-        <attr name="layout_height" format="dimension">
-            <!-- The view should be as big as its parent (minus padding). -->
-            <enum name="fill_parent" value="-1" />
-            <!-- The view should be only big enough to enclose its content (plus padding). -->
-            <enum name="wrap_content" value="-2" />
-        </attr>
-    </declare-styleable>
-
-    <!-- This is the basic set of layout attributes for layout managers that
-         wish to place margins around their child views.
-         These attributes are specified with the rest of
-         a view's normal attributes (such as {@link android.R.attr#background},
-         but will be parsed by the view's parent and ignored by the child.
-        <p>The values defined here correspond to the base layout attribute
-        class {@link android.view.ViewGroup.MarginLayoutParams}. -->
-    <declare-styleable name="ViewGroup_MarginLayout">
-        <attr name="layout_width" />
-        <attr name="layout_height" />
-        <!--  Specifies extra space on the left side of this view.
-            This space is outside this view's bounds. -->
-        <attr name="layout_marginLeft" format="dimension"  />
-        <!--  Specifies extra space on the top side of this view.
-            This space is outside this view's bounds. -->
-        <attr name="layout_marginTop" format="dimension" />
-        <!--  Specifies extra space on the right side of this view.
-            This space is outside this view's bounds. -->
-        <attr name="layout_marginRight" format="dimension"  />
-        <!--  Specifies extra space on the bottom side of this view.
-            This space is outside this view's bounds. -->
-        <attr name="layout_marginBottom" format="dimension"  />
-    </declare-styleable>
-
-    <!-- This is a linear layout. -->
-    <declare-styleable name="LinearLayout">
-        <!-- Should the layout be a column or a row?  Use "horizontal"
-             for a row, "vertical" for a column.  The default is
-             horizontal. -->
-        <attr name="orientation" />
-        <attr name="baselineAligned" format="boolean|reference" />
-        <!-- When a linear layout is part of another layout that is baseline
-          aligned, it can specify which of its children to baseline align to
-          (i.e which child TextView).-->
-        <attr name="baselineAlignedChildIndex" format="integer|color" min="0"/>
-        <!-- Defines the maximum weight sum. If unspecified, the sum is computed
-             by adding the layout_weight of all of the children. This can be
-             used for instance to give a single child 50% of the total available
-             space by giving it a layout_weight of 0.5 and setting the weightSum
-             to 1.0. -->
-        <attr name="weightSum" format="float" />
-    </declare-styleable>
-
-    <declare-styleable name="LinearLayout_Layout">
-        <attr name="layout_width" />
-        <attr name="layout_height" />
-        <attr name="layout_weight" format="float" />
-        <attr name="layout_gravity" />
-    </declare-styleable>
-
-    <declare-styleable name="TableLayout">
-        <!-- The 0 based index of the columns to stretch. The column indices
-             must be separated by a comma: 1, 2, 5. Illegal and duplicate
-             indices are ignored. You can stretch all columns by using the
-             value "*" instead. Note that a column can be marked stretchable
-             and shrinkable at the same time. -->
-        <attr name="stretchColumns" format="string" />
-       <!-- The 0 based index of the columns to shrink. The column indices
-             must be separated by a comma: 1, 2, 5. Illegal and duplicate
-             indices are ignored. You can shrink all columns by using the
-             value "*" instead. Note that a column can be marked stretchable
-             and shrinkable at the same time. -->
-        <attr name="shrinkColumns" format="string" /> 
-        <!-- The 0 based index of the columns to collapse. The column indices
-             must be separated by a comma: 1, 2, 5. Illegal and duplicate
-             indices are ignored. -->
-        <attr name="collapseColumns" format="string" />
-    </declare-styleable>
-
-	<!-- Test for deprecated attributes. -->
-	<declare-styleable name="DeprecatedTest">
-		<!-- Deprecated comments using delimiters.
-			 Ignored. {@deprecated In-line deprecated.} {@ignore Ignored}.
-		 -->
-		<attr name="deprecated-inline" /> 
-
-		<!-- Deprecated comments on their own line.
-			 @deprecated Multi-line version of deprecated
-			    that works till the next tag.
-			 @ignore This tag must be ignored
-		 -->
-		<attr name="deprecated-multiline" />
-		
-		<!-- This attribute is not deprecated. -->
-		<attr name="deprecated-not" />
-		
-        <!-- {@deprecated There is no other javadoc here. } -->
-        <attr name="deprecated-no-javadoc" format="boolean" />
-		
-	</declare-styleable>
-
-</resources>
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/View.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/View.java
deleted file mode 100644
index a80a98d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/View.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.view;
-
-public class View {
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/ViewGroup.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/ViewGroup.java
deleted file mode 100644
index 466470f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/ViewGroup.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.view;
-
-public class ViewGroup extends View {
-
-    public class MarginLayoutParams extends LayoutParams {
-
-    }
-
-    public class LayoutParams {
-
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/LinearLayout.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/LinearLayout.java
deleted file mode 100644
index 3870a63..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/LinearLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.widget;
-
-import mock_android.view.ViewGroup;
-
-public class LinearLayout extends ViewGroup {
-
-    public class LayoutParams extends mock_android.view.ViewGroup.LayoutParams {
-
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/TableLayout.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/TableLayout.java
deleted file mode 100644
index e455e7d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/TableLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.widget;
-
-import mock_android.view.ViewGroup;
-
-public class TableLayout extends ViewGroup {
-
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/eclipse/scripts/_mk_icons.sh b/tools/eclipse/scripts/_mk_icons.sh
deleted file mode 100755
index b3ea35b..0000000
--- a/tools/eclipse/scripts/_mk_icons.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-
-function icon() {
-  # $1=letter, $2=letter's color (e.g. A red), $3=filename
-  ./gen_icon.py ${3}.png 16 white black $2 $1
-}
-
-icon M green  manifest
-  icon S blue   sharedUserId
-  icon S red    signature
-  icon P green  package
-
-icon I green  instrumentation
-  icon F green  functionalTest
-  icon H green  handleProfiling
-  icon I green  icon
-  icon T green  targetPackage
-
-icon U blue   uses-permission
-icon P red    permission
-  icon N green  name
-  icon L blue   label
-
-icon A blue     application
-    icon P red    permission
-    icon P blue   persistent
-    icon P green  process
-    icon T green  taskAffinity
-    icon T blue   theme
-  icon P red    provider
-    icon A green  authorities
-    icon I green  initOrder
-    icon M green  multiprocess
-    icon R green  readPermission
-    icon W green  writePermission
-    icon S green  syncable
-  icon R green  receiver
-  icon S blue   service
-  icon A green  activity
-      icon C blue   clearOnBackground
-      icon C green  configChanges
-      icon E green  excludeFromRecents
-      icon L green  launchMode
-      icon S green  stateNotNeeded
-    icon F blue  intent-filter
-        icon P green  priority
-      icon A red    action
-      icon C green  category
-      icon D green  data
-        icon M green    mimeType
-        icon S green    scheme
-        icon H green    host
-        icon P green    port
-        icon P blue     path
-
diff --git a/tools/eclipse/scripts/build_plugins.sh b/tools/eclipse/scripts/build_plugins.sh
deleted file mode 100755
index 5f94ca0..0000000
--- a/tools/eclipse/scripts/build_plugins.sh
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/bin/bash
-
-# build script for eclipse adt build on linux platform
-#
-# Usage: development/tools/eclipse/scripts/build_plugins <build_version> 
-#
-# It expects environment variable ECLIPSE_HOME to be defined to point to _your_
-# version of Eclipse RCP (must have the WTP & GEF plugins available too.)
-#
-# If ECLIPSE_HOME is not provided, this script will _download_ a reference version
-# of Eclipse RCP and install it in a specific location.
-# 
-# Other properties, ant scripts that drive the build are defined in ./buildConfig
-# Currently, this script will create an update site at ${user.home}/www/no_crawl/android-build
-# or at the directory specified using "-d"
-
-# Known Issues:
-# - Build does not properly clean up after itself (build server always executes from
-#   a clean state.)
-# - Script will fail if current absolute path has spaces in it.
-# - Only linux is supported for now
-
-
-set -e # abort this script early if any command fails
-
-#
-# -- Utility methods --
-# 
-
-function printUsage() {
-  echo "Usage: $0 <build_qualifier> [-i] [-d <destination-directory>] [-a <archivePrefix>] "
-  echo "<build_qualifier>: build qualifier string"
-  echo "-i = build internal site. Otherwise, external site will be built"
-  echo "-d = destination directory. Default is $USER/www/no_crawl/. Cannot contain spaces."
-  echo "-a = archive prefix. Cannot contain spaces."
-}
-
-function die() {
-  echo $@
-  exit 1
-}
-
-function dieWithUsage() {
-  echo $@
-  echo
-  printUsage
-  exit 1
-}
-
-
-#
-# -- Setup our custom version of Eclipse --
-#
-
-# The dependency on the linux platform comes from a series of environment
-# variables that the eclipse ant runner expects. These are defined in the
-# build.properties file. We can easily support other platforms but would need
-# to override those values in this script.
-HOST=`uname`
-[ "$HOST" == "Linux" ] || die "ERROR: This script is currently only supported on Linux platform"
-
-# Make sure this runs from the tools/eclipse plugin.
-D=`dirname "$0"`
-cd "$D/.."
-[ `basename "$PWD"` == "eclipse" ] || dieWithUsage "Please run this script from the device/tools/eclipse directory"
-
-# check for number of parameters
-[ $# -lt 1 ] && dieWithUsage "ERROR: Not enough parameters"
-
-# check if ECLIPSE_HOME set (ECLIPSE_HOME is were the "eclipse" binary and the
-# "plugins" sub-directory are located)
-if [ -z "$ECLIPSE_HOME" ]; then
-  BASE_DIR=/buildbot/eclipse-android
-
-  echo "ECLIPSE_HOME not set, using $BASE_DIR as default"
-
-  if [ ! -d "$BASE_DIR" ]; then
-    mkdir -p "$BASE_DIR" || die "Please create a directory $BASE_DIR where Eclipse will be installed, i.e. execute 'mkdir -p $BASE_DIR && chown $USER $BASE_DIR'."
-  fi
-
-  # download the version if not available
-  VERSION="3.4.0"
-  BASE_DIR="$BASE_DIR/$VERSION"
-  scripts/setup_eclipse.sh -p "$BASE_DIR"
-
-  ECLIPSE_HOME="$BASE_DIR/eclipse"      # path to installed directory
-  PID_FILE="$BASE_DIR/eclipse.pid"
-  [ -f "$PID_FILE" ] && ECLIPSE_PID=`cat "$PID_FILE"`
-fi
-
-echo "PWD=`pwd`"
-echo "ECLIPSE_HOME=$ECLIPSE_HOME"
-
-#
-# -- Site parameters and Build version --
-#
-
-BUILD_VERSION="$1" ; shift
-
-# parse for build internal site flag. If set, pass in internalSite property to ant scripts
-if [ "-i" == "$1" ]; then
-  shift
-  echo "Setting for internal site build"
-  SITE_PARAM="-DinternalSite=1 -DupdateSiteSource=$PWD/sites/internal"
-else
-  SITE_PARAM="-DupdateSiteSource=$PWD/sites/external"
-fi
-
-if [ "-d" == $1 ]; then
-  shift
-  echo "Setting destination directory to $1"
-  SITE_PARAM="$SITE_PARAM -DupdateSiteRoot=$1"
-  shift
-fi
-
-if [ "-a" == "$1" ]; then
-  shift
-  echo "Setting archivePrefix to $1"
-  SITE_PARAM="$SITE_PARAM -DarchivePrefix=$1"
-  shift
-fi
-
-
-#
-# -- Configuration directory --
-#
-
-# The "configuration directory" will hold the workspace for this build.
-# If it contains old data the build may fail so we need to clean it first
-# and create it if it doesn't exist.
-CONFIG_DIR="../../../out/eclipse-configuration-$BUILD_VERSION"
-[ -d "$CONFIG_DIR" ] && rm -rfv "$CONFIG_DIR"
-mkdir -p "$CONFIG_DIR"
-
-# The "buildConfig" directory contains our customized ant rules
-BUILDCONFIG="$PWD/buildConfig"
-
-
-#
-# -- Find Eclipse Launcher --
-#
-
-# Get the Eclipse launcher and build script to use
-function findFirst() {
-  for i in "$@"; do
-    if [ -f "$i" ]; then
-      echo "$i"
-      return
-    fi
-  done
-}
-
-LAUNCHER=`findFirst "$ECLIPSE_HOME"/plugins/org.eclipse.equinox.launcher_*.jar`
-BUILDFILE=`findFirst "$ECLIPSE_HOME"/plugins/org.eclipse.pde.build_*/scripts/build.xml`
-
-# make sure we found valid files
-if [ ! -f "$LAUNCHER" ]; then
-  echo "Installation Error: Eclipse plugin org.eclipse.equinox.launcher...jar not detected. " \
-       "Found '$LAUNCHER'. Aborting."
-  exit 1
-fi
-if [ ! -f "$BUILDFILE" ]; then
-  echo "Installation Error: Eclipse build file org.eclipse.pde.build_.../scripts/build.xml " \
-       "not detected. Found '$BUILDFILE'. Aborting."
-  exit 1
-fi
-
-
-#
-# -- Print configuration used and actually execute the build --
-#
-
-echo "Eclipse configuration found:"
-echo "  Eclipse Home: $ECLIPSE_HOME"
-echo "  Launcher:     $LAUNCHER"
-echo "  Build File:   $BUILDFILE"
-echo "  Build Config: $BUILDCONFIG"
-echo "  Config Dir:   $CONFIG_DIR"
-
-# clean input directories to make sure there's nothing left from previous run
-
-rm -fv *.properties *.xml
-find . -name "@*" | xargs rm -rfv
-
-# Now execute the ant runner
-
-set +e  # don't stop on errors anymore, we want to catch there here
-
-java \
-  -jar $LAUNCHER \
-  -data "$CONFIG_DIR" \
-  -configuration "$CONFIG_DIR" \
-  -application org.eclipse.ant.core.antRunner \
-  -buildfile $BUILDFILE \
-  -Dbuilder=$BUILDCONFIG \
-  -DbuildDirectory=$PWD \
-  -DforceContextQualifier=$BUILD_VERSION \
-  -DECLIPSE_HOME=$ECLIPSE_HOME \
-  $SITE_PARAM
-RESULT=$?
-
-if [ "0" != "$RESULT" ]; then
-    echo "JAVA died with error code $RESULT"
-    echo "Dump of build config logs:"
-    for i in "$CONFIG_DIR"/*.log; do
-        if [ -f "$i" ]; then
-            echo "----------------------"
-            echo "--- $i"
-            echo "----------------------"
-            cat "$i"
-            echo
-        fi
-    done
-fi
-
-#
-# -- Cleanup
-#
-
-if [ -n "$ECLIPSE_PID" ] && [ -f "$PID_FILE" ]; then
-  rm -fv "$PID_FILE"
-  kill -9 "$ECLIPSE_PID"
-fi
-
-# we're done!
diff --git a/tools/eclipse/scripts/build_server.sh b/tools/eclipse/scripts/build_server.sh
deleted file mode 100755
index 39c8dcd..0000000
--- a/tools/eclipse/scripts/build_server.sh
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/bash
-# Entry point to build the Eclipse plugins for the build server.
-#
-# Input parameters:
-# $1: *Mandatory* destination directory. Must already exist. Cannot contain spaces.
-# $2: Optional build number. If present, will be appended to the date qualifier.
-#     The build number cannot contain spaces *nor* periods (dashes are ok.)
-# -z: Optional, prevents the final zip and leaves the udate-site directory intact.
-# -i: Optional, if present, the Google internal update site will be built. Otherwise, 
-#     the external site will be built
-# Workflow:
-# - make dx, ddms, ping
-# - create symlinks (for eclipse code reorg, for ddms, ping)
-# - call the actual builder script from Brett
-# - zip resulting stuff and move to $DEST
-# Note: currently wrap around existing shell script, reuse most of it,
-# eventually both might merge as needed.
-
-set -e  # Fail this script as soon as a command fails -- fail early, fail fast
-
-DEST_DIR=""
-BUILD_NUMBER=""
-CREATE_ZIP="1"
-INTERNAL_BUILD=""
-
-function get_params() {
-  # parse input parameters
-  while [ $# -gt 0 ]; do
-    if [ "$1" == "-z" ]; then
-      CREATE_ZIP=""
-    elif [ "$1" == "-i" ]; then
-      INTERNAL_BUILD="-i"
-    elif [ "$1" != "" ] && [ -z "$DEST_DIR" ]; then
-      DEST_DIR="$1"
-    elif [ "$1" != "" ] && [ -z "$BUILD_NUMBER" ]; then
-      BUILD_NUMBER="$1"
-    fi
-    shift
-  done
-}
-
-function die() {
-  echo "Error:" $*
-  echo "Aborting"
-  exit 1
-}
-
-function check_params() {
-  # This needs to run from the top android directory
-  # Automatically CD to the top android directory, whatever its name
-  D=`dirname "$0"`
-  cd "$D/../../../../" && echo "Switched to directory $PWD"
-
-  # The current Eclipse build has some Linux dependency in its config files
-  [ `uname` == "Linux" ] || die "This must run from a Linux box."
-
-  # Check dest dir exists
-  [ -n "$DEST_DIR" ] || die "Usage: $0 <destination-directory> [build-number]"
-  [ -d "$DEST_DIR" ] || die "Destination directory $DEST_DIR must exist."
-}
-
-function build_libs() {
-  MAKE_OPT="-j8"
-  echo "*** Building: make $MAKE_OPT dx ping ddms jarutils androidprefs layoutlib_api ninepatch sdklib sdkuilib"
-  make $MAKE_OPT dx ping ddms jarutils androidprefs layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib
-}
-
-function build_plugin {
-  development/tools/eclipse/scripts/create_all_symlinks.sh
-
-  # Qualifier is "v" followed by date/time in YYYYMMDDHHSS format and the optional
-  # build number.
-  DATE=`date +v%Y%m%d%H%M`
-  QUALIFIER="$DATE"
-  [ -n "$BUILD_NUMBER" ] && QUALIFIER="${QUALIFIER}-${BUILD_NUMBER}"
-
-  # Compute the final directory name and remove any leftovers from previous
-  # runs if any.
-  BUILD_PREFIX="android-eclipse"  
-  if [ "$INTERNAL_BUILD" ]; then
-    # append 'eng' signifier to end of archive name to denote internal build
-    BUILD_PREFIX="${BUILD_PREFIX}-eng"
-  fi  
-
-  # exclude date from build-zip name so it can be auto-calculated by continuous
-  # test process unless there's no build number, in which case the date is
-  # still used (useful for testing)
-  ZIP_NAME="${BUILD_PREFIX}-${BUILD_NUMBER:-$DATE}.zip"
-  [ -d "$DEST_DIR/$BUILD_PREFIX" ] || rm -rfv "$DEST_DIR/$BUILD_PREFIX"
-
-  # Perform the Eclipse build and move the result in $DEST_DIR/android-build
-  development/tools/eclipse/scripts/build_plugins.sh $QUALIFIER $INTERNAL_BUILD -d "$DEST_DIR" -a "$BUILD_PREFIX"
-
-  # Cleanup
-  [ -d "$QUALIFIER" ] && rm -rfv "$QUALIFIER"
-
-  if [ "$CREATE_ZIP" ]; then
-    # The result is a full update-site under $DEST_DIR/BUILD_PREFIX
-    # Zip it and remove the directory.
-    echo "**** Package in $DEST_DIR"
-    [ -d "$DEST_DIR/$BUILD_PREFIX" ] || \
-      die "Build failed to produce $DEST_DIR/$BUILD_PREFIX"
-    cd "$DEST_DIR"
-    [ -f "$ZIP_NAME" ] && rm -rfv "$ZIP_NAME"
-    cd "$BUILD_PREFIX"
-    zip -9r "../$ZIP_NAME" *
-    cd .. # back to $DEST_DIR
-    rm -rfv "$BUILD_PREFIX"  # removes the directory, not the zip
-    echo "ZIP of Update site available at $DEST_DIR/${ZIP_NAME}"
-  else
-    echo "Update site available in $DEST_DIR/$BUILD_PREFIX"
-  fi
-}
-
-get_params "$@"
-check_params
-build_libs
-build_plugin
diff --git a/tools/eclipse/scripts/build_update_site.sh b/tools/eclipse/scripts/build_update_site.sh
deleted file mode 100755
index 5998756..0000000
--- a/tools/eclipse/scripts/build_update_site.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-# Entry point to build the Eclipse plugins for local deployment.
-#
-# Input parameters:
-# $1: Optional build number. If present, will be appended to the date qualifier.
-#     The build number cannot contain spaces *nor* periods (dashes are ok.)
-# -i: Optional, if present, the Google internal update site will be built. Otherwise, 
-#     the external site will be built
-#
-# Workflow:
-# - calls buildserver with /home/$USER/www/no_crawl and -z
-#   to build and create the update size but do not zip it in the destination directory.
-
-set -e  # Fail this script as soon as a command fails -- fail early, fail fast
-
-D=`dirname $0`
-BUILD_NUMBER=""
-INTERNAL_BUILD=""
-# parse input parameters
-while [ $# -gt 0 ]; do
-  if [ "$1" == "-i" ]; then
-    INTERNAL_BUILD="-i"
-  elif [ "$1" != "" ]; then
-    BUILD_NUMBER="$1"
-  fi
-  shift
-done
-
-DEST_DIR="$HOME"
-[ -z "$DEST_DIR" ] && [ -n "$USER" ] && DEST_DIR="/home/$USER"
-[ -z "$DEST_DIR" ] && DEST_DIR="~"
-DEST_DIR="$DEST_DIR/www/no_crawl"
-
-"$D/build_server.sh" "$DEST_DIR" "$BUILD_NUMBER" -z "$INTERNAL_BUILD"
diff --git a/tools/eclipse/scripts/collect_sources_for_sdk.py b/tools/eclipse/scripts/collect_sources_for_sdk.py
deleted file mode 100755
index 773070b..0000000
--- a/tools/eclipse/scripts/collect_sources_for_sdk.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""
-Description:
-   This script collects all framework Java sources from the current android
-   source code and places them in a source folder suitable for the eclipse ADT
-   plugin.
-
-See usage() below.
-
-Copyright (C) 2009 The Android Open Source Project
-Licensed under the Apache License, Version 2.0 (the "License").
-"""
-
-import re
-import os
-import sys
-import getopt
-import shutil
-
-_RE_PKG = re.compile("^\s*package\s+([^\s;]+)\s*;.*")
-
-# Holds cmd-line arguments
-class Params(object):
-    def __init__(self):
-        self.DRY = False
-        self.DIR = "frameworks"
-        self.SRC = None
-        self.DST = None
-        self.CNT_USED = 0
-        self.CNT_NOPKG = 0
-
-
-# Prints a usage summary
-def usage(error=None):
-    print """
- Description:
-   This script collects all framework Java sources from the current android
-   source code and places them in a source folder suitable for the eclipse ADT
-   plugin.
-
- Usage:
-   %s [-n] <android-git-repo root> <sdk/platforms/xyz/sources>
- 
- The source and destination directories must already exist.
- Use -n for a dry-run.
-
-""" % sys.argv[0]
-
-    if error:
-        print >>sys.stderr, "Error:", error
-
-
-# Parse command line args, returns a Params instance or sys.exit(2) on error
-# after printing the error and the usage.
-def parseArgs(argv):
-    p = Params()
-    error = None
-    
-    try:
-        opts, args = getopt.getopt(argv[1:],
-                                   "ns:",
-                                   [ "--dry", "--sourcedir=" ])
-    except getopt.GetoptError, e:
-        error = str(e)
-
-    if error is None:
-        for o, a in opts:
-            if o in [ "-n", "--dry" ]:
-                p.DRY = True
-            elif o in [ "-s", "--sourcedir" ]:
-                p.DIR = a
-
-        if len(args) != 2:
-            error = "Missing arguments: <source> <dest>"
-        else:
-            p.SRC = args[0]
-            p.DST = args[1]
-
-            if not os.path.isdir(p.SRC):
-                error = "%s is not a directory" % p.SRC
-            elif not os.path.isdir(p.DST):
-                error = "%s is not a directory" % p.DST
-
-    if error:
-        usage(error)
-        sys.exit(2)
-
-    return p
-
-
-# Recursively parses the given directory and process java files found
-def parseSrcDir(p, srcdir):
-    for f in os.listdir(srcdir):
-        fp = os.path.join(srcdir, f)
-        if f.endswith(".java") and os.path.isfile(fp):
-            pkg = checkJavaFile(fp)
-            if pkg:
-                pkg = pkg.replace(".", os.path.sep)  # e.g. android.view => android/view
-                copy(p, fp, f, pkg)
-                p.CNT_USED += 1   # one more copied
-            else:
-                p.CNT_NOPKG += 1  # this java file lacked a package declaration
-        elif os.path.isdir(fp):
-            parseSrcDir(p, fp)
-
-
-# Check a java file to find its package declaration, if any
-def checkJavaFile(path):
-    print "Process", path
-
-    try:
-        f = None
-        try:
-            f = file(path)
-            for l in f.readlines():
-                m = _RE_PKG.match(l)
-                if m:
-                    return m.group(1)
-        finally:
-            if f: f.close()
-    except Exception:
-        pass
-
-    return None
-
-# Create destination directory based on package name then copy the
-# source file in there
-def copy(p, fp, f, pkg):
-    dstdir = os.path.join(p.DST, pkg)
-    _mkdir(p, dstdir)
-    _cp(p, fp, os.path.join(dstdir, f))
-
-def _mkdir(p, dir):
-    if not os.path.isdir(dir):
-        if p.DRY:
-            print "mkdir", dir
-        else:
-            os.makedirs(dir)
-
-def _cp(p, src, dst):
-    if p.DRY:
-        print "cp", src, dst
-    else:
-        shutil.copyfile(src, dst)
-
-
-def main():
-    p = parseArgs(sys.argv)
-    parseSrcDir(p, os.path.join(p.SRC, p.DIR))
-    print "%d java files copied" % p.CNT_USED
-    if p.CNT_NOPKG: print "%d java files ignored (no package)" % p.CNT_NOPKG
-    if p.DRY: print "This was in *DRY* mode. No copies done."
-
-if __name__ == "__main__":
-    main()
diff --git a/tools/eclipse/scripts/create_adt_symlinks.sh b/tools/eclipse/scripts/create_adt_symlinks.sh
deleted file mode 100755
index 1ceb192..0000000
--- a/tools/eclipse/scripts/create_adt_symlinks.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-function die() {
-    echo "Error: $*"
-    exit 1
-}
-
-set -e # fail early
-
-# CD to the top android directory
-D=`dirname "$0"`
-cd "$D/../../../../"
-
-DEST="development/tools/eclipse/plugins/com.android.ide.eclipse.adt"
-# computes "../.." from DEST to here (in /android)
-BACK=`echo $DEST | sed 's@[^/]*@..@g'`
-
-LIBS="sdkstats jarutils androidprefs layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib"
-
-echo "make java libs ..."
-make -j3 showcommands $LIBS || die "ADT: Fail to build one of $LIBS."
-
-echo "Copying java libs to $DEST"
-
-HOST=`uname`
-if [ "$HOST" == "Linux" ]; then
-    for LIB in $LIBS; do
-        ln -svf $BACK/out/host/linux-x86/framework/$LIB.jar "$DEST/"
-    done
-    ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/"
-    ln -svf $BACK/out/host/linux-x86/framework/commons-compress-1.0.jar "$DEST/"
-  
-elif [ "$HOST" == "Darwin" ]; then
-    for LIB in $LIBS; do
-        ln -svf $BACK/out/host/darwin-x86/framework/$LIB.jar "$DEST/"
-    done
-    ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/"
-    ln -svf $BACK/out/host/darwin-x86/framework/commons-compress-1.0.jar "$DEST/"
-
-elif [ "${HOST:0:6}" == "CYGWIN" ]; then
-    for LIB in $LIBS; do
-        cp -vf  out/host/windows-x86/framework/$LIB.jar "$DEST/"
-    done
-
-    if [ ! -f "$DEST/kxml2-2.3.0.jar" ]; then
-        cp -v "prebuilt/common/kxml2/kxml2-2.3.0.jar" "$DEST/"
-    fi
-
-    if [ ! -f "$DEST/commons-compress-1.0.jar" ]; then
-        cp -v "prebuilt/common/commons-compress/commons-compress-1.0.jar" "$DEST/"
-    fi
-
-    chmod -v a+rx "$DEST"/*.jar
-else
-    echo "Unsupported platform ($HOST). Nothing done."
-fi
-
diff --git a/tools/eclipse/scripts/create_all_symlinks.sh b/tools/eclipse/scripts/create_all_symlinks.sh
deleted file mode 100755
index dcbc5b3..0000000
--- a/tools/eclipse/scripts/create_all_symlinks.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-HOST=`uname`
-if [ "${HOST:0:6}" == "CYGWIN" ]; then
-    if [ "x$1" == "x" ] || [ `basename "$1"` != "layoutlib.jar" ]; then
-        echo "Usage: $0 sdk/platforms/xxx/data/layoutlib.jar"
-        echo "Argument 1 should be the path to the layoutlib.jar that should be updated by create_bridge_symlinks.sh."
-        exit 1
-    fi
-fi
-
-echo "### $0 executing"
-
-function die() {
-    echo "Error: $*"
-    exit 1
-}
-
-# CD to the top android directory
-D=`dirname "$0"`
-cd "$D/../../../../"
-
-DEST="development/tools/eclipse/scripts"
-
-set -e # fail early
-
-echo ; echo "### ADT ###" ; echo
-$DEST/create_adt_symlinks.sh "$*"
-echo ; echo "### DDMS ###" ; echo
-$DEST/create_ddms_symlinks.sh "$*"
-echo ; echo "### TEST ###" ; echo
-$DEST/create_test_symlinks.sh "$*"
-echo ; echo "### BRIDGE ###" ; echo
-$DEST/create_bridge_symlinks.sh "$*"
-
-echo "### $0 done"
diff --git a/tools/eclipse/scripts/create_bridge_symlinks.sh b/tools/eclipse/scripts/create_bridge_symlinks.sh
deleted file mode 100755
index 605ef63..0000000
--- a/tools/eclipse/scripts/create_bridge_symlinks.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-function die() {
-    echo "Error: $*"
-    exit 1
-}
-
-set -e # fail early
-
-# CD to the top android directory
-D=`dirname "$0"`
-cd "$D/../../../../"
-
-HOST=`uname`
-if [ "$HOST" == "Linux" ]; then
-    echo # nothing to do
-
-elif [ "$HOST" == "Darwin" ]; then
-    echo # nothing to do
-
-elif [ "${HOST:0:6}" == "CYGWIN" ]; then
-    if [ "x$1" == "x" ] || [ `basename "$1"` != "layoutlib.jar" ]; then
-        echo "Usage: $0 sdk/platforms/xxx/data/layoutlib.jar"
-        echo "Argument 1 should be the path to the layoutlib.jar that should be updated."
-        exit 1
-    fi
-
-    LIBS="layoutlib ninepatch"
-    echo "Make java libs: $LIBS"
-    make -j3 showcommands $LIBS || die "Bridge: Failed to build one of $LIBS."
-
-    echo "Updating your SDK in $1"
-    cp -vf  "out/host/windows-x86/framework/layoutlib.jar" "$1"
-    chmod -v a+rx "$1"
-
-else
-    echo "Unsupported platform ($HOST). Nothing done."
-fi
-
diff --git a/tools/eclipse/scripts/create_ddms_symlinks.sh b/tools/eclipse/scripts/create_ddms_symlinks.sh
deleted file mode 100755
index 87cdf68..0000000
--- a/tools/eclipse/scripts/create_ddms_symlinks.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/bash
-#----------------------------------------------------------------------------|
-# Creates the links to use ddm{ui}lib in the eclipse-ide plugin.
-# Run this from device/tools/eclipse/scripts
-#----------------------------------------------------------------------------|
-
-set -e
-
-HOST=`uname`
-if [ "${HOST:0:6}" == "CYGWIN" ]; then
-    # We can't use symlinks under Cygwin
-
-    function cpfile { # $1=dest $2=source
-        cp -fv $2 $1/
-    }
-
-    function cpdir() { # $1=dest $2=source
-        rsync -avW --delete-after $2 $1
-    }
-
-else
-    # For all other systems which support symlinks
-
-    # computes the "reverse" path, e.g. "a/b/c" => "../../.."
-    function back() {
-        echo $1 | sed 's@[^/]*@..@g'
-    }
-
-    function cpfile { # $1=dest $2=source
-        ln -svf `back $1`/$2 $1/
-    }
-
-    function cpdir() { # $1=dest $2=source
-        ln -svf `back $1`/$2 $1
-    }
-fi
-
-# CD to the top android directory
-D=`dirname "$0"`
-cd "$D/../../../../"
-
-
-BASE="development/tools/eclipse/plugins/com.android.ide.eclipse.ddms"
-
-DEST=$BASE/libs
-mkdir -p $DEST
-for i in prebuilt/common/jfreechart/*.jar; do
-  cpfile $DEST $i
-done
-
-DEST=$BASE/src/com/android
-mkdir -p $DEST
-for i in development/tools/ddms/libs/ddmlib/src/com/android/ddmlib \
-         development/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib ; do
-  cpdir $DEST $i
-done
-
-DEST=$BASE/icons
-mkdir -p $DEST
-for i in \
-    add.png \
-    backward.png \
-    clear.png \
-    d.png debug-attach.png debug-error.png debug-wait.png delete.png device.png down.png \
-    e.png edit.png empty.png emulator.png \
-    forward.png \
-    gc.png \
-    heap.png halt.png hprof.png \
-    i.png importBug.png \
-    load.png \
-    pause.png play.png pull.png push.png \
-    save.png \
-    thread.png tracing_start.png tracing_stop.png \
-    up.png \
-    v.png \
-    w.png warning.png ; do
-  cpfile $DEST development/tools/ddms/libs/ddmuilib/src/resources/images/$i
-done
-
diff --git a/tools/eclipse/scripts/create_test_symlinks.sh b/tools/eclipse/scripts/create_test_symlinks.sh
deleted file mode 100755
index 2b2405b..0000000
--- a/tools/eclipse/scripts/create_test_symlinks.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# CD to the top android directory
-D=`dirname "$0"`
-cd "$D/../../../../"
-
-# computes relative ".." paths from $1 to here (in /android)
-function back() {
-  echo $1 | sed 's@[^/]*@..@g'
-}
-
-HOST=`uname`
-if [ "${HOST:0:6}" == "CYGWIN" ]; then
-    # We can't use symlinks under Cygwin
-    function cpdir() { # $1=dest $2=source
-        echo "rsync $2 => $1"
-        rsync -avW --delete-after $2 $1
-    }
-
-else
-    # For all other systems which support symlinks
-    function cpdir() { # $1=dest $2=source
-        ln -svf `back $1`/$2 $1
-    }
-fi
-
-BASE="development/tools/eclipse/plugins/com.android.ide.eclipse.tests"
-DEST=$BASE
-BACK=`back $DEST`
-
-HOST=`uname`
-if [ "$HOST" == "Linux" ]; then
-    ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/"
-    ln -svf $BACK/out/host/linux-x86/framework/layoutlib.jar   "$DEST/"
-
-elif [ "$HOST" == "Darwin" ]; then
-    ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/"
-    ln -svf $BACK/out/host/darwin-x86/framework/layoutlib.jar   "$DEST/"
-
-elif [ "${HOST:0:6}" == "CYGWIN" ]; then
-    if [ ! -f "$DEST/kxml2-2.3.0.jar" ]; then
-        cp -v "prebuilt/common/kxml2/kxml2-2.3.0.jar" "$DEST/"
-    fi
-
-    LIBS="layoutlib.jar"
-    NEED_MAKE="yes"
-    for LIB in $LIBS ; do
-        SRCJAR="out/host/windows-x86/framework/$LIB"
-        DSTJAR="$DEST/$LIB"
-        if [[ $NEED_MAKE ]] && ! diff -q "$SRCJAR" "$DSTJAR" >/dev/null ; then
-            MAKE_LIBS="${LIBS//.jar/}"
-            echo "Make java libs: $MAKE_LIBS"
-            make -j3 showcommands $MAKE_LIBS || die "adt-tests: Failed to build one of $LIBS."
-            NEED_MAKE=""
-        fi
-        
-        cp -v "$SRCJAR" "$DSTJAR"
-    done
-
-    chmod -v a+rx "$DEST"/*.jar
-else
-    echo "Unsupported platform ($HOST). Nothing done."
-fi
-
-# create link to ddmlib tests
-DEST=$BASE/unittests/com/android
-cpdir $DEST development/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib
-cpdir $DEST development/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib
-
-DEST=$BASE/unittests/com/android/layoutlib
-mkdir -p $DEST
-cpdir $DEST frameworks/base/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge
-cpdir $DEST frameworks/base/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata
-
diff --git a/tools/eclipse/scripts/gen_icon.py b/tools/eclipse/scripts/gen_icon.py
deleted file mode 100755
index f6274e1..0000000
--- a/tools/eclipse/scripts/gen_icon.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import StringIO
-try:
-    import Image, ImageDraw, ImageFont
-except ImportError, e:
-    print str(e)
-    print "Are you missing the Python Imaging Library? (apt-get install python-imaging)"
-    sys.exit(1)
-
-FONT_PATH = "/usr/share/fonts/truetype/msttcorefonts/arial.ttf"
-
-class Args(object):
-    def __init__(self, dest_name, size, circle_color, border_color,
-                 letter_color, letter):
-        self.dest_name = dest_name
-        self.size = size
-        self.circle_color = circle_color
-        self.border_color = border_color
-        self.letter_color = letter_color
-        self.letter = letter
-
-def main(args):
-    data = process_args(args)
-    if data:
-        createImage(data)
-
-def process_args(args):
-    if not args or len(args) != 6:
-        usage()
-    return Args(*args)
-    
-def usage():
-    print """Usage: %s <file_name> <size> <circle-color> <border-color> <letter-color> <letter>""" % sys.argv[0]
-    sys.exit(1)
-
-def createImage(data):
-    zoom = 4
-    rmin = -zoom/2
-    rmax = zoom/2
-    if zoom > 1:
-        r = range(-zoom/2, zoom/2+1)
-    else:
-        r = [ 0 ]
-    sz = int(data.size)
-    sz4 = sz * zoom
-    
-    img = Image.new("RGBA", (sz4, sz4), (255,255,255,0))
-    draw = ImageDraw.Draw(img)
-
-    draw.ellipse((0, 0, sz4-zoom, sz4-zoom),
-                     fill=data.circle_color, outline=None)
-    for i in r:
-        draw.ellipse((i, i, sz4-i-zoom, sz4-i-zoom),
-                     fill=None, outline=data.border_color)
-
-    font = ImageFont.truetype(FONT_PATH, int(sz4 * .75))
-    tsx, tsy = draw.textsize(data.letter, font=font)
-
-    ptx = (sz4 - tsx) / 2
-    pty = (sz4 - tsy) / 2
-    for i in r:
-        draw.text((ptx + i, pty), data.letter, font=font, fill=data.letter_color)
-
-    img = img.resize((sz, sz), Image.BICUBIC)
-    img.save(data.dest_name, "PNG")
-    print "Saved", data.dest_name
-
-if __name__ == "__main__":
-    main(sys.argv[1:])
diff --git a/tools/eclipse/scripts/setup_eclipse.sh b/tools/eclipse/scripts/setup_eclipse.sh
deleted file mode 100755
index 5143e23..0000000
--- a/tools/eclipse/scripts/setup_eclipse.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/bash
-
-# Quick script used to setup Eclipse for the ADT plugin build.
-#
-# usage:
-#   setup_eclipse.sh <dest_dir>
-#
-# Workflow:
-# - downloads & unpack Eclipse if necessary
-# - *runs* it once
-
-
-#-----------------
-#
-# Note: right now this is invoked by //device/tools/eclipse/doBuild.sh
-# and it *MUST* be invoked with the following destination directory:
-#
-# $ setup_eclipse.sh /buildbot/eclipse-android/3.4.0/
-#
-#-----------------
-
-
-set -e # abort this script early if any command fails
-
-function die() {
-  echo $@
-  exit 1
-}
-
-if [ "-p" == "$1" ]; then
-  GET_PID="-p"
-  shift
-fi
-
-BASE_DIR="$1"
-
-[ -n "$1" ] || die "Usage: $0 <dest-dir>"
-
-# URL for 3.4.0 RCP Linux 32 Bits. Includes GEF, WTP as needed.
-DOWNLOAD_URL="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/ganymede/R/eclipse-rcp-ganymede-linux-gtk.tar.gz&url=http://eclipse.unixheads.org/technology/epp/downloads/release/ganymede/R/eclipse-rcp-ganymede-linux-gtk.tar.gz&mirror_id=480"
-
-BIN="$BASE_DIR/eclipse/eclipse"           # path to installed binary
-TARGZ="$BASE_DIR/eclipse-rcp-ganymede-linux-gtk.tar.gz"
-
-if [ ! -f "$BIN" ]; then   
-  echo "Downloading and installing Eclipse in $BASE_DIR."
-  mkdir -p "$BASE_DIR"
-  wget --continue --no-verbose --output-document="$TARGZ" "$DOWNLOAD_URL"
-  echo "Unpacking $TARGZ"
-  (cd "$BASE_DIR" && tar xzf "$TARGZ")
-    
-  echo
-  echo "*** WARNING: To setup Eclipse correctly, it must be ran at least once manually"
-  echo "***          Eclipse will now start."
-  echo
-  if [ -n "$GET_PID" ]; then
-    # if started from the automatic eclipse build, run Eclipse in the background
-    "$BIN" &
-    ECLIPSE_PID=$!
-    echo "*** Eclipse started in background with PID $ECLIPSE_PID"
-    echo "$ECLIPSE_PID" > "$BASE_DIR"/eclipse.pid
-    sleep 5  # give some time for Eclipse to start and setup its environment
-  else
-    # if started manually, run Eclipse in the foreground
-    "$BIN"
-  fi
-fi
diff --git a/tools/eclipse/scripts/update_version.sh b/tools/eclipse/scripts/update_version.sh
deleted file mode 100644
index a288965..0000000
--- a/tools/eclipse/scripts/update_version.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-
-OLD="$1"
-NEW="$2"
-
-# sanity check in input args
-if [ -z "$OLD" ] || [ -z "$NEW" ]; then
-    cat <<EOF
-Usage: $0 <old> <new>
-Changes the ADT plugin revision number.
-Example:
-  cd tools/eclipse
-  scripts/update_version.sh 0.1.2 0.2.3
-EOF
-    exit 1
-fi
-
-# sanity check on current dir
-if [ `basename "$PWD"` != "eclipse" ]; then
-    echo "Please run this from tools/eclipse."
-    exit 1
-fi
-
-# quote dots for regexps
-OLD="${OLD//./\.}"
-NEW="${NEW//./\.}"
-
-# Find all the files with the old pattern, except changes.txt and
-# p4 edit them. Skip that if there's no p4 in path.
-if which g4 1>/dev/null 2>/dev/null ; then
-    grep -rl "$OLD" * | grep -E "\.xml$|\.MF$" | xargs -n 5 g4 edit
-fi
-
-# Now find the same files but this time use sed to replace in-place with
-# the new pattern. Old files get backuped with the .old extension.
-grep -rl "$OLD" * | grep -E "\.xml$|\.MF$" | xargs -n 1 sed -i.old "s/$OLD/$NEW/g"
-
diff --git a/tools/eclipse/sites/external/.project b/tools/eclipse/sites/external/.project
deleted file mode 100644
index 9916269..0000000
--- a/tools/eclipse/sites/external/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>external-site</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.UpdateSiteBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.UpdateSiteNature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/sites/external/index.html b/tools/eclipse/sites/external/index.html
deleted file mode 100644
index 784be4b..0000000
--- a/tools/eclipse/sites/external/index.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<html>
-<head>
-<title>Android Development Toolkit update site.</title>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<style>@import url("web/site.css");</style>
-<script type="text/javascript">
-	var returnval = 0;
-	var stylesheet, xmlFile, cache, doc;
-	function init(){
-		// NSCP 7.1+ / Mozilla 1.4.1+ / Safari
-		// Use the standard DOM Level 2 technique, if it is supported
-		if (document.implementation && document.implementation.createDocument) {
-			xmlFile = document.implementation.createDocument("", "", null);
-			stylesheet = document.implementation.createDocument("", "", null);
-			if (xmlFile.load){
-				xmlFile.load("site.xml");
-				stylesheet.load("web/site.xsl");
-			} else {
-				alert("Document could not be loaded by browser.");
-			}
-			xmlFile.addEventListener("load", transform, false);
-			stylesheet.addEventListener("load", transform, false);
-		}
-		//IE 6.0+ solution
-		else if (window.ActiveXObject) {
-			xmlFile = new ActiveXObject("msxml2.DOMDocument.3.0");
-			xmlFile.async = false;
-			xmlFile.load("site.xml");
-			stylesheet = new ActiveXObject("msxml2.FreeThreadedDOMDocument.3.0");
-			stylesheet.async = false;
-			stylesheet.load("web/site.xsl");
-			cache = new ActiveXObject("msxml2.XSLTemplate.3.0");
-			cache.stylesheet = stylesheet;
-			transformData();
-		}
-	}
-	// separate transformation function for IE 6.0+
-	function transformData(){
-		var processor = cache.createProcessor();
-		processor.input = xmlFile;
-		processor.transform();
-		data.innerHTML = processor.output;
-	}
-	// separate transformation function for NSCP 7.1+ and Mozilla 1.4.1+
-	function transform(){
-		returnval+=1;
-		if (returnval==2){
-			var processor = new XSLTProcessor();
-			processor.importStylesheet(stylesheet);
-			doc = processor.transformToDocument(xmlFile);
-			document.getElementById("data").innerHTML = doc.documentElement.innerHTML;
-		}
-	}
-</script>
-</head>
-<body onload="init();">
-<!--[insert static HTML here]-->
-<div id="data"><!-- this is where the transformed data goes --></div>
-</body>
-</html>
diff --git a/tools/eclipse/sites/external/site.xml b/tools/eclipse/sites/external/site.xml
deleted file mode 100644
index ef0df64..0000000
--- a/tools/eclipse/sites/external/site.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<site>
-   <description url="https://dl-ssl.google.com/android/eclipse/">
-      Update Site for Android Development Toolkit
-   </description>
-   <feature url="features/com.android.ide.eclipse.adt_0.9.4.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.4.qualifier">
-      <category name="developer"/>
-   </feature>
-   <feature url="features/com.android.ide.eclipse.ddms_0.9.4.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.4.qualifier">
-      <category name="developer"/>
-   </feature>
-   <category-def name="developer" label="Developer Tools">
-      <description>
-         Features that add Android support to Eclipse for application developers.
-      </description>
-   </category-def>
-</site>
diff --git a/tools/eclipse/sites/external/web/site.css b/tools/eclipse/sites/external/web/site.css
deleted file mode 100644
index 62c6f9f..0000000
--- a/tools/eclipse/sites/external/web/site.css
+++ /dev/null
@@ -1,12 +0,0 @@
-<STYLE type="text/css">
-td.spacer {padding-bottom: 10px; padding-top: 10px;}
-.title { font-family: sans-serif; color: #99AACC;}
-.bodyText { font-family: sans-serif; font-size: 9pt; color:#000000;  }
-.sub-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white;}
-.log-text {font-family: sans-serif; font-style: normal; font-weight: lighter; font-size: 8pt; color:black;}
-.big-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white; border-top:10px solid white;}
-.light-row {background:#FFFFFF}
-.dark-row {background:#EEEEFF}
-.header {background:#99AADD}
-#indent {word-wrap : break-word;width :300px;text-indent:10px;}
-</STYLE>
diff --git a/tools/eclipse/sites/external/web/site.xsl b/tools/eclipse/sites/external/web/site.xsl
deleted file mode 100644
index a94157d..0000000
--- a/tools/eclipse/sites/external/web/site.xsl
+++ /dev/null
@@ -1,214 +0,0 @@
-<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl="urn:schemas-microsoft-com:xslt">
-<xsl:output method="html" encoding="UTF-8"/>
-<xsl:key name="cat" match="category" use="@name"/>
-<xsl:template match="/">
-<xsl:for-each select="site">
-	<html>
-	<head>
-	<title>update-site</title>
-	<style>@import url("web/site.css");</style>
-	</head>
-	<body>
-	<h1 class="title">update-site</h1>
-	<p class="bodyText"><xsl:value-of select="description"/></p>
-	<table width="100%" border="0" cellspacing="1" cellpadding="2">
-	<xsl:for-each select="category-def">
-		<xsl:sort select="@label" order="ascending" case-order="upper-first"/>
-		<xsl:sort select="@name" order="ascending" case-order="upper-first"/>
-	<xsl:if test="count(key('cat',@name)) != 0">
-			<tr class="header">
-				<td class="sub-header" width="30%">
-					<xsl:value-of select="@name"/>
-				</td>
-				<td class="sub-header" width="70%">
-					<xsl:value-of select="@label"/>
-				</td>
-			</tr>
-			<xsl:for-each select="key('cat',@name)">
-			<xsl:sort select="ancestor::feature//@version" order="ascending"/>
-			<xsl:sort select="ancestor::feature//@id" order="ascending" case-order="upper-first"/>
-			<tr>
-				<xsl:choose>
-				<xsl:when test="(position() mod 2 = 1)">
-					<xsl:attribute name="class">dark-row</xsl:attribute>
-				</xsl:when>
-				<xsl:otherwise>
-					<xsl:attribute name="class">light-row</xsl:attribute>
-				</xsl:otherwise>
-				</xsl:choose>
-				<td class="log-text" id="indent">
-						<xsl:choose>
-						<xsl:when test="ancestor::feature//@label">
-							<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@label"/></a>
-							<br/>
-							<div id="indent">
-							(<xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/>)
-							</div>
-						</xsl:when>
-						<xsl:otherwise>
-						<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/></a>
-						</xsl:otherwise>
-						</xsl:choose>
-						<br />
-				</td>
-				<td>
-					<table>
-						<xsl:if test="ancestor::feature//@os">
-							<tr><td class="log-text" id="indent">Operating Systems:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@os"/></td>
-							</tr>
-						</xsl:if>
-						<xsl:if test="ancestor::feature//@ws">
-							<tr><td class="log-text" id="indent">Windows Systems:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@ws"/></td>
-							</tr>
-						</xsl:if>
-						<xsl:if test="ancestor::feature//@nl">
-							<tr><td class="log-text" id="indent">Languages:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@nl"/></td>
-							</tr>
-						</xsl:if>
-						<xsl:if test="ancestor::feature//@arch">
-							<tr><td class="log-text" id="indent">Architecture:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@arch"/></td>
-							</tr>
-						</xsl:if>
-					</table>
-				</td>
-			</tr>
-			</xsl:for-each>
-			<tr><td class="spacer"><br/></td><td class="spacer"><br/></td></tr>
-		</xsl:if>
-	</xsl:for-each>
-	<xsl:if test="count(feature)  &gt; count(feature/category)">
-	<tr class="header">
-		<td class="sub-header" colspan="2">
-		Uncategorized
-		</td>
-	</tr>
-	</xsl:if>
-	<xsl:choose>
-	<xsl:when test="function-available('msxsl:node-set')">
-	   <xsl:variable name="rtf-nodes">
-		<xsl:for-each select="feature[not(category)]">
-			<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
-			<xsl:sort select="@version" order="ascending" />
-			<xsl:value-of select="."/>
-			<xsl:copy-of select="." />
-		</xsl:for-each>
-	   </xsl:variable>
-	   <xsl:variable name="myNodeSet" select="msxsl:node-set($rtf-nodes)/*"/>
-	<xsl:for-each select="$myNodeSet">
-	<tr>
-		<xsl:choose>
-		<xsl:when test="position() mod 2 = 1">
-		<xsl:attribute name="class">dark-row</xsl:attribute>
-		</xsl:when>
-		<xsl:otherwise>
-		<xsl:attribute name="class">light-row</xsl:attribute>
-		</xsl:otherwise>
-		</xsl:choose>
-		<td class="log-text" id="indent">
-			<xsl:choose>
-			<xsl:when test="@label">
-				<a href="{@url}"><xsl:value-of select="@label"/></a>
-				<br />
-				<div id="indent">
-				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
-				</div>
-			</xsl:when>
-			<xsl:otherwise>
-				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
-			</xsl:otherwise>
-			</xsl:choose>
-			<br /><br />
-		</td>
-		<td>
-			<table>
-				<xsl:if test="@os">
-					<tr><td class="log-text" id="indent">Operating Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@ws">
-					<tr><td class="log-text" id="indent">Windows Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@nl">
-					<tr><td class="log-text" id="indent">Languages:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@arch">
-					<tr><td class="log-text" id="indent">Architecture:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
-					</tr>
-				</xsl:if>
-			</table>
-		</td>
-	</tr>
-	</xsl:for-each>
-	</xsl:when>
-	<xsl:otherwise>
-	<xsl:for-each select="feature[not(category)]">
-	<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
-	<xsl:sort select="@version" order="ascending" />
-	<tr>
-		<xsl:choose>
-		<xsl:when test="count(preceding-sibling::feature[not(category)]) mod 2 = 1">
-		<xsl:attribute name="class">dark-row</xsl:attribute>
-		</xsl:when>
-		<xsl:otherwise>
-		<xsl:attribute name="class">light-row</xsl:attribute>
-		</xsl:otherwise>
-		</xsl:choose>
-		<td class="log-text" id="indent">
-			<xsl:choose>
-			<xsl:when test="@label">
-				<a href="{@url}"><xsl:value-of select="@label"/></a>
-				<br />
-				<div id="indent">
-				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
-				</div>
-			</xsl:when>
-			<xsl:otherwise>
-				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
-			</xsl:otherwise>
-			</xsl:choose>
-			<br /><br />
-		</td>
-		<td>
-			<table>
-				<xsl:if test="@os">
-					<tr><td class="log-text" id="indent">Operating Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@ws">
-					<tr><td class="log-text" id="indent">Windows Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@nl">
-					<tr><td class="log-text" id="indent">Languages:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@arch">
-					<tr><td class="log-text" id="indent">Architecture:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
-					</tr>
-				</xsl:if>
-			</table>
-		</td>
-	</tr>
-	</xsl:for-each>
-	</xsl:otherwise>
-	</xsl:choose>
-	</table>
-	</body>
-	</html>
-</xsl:for-each>
-</xsl:template>
-</xsl:stylesheet>
diff --git a/tools/eclipse/sites/internal/.project b/tools/eclipse/sites/internal/.project
deleted file mode 100644
index 0bd658d..0000000
--- a/tools/eclipse/sites/internal/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>internal-site</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.UpdateSiteBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.UpdateSiteNature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eclipse/sites/internal/index.html b/tools/eclipse/sites/internal/index.html
deleted file mode 100644
index 784be4b..0000000
--- a/tools/eclipse/sites/internal/index.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<html>
-<head>
-<title>Android Development Toolkit update site.</title>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<style>@import url("web/site.css");</style>
-<script type="text/javascript">
-	var returnval = 0;
-	var stylesheet, xmlFile, cache, doc;
-	function init(){
-		// NSCP 7.1+ / Mozilla 1.4.1+ / Safari
-		// Use the standard DOM Level 2 technique, if it is supported
-		if (document.implementation && document.implementation.createDocument) {
-			xmlFile = document.implementation.createDocument("", "", null);
-			stylesheet = document.implementation.createDocument("", "", null);
-			if (xmlFile.load){
-				xmlFile.load("site.xml");
-				stylesheet.load("web/site.xsl");
-			} else {
-				alert("Document could not be loaded by browser.");
-			}
-			xmlFile.addEventListener("load", transform, false);
-			stylesheet.addEventListener("load", transform, false);
-		}
-		//IE 6.0+ solution
-		else if (window.ActiveXObject) {
-			xmlFile = new ActiveXObject("msxml2.DOMDocument.3.0");
-			xmlFile.async = false;
-			xmlFile.load("site.xml");
-			stylesheet = new ActiveXObject("msxml2.FreeThreadedDOMDocument.3.0");
-			stylesheet.async = false;
-			stylesheet.load("web/site.xsl");
-			cache = new ActiveXObject("msxml2.XSLTemplate.3.0");
-			cache.stylesheet = stylesheet;
-			transformData();
-		}
-	}
-	// separate transformation function for IE 6.0+
-	function transformData(){
-		var processor = cache.createProcessor();
-		processor.input = xmlFile;
-		processor.transform();
-		data.innerHTML = processor.output;
-	}
-	// separate transformation function for NSCP 7.1+ and Mozilla 1.4.1+
-	function transform(){
-		returnval+=1;
-		if (returnval==2){
-			var processor = new XSLTProcessor();
-			processor.importStylesheet(stylesheet);
-			doc = processor.transformToDocument(xmlFile);
-			document.getElementById("data").innerHTML = doc.documentElement.innerHTML;
-		}
-	}
-</script>
-</head>
-<body onload="init();">
-<!--[insert static HTML here]-->
-<div id="data"><!-- this is where the transformed data goes --></div>
-</body>
-</html>
diff --git a/tools/eclipse/sites/internal/site.xml b/tools/eclipse/sites/internal/site.xml
deleted file mode 100644
index 31744d7..0000000
--- a/tools/eclipse/sites/internal/site.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<site>
-   <description url="https://android.corp.google.com/adt/">
-      Update Site for Android Development Toolkit
-   </description>
-   <feature url="features/com.android.ide.eclipse.adt_0.9.4.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.4.qualifier">
-      <category name="developer"/>
-   </feature>
-   <feature url="features/com.android.ide.eclipse.ddms_0.9.4.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.4.qualifier">
-      <category name="developer"/>
-   </feature>
-   <feature url="features/com.android.ide.eclipse.tests_0.9.4.qualifier.jar" id="com.android.ide.eclipse.tests" version="0.9.4.qualifier">
-      <category name="test"/>
-   </feature>
-   <category-def name="developer" label="Application Developer Tools">
-      <description>
-         Features that add Android support to Eclipse for application developers.
-      </description>
-   </category-def>
-   <category-def name="test" label="Plugin Developer Tests">
-      <description>
-         Tests for the other Android plugins
-      </description>
-   </category-def>
-</site>
diff --git a/tools/eclipse/sites/internal/web/site.css b/tools/eclipse/sites/internal/web/site.css
deleted file mode 100644
index 62c6f9f..0000000
--- a/tools/eclipse/sites/internal/web/site.css
+++ /dev/null
@@ -1,12 +0,0 @@
-<STYLE type="text/css">
-td.spacer {padding-bottom: 10px; padding-top: 10px;}
-.title { font-family: sans-serif; color: #99AACC;}
-.bodyText { font-family: sans-serif; font-size: 9pt; color:#000000;  }
-.sub-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white;}
-.log-text {font-family: sans-serif; font-style: normal; font-weight: lighter; font-size: 8pt; color:black;}
-.big-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white; border-top:10px solid white;}
-.light-row {background:#FFFFFF}
-.dark-row {background:#EEEEFF}
-.header {background:#99AADD}
-#indent {word-wrap : break-word;width :300px;text-indent:10px;}
-</STYLE>
diff --git a/tools/eclipse/sites/internal/web/site.xsl b/tools/eclipse/sites/internal/web/site.xsl
deleted file mode 100644
index a94157d..0000000
--- a/tools/eclipse/sites/internal/web/site.xsl
+++ /dev/null
@@ -1,214 +0,0 @@
-<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl="urn:schemas-microsoft-com:xslt">
-<xsl:output method="html" encoding="UTF-8"/>
-<xsl:key name="cat" match="category" use="@name"/>
-<xsl:template match="/">
-<xsl:for-each select="site">
-	<html>
-	<head>
-	<title>update-site</title>
-	<style>@import url("web/site.css");</style>
-	</head>
-	<body>
-	<h1 class="title">update-site</h1>
-	<p class="bodyText"><xsl:value-of select="description"/></p>
-	<table width="100%" border="0" cellspacing="1" cellpadding="2">
-	<xsl:for-each select="category-def">
-		<xsl:sort select="@label" order="ascending" case-order="upper-first"/>
-		<xsl:sort select="@name" order="ascending" case-order="upper-first"/>
-	<xsl:if test="count(key('cat',@name)) != 0">
-			<tr class="header">
-				<td class="sub-header" width="30%">
-					<xsl:value-of select="@name"/>
-				</td>
-				<td class="sub-header" width="70%">
-					<xsl:value-of select="@label"/>
-				</td>
-			</tr>
-			<xsl:for-each select="key('cat',@name)">
-			<xsl:sort select="ancestor::feature//@version" order="ascending"/>
-			<xsl:sort select="ancestor::feature//@id" order="ascending" case-order="upper-first"/>
-			<tr>
-				<xsl:choose>
-				<xsl:when test="(position() mod 2 = 1)">
-					<xsl:attribute name="class">dark-row</xsl:attribute>
-				</xsl:when>
-				<xsl:otherwise>
-					<xsl:attribute name="class">light-row</xsl:attribute>
-				</xsl:otherwise>
-				</xsl:choose>
-				<td class="log-text" id="indent">
-						<xsl:choose>
-						<xsl:when test="ancestor::feature//@label">
-							<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@label"/></a>
-							<br/>
-							<div id="indent">
-							(<xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/>)
-							</div>
-						</xsl:when>
-						<xsl:otherwise>
-						<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/></a>
-						</xsl:otherwise>
-						</xsl:choose>
-						<br />
-				</td>
-				<td>
-					<table>
-						<xsl:if test="ancestor::feature//@os">
-							<tr><td class="log-text" id="indent">Operating Systems:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@os"/></td>
-							</tr>
-						</xsl:if>
-						<xsl:if test="ancestor::feature//@ws">
-							<tr><td class="log-text" id="indent">Windows Systems:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@ws"/></td>
-							</tr>
-						</xsl:if>
-						<xsl:if test="ancestor::feature//@nl">
-							<tr><td class="log-text" id="indent">Languages:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@nl"/></td>
-							</tr>
-						</xsl:if>
-						<xsl:if test="ancestor::feature//@arch">
-							<tr><td class="log-text" id="indent">Architecture:</td>
-							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@arch"/></td>
-							</tr>
-						</xsl:if>
-					</table>
-				</td>
-			</tr>
-			</xsl:for-each>
-			<tr><td class="spacer"><br/></td><td class="spacer"><br/></td></tr>
-		</xsl:if>
-	</xsl:for-each>
-	<xsl:if test="count(feature)  &gt; count(feature/category)">
-	<tr class="header">
-		<td class="sub-header" colspan="2">
-		Uncategorized
-		</td>
-	</tr>
-	</xsl:if>
-	<xsl:choose>
-	<xsl:when test="function-available('msxsl:node-set')">
-	   <xsl:variable name="rtf-nodes">
-		<xsl:for-each select="feature[not(category)]">
-			<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
-			<xsl:sort select="@version" order="ascending" />
-			<xsl:value-of select="."/>
-			<xsl:copy-of select="." />
-		</xsl:for-each>
-	   </xsl:variable>
-	   <xsl:variable name="myNodeSet" select="msxsl:node-set($rtf-nodes)/*"/>
-	<xsl:for-each select="$myNodeSet">
-	<tr>
-		<xsl:choose>
-		<xsl:when test="position() mod 2 = 1">
-		<xsl:attribute name="class">dark-row</xsl:attribute>
-		</xsl:when>
-		<xsl:otherwise>
-		<xsl:attribute name="class">light-row</xsl:attribute>
-		</xsl:otherwise>
-		</xsl:choose>
-		<td class="log-text" id="indent">
-			<xsl:choose>
-			<xsl:when test="@label">
-				<a href="{@url}"><xsl:value-of select="@label"/></a>
-				<br />
-				<div id="indent">
-				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
-				</div>
-			</xsl:when>
-			<xsl:otherwise>
-				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
-			</xsl:otherwise>
-			</xsl:choose>
-			<br /><br />
-		</td>
-		<td>
-			<table>
-				<xsl:if test="@os">
-					<tr><td class="log-text" id="indent">Operating Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@ws">
-					<tr><td class="log-text" id="indent">Windows Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@nl">
-					<tr><td class="log-text" id="indent">Languages:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@arch">
-					<tr><td class="log-text" id="indent">Architecture:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
-					</tr>
-				</xsl:if>
-			</table>
-		</td>
-	</tr>
-	</xsl:for-each>
-	</xsl:when>
-	<xsl:otherwise>
-	<xsl:for-each select="feature[not(category)]">
-	<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
-	<xsl:sort select="@version" order="ascending" />
-	<tr>
-		<xsl:choose>
-		<xsl:when test="count(preceding-sibling::feature[not(category)]) mod 2 = 1">
-		<xsl:attribute name="class">dark-row</xsl:attribute>
-		</xsl:when>
-		<xsl:otherwise>
-		<xsl:attribute name="class">light-row</xsl:attribute>
-		</xsl:otherwise>
-		</xsl:choose>
-		<td class="log-text" id="indent">
-			<xsl:choose>
-			<xsl:when test="@label">
-				<a href="{@url}"><xsl:value-of select="@label"/></a>
-				<br />
-				<div id="indent">
-				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
-				</div>
-			</xsl:when>
-			<xsl:otherwise>
-				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
-			</xsl:otherwise>
-			</xsl:choose>
-			<br /><br />
-		</td>
-		<td>
-			<table>
-				<xsl:if test="@os">
-					<tr><td class="log-text" id="indent">Operating Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@ws">
-					<tr><td class="log-text" id="indent">Windows Systems:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@nl">
-					<tr><td class="log-text" id="indent">Languages:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
-					</tr>
-				</xsl:if>
-				<xsl:if test="@arch">
-					<tr><td class="log-text" id="indent">Architecture:</td>
-					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
-					</tr>
-				</xsl:if>
-			</table>
-		</td>
-	</tr>
-	</xsl:for-each>
-	</xsl:otherwise>
-	</xsl:choose>
-	</table>
-	</body>
-	</html>
-</xsl:for-each>
-</xsl:template>
-</xsl:stylesheet>
diff --git a/tools/eventanalyzer/.classpath b/tools/eventanalyzer/.classpath
deleted file mode 100644
index b0326c8..0000000
--- a/tools/eventanalyzer/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/eventanalyzer/.project b/tools/eventanalyzer/.project
deleted file mode 100644
index 2862978..0000000
--- a/tools/eventanalyzer/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>eventanalyzer</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/eventanalyzer/Android.mk b/tools/eventanalyzer/Android.mk
deleted file mode 100644
index 18e730e..0000000
--- a/tools/eventanalyzer/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-EVENTANALUZER_LOCAL_DIR := $(call my-dir)
-include $(EVENTANALUZER_LOCAL_DIR)/etc/Android.mk
-include $(EVENTANALUZER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/eventanalyzer/etc/Android.mk b/tools/eventanalyzer/etc/Android.mk
deleted file mode 100644
index e7703b4..0000000
--- a/tools/eventanalyzer/etc/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := eventanalyzer
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/eventanalyzer/etc/eventanalyzer b/tools/eventanalyzer/etc/eventanalyzer
deleted file mode 100755
index d6c7895..0000000
--- a/tools/eventanalyzer/etc/eventanalyzer
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh
-# Copyright 2005-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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=eventanalyzer.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-
-# Check args.
-# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
-if [ `uname` = "Darwin" ]; then
-    os_opts="-XstartOnFirstThread"
-else
-    os_opts=
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx128M $os_opts -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
diff --git a/tools/eventanalyzer/etc/manifest.txt b/tools/eventanalyzer/etc/manifest.txt
deleted file mode 100644
index 6d99ea1..0000000
--- a/tools/eventanalyzer/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.eventanalyzer.EventAnalyzer
diff --git a/tools/eventanalyzer/src/Android.mk b/tools/eventanalyzer/src/Android.mk
deleted file mode 100644
index e65c61f..0000000
--- a/tools/eventanalyzer/src/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	ddmlib
-LOCAL_MODULE := eventanalyzer
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java b/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
deleted file mode 100644
index 11444ec..0000000
--- a/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * 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.android.eventanalyzer;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.ILogOutput;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.log.EventContainer;
-import com.android.ddmlib.log.EventLogParser;
-import com.android.ddmlib.log.InvalidTypeException;
-import com.android.ddmlib.log.LogReceiver;
-import com.android.ddmlib.log.LogReceiver.ILogListener;
-import com.android.ddmlib.log.LogReceiver.LogEntry;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Set;
-import java.util.TreeMap;
-
-/**
- * Connects to a device using ddmlib and analyze its event log.
- */
-public class EventAnalyzer implements ILogListener {
-
-    private final static int TAG_ACTIVITY_LAUNCH_TIME = 30009;
-    private final static char DATA_SEPARATOR = ',';
-
-    private final static String CVS_EXT = ".csv";
-    private final static String TAG_FILE_EXT = ".tag"; //$NON-NLS-1$
-
-    private EventLogParser mParser;
-    private TreeMap<String, ArrayList<Long>> mLaunchMap = new TreeMap<String, ArrayList<Long>>();
-
-    String mInputTextFile = null;
-    String mInputBinaryFile = null;
-    String mInputDevice = null;
-    String mInputFolder = null;
-    String mAlternateTagFile = null;
-    String mOutputFile = null;
-
-    public static void main(String[] args) {
-        new EventAnalyzer().run(args);
-    }
-
-    private void run(String[] args) {
-        if (args.length == 0) {
-            printUsageAndQuit();
-        }
-
-        int index = 0;
-        do {
-            String argument = args[index++];
-
-            if ("-s".equals(argument)) {
-                checkInputValidity("-s");
-
-                if (index == args.length) {
-                    printUsageAndQuit();
-                }
-
-                mInputDevice = args[index++];
-            } else if ("-fb".equals(argument)) {
-                checkInputValidity("-fb");
-
-                if (index == args.length) {
-                    printUsageAndQuit();
-                }
-
-                mInputBinaryFile = args[index++];
-            } else if ("-ft".equals(argument)) {
-                checkInputValidity("-ft");
-
-                if (index == args.length) {
-                    printUsageAndQuit();
-                }
-
-                mInputTextFile = args[index++];
-            } else if ("-F".equals(argument)) {
-                checkInputValidity("-F");
-
-                if (index == args.length) {
-                    printUsageAndQuit();
-                }
-
-                mInputFolder = args[index++];
-            } else if ("-t".equals(argument)) {
-                if (index == args.length) {
-                    printUsageAndQuit();
-                }
-
-                mAlternateTagFile = args[index++];
-            } else {
-                // get the filepath and break.
-                mOutputFile = argument;
-
-                // should not be any other device.
-                if (index < args.length) {
-                    printAndExit("Too many arguments!", false /* terminate */);
-                }
-            }
-        } while (index < args.length);
-
-        if ((mInputTextFile == null && mInputBinaryFile == null && mInputFolder == null &&
-                mInputDevice == null)) {
-            printUsageAndQuit();
-        }
-
-        File outputParent = new File(mOutputFile).getParentFile();
-        if (outputParent == null || outputParent.isDirectory() == false) {
-            printAndExit(String.format("%1$s is not a valid ouput file", mOutputFile),
-                    false /* terminate */);
-        }
-
-        // redirect the log output to /dev/null
-        Log.setLogOutput(new ILogOutput() {
-            public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
-                // pass
-            }
-
-            public void printLog(LogLevel logLevel, String tag, String message) {
-                // pass
-            }
-        });
-
-        try {
-            if (mInputBinaryFile != null) {
-                parseBinaryLogFile();
-            } else if (mInputTextFile != null) {
-                parseTextLogFile(mInputTextFile);
-            } else if (mInputFolder != null) {
-                parseFolder(mInputFolder);
-            } else if (mInputDevice != null) {
-                parseLogFromDevice();
-            }
-
-            // analyze the data gathered by the parser methods
-            analyzeData();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Parses a binary event log file located at {@link #mInputBinaryFile}.
-     * @throws IOException
-     */
-    private void parseBinaryLogFile() throws IOException {
-        mParser = new EventLogParser();
-
-        String tagFile = mInputBinaryFile + TAG_FILE_EXT;
-        if (mParser.init(tagFile) == false) {
-            // if we have an alternate location
-            if (mAlternateTagFile != null) {
-                if (mParser.init(mAlternateTagFile) == false) {
-                    printAndExit("Failed to get event tags from " + mAlternateTagFile,
-                            false /* terminate*/);
-                }
-            } else {
-                printAndExit("Failed to get event tags from " + tagFile, false /* terminate*/);
-            }
-        }
-
-        LogReceiver receiver = new LogReceiver(this);
-
-        byte[] buffer = new byte[256];
-
-        FileInputStream fis = new FileInputStream(mInputBinaryFile);
-
-        int count;
-        while ((count = fis.read(buffer)) != -1) {
-            receiver.parseNewData(buffer, 0, count);
-        }
-    }
-
-    /**
-     * Parse a text Log file.
-     * @param filePath the location of the file.
-     * @throws IOException
-     */
-    private void parseTextLogFile(String filePath) throws IOException {
-        mParser = new EventLogParser();
-
-        String tagFile = filePath + TAG_FILE_EXT;
-        if (mParser.init(tagFile) == false) {
-            // if we have an alternate location
-            if (mAlternateTagFile != null) {
-                if (mParser.init(mAlternateTagFile) == false) {
-                    printAndExit("Failed to get event tags from " + mAlternateTagFile,
-                            false /* terminate*/);
-                }
-            } else {
-                printAndExit("Failed to get event tags from " + tagFile, false /* terminate*/);
-            }
-        }
-
-        // read the lines from the file and process them.
-        BufferedReader reader = new BufferedReader(
-                new InputStreamReader(new FileInputStream(filePath)));
-
-        String line;
-        while ((line = reader.readLine()) != null) {
-            processEvent(mParser.parse(line));
-        }
-    }
-
-    private void parseLogFromDevice() throws IOException {
-        // init the lib
-        AndroidDebugBridge.init(false /* debugger support */);
-
-        try {
-            AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
-
-            // we can't just ask for the device list right away, as the internal thread getting
-            // them from ADB may not be done getting the first list.
-            // Since we don't really want getDevices() to be blocking, we wait here manually.
-            int count = 0;
-            while (bridge.hasInitialDeviceList() == false) {
-                try {
-                    Thread.sleep(100);
-                    count++;
-                } catch (InterruptedException e) {
-                    // pass
-                }
-
-                // let's not wait > 10 sec.
-                if (count > 100) {
-                    printAndExit("Timeout getting device list!", true /* terminate*/);
-                }
-            }
-
-            // now get the devices
-            IDevice[] devices = bridge.getDevices();
-
-            for (IDevice device : devices) {
-                if (device.getSerialNumber().equals(mInputDevice)) {
-                    grabLogFrom(device);
-                    return;
-                }
-            }
-
-            System.err.println("Could not find " + mInputDevice);
-        } finally {
-            AndroidDebugBridge.terminate();
-        }
-    }
-
-    /**
-     * Parses the log files located in the folder, and its sub-folders.
-     * @param folderPath the path to the folder.
-     */
-    private void parseFolder(String folderPath) {
-        File f = new File(folderPath);
-        if (f.isDirectory() == false) {
-            printAndExit(String.format("%1$s is not a valid folder", folderPath),
-                    false /* terminate */);
-        }
-
-        String[] files = f.list(new FilenameFilter() {
-            public boolean accept(File dir, String name) {
-                name = name.toLowerCase();
-                return name.endsWith(".tag") == false;
-            }
-        });
-
-        for (String file : files) {
-            try {
-                f = new File(folderPath + File.separator + file);
-                if (f.isDirectory()) {
-                    parseFolder(f.getAbsolutePath());
-                } else {
-                    parseTextLogFile(f.getAbsolutePath());
-                }
-            } catch (IOException e) {
-                // ignore this file.
-            }
-        }
-    }
-
-    private void grabLogFrom(IDevice device) throws IOException {
-        mParser = new EventLogParser();
-        if (mParser.init(device) == false) {
-            printAndExit("Failed to get event-log-tags from " + device.getSerialNumber(),
-                    true /* terminate*/);
-        }
-
-        LogReceiver receiver = new LogReceiver(this);
-
-        device.runEventLogService(receiver);
-    }
-
-    /**
-     * Analyze the data and writes it to {@link #mOutputFile}
-     * @throws IOException
-     */
-    private void analyzeData() throws IOException {
-        BufferedWriter writer = null;
-        try {
-            // make sure the file name has the proper extension.
-            if (mOutputFile.toLowerCase().endsWith(CVS_EXT) == false) {
-                mOutputFile = mOutputFile + CVS_EXT;
-            }
-
-            writer = new BufferedWriter(new FileWriter(mOutputFile));
-            StringBuilder builder = new StringBuilder();
-
-            // write the list of launch start. One column per activity.
-            Set<String> activities = mLaunchMap.keySet();
-
-            // write the column headers.
-            for (String activity : activities) {
-                builder.append(activity).append(DATA_SEPARATOR);
-            }
-            writer.write(builder.append('\n').toString());
-
-            // loop on the activities and write their values.
-            boolean moreValues = true;
-            int index = 0;
-            while (moreValues) {
-                moreValues = false;
-                builder.setLength(0);
-
-                for (String activity : activities) {
-                    // get the activity list.
-                    ArrayList<Long> list = mLaunchMap.get(activity);
-                    if (index < list.size()) {
-                        moreValues = true;
-                        builder.append(list.get(index).longValue()).append(DATA_SEPARATOR);
-                    } else {
-                        builder.append(DATA_SEPARATOR);
-                    }
-                }
-
-                // write the line.
-                if (moreValues) {
-                    writer.write(builder.append('\n').toString());
-                }
-
-                index++;
-            }
-
-            // write per-activity stats.
-            for (String activity : activities) {
-                builder.setLength(0);
-                builder.append(activity).append(DATA_SEPARATOR);
-
-                // get the activity list.
-                ArrayList<Long> list = mLaunchMap.get(activity);
-
-                // sort the list
-                Collections.sort(list);
-
-                // write min/max
-                builder.append(list.get(0).longValue()).append(DATA_SEPARATOR);
-                builder.append(list.get(list.size()-1).longValue()).append(DATA_SEPARATOR);
-
-                // write median value
-                builder.append(list.get(list.size()/2).longValue()).append(DATA_SEPARATOR);
-
-                // compute and write average
-                long total = 0; // despite being encoded on a long, the values are low enough that
-                                // a Long should be enough to compute the total
-                for (Long value : list) {
-                    total += value.longValue();
-                }
-                builder.append(total / list.size()).append(DATA_SEPARATOR);
-
-                // finally write the data.
-                writer.write(builder.append('\n').toString());
-            }
-        } finally {
-            writer.close();
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.log.LogReceiver.ILogListener#newData(byte[], int, int)
-     */
-    public void newData(byte[] data, int offset, int length) {
-        // we ignore raw data. New entries are processed in #newEntry(LogEntry)
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.ddmlib.log.LogReceiver.ILogListener#newEntry(com.android.ddmlib.log.LogReceiver.LogEntry)
-     */
-    public void newEntry(LogEntry entry) {
-        // parse and process the entry data.
-        processEvent(mParser.parse(entry));
-    }
-
-    private void processEvent(EventContainer event) {
-        if (event != null && event.mTag == TAG_ACTIVITY_LAUNCH_TIME) {
-            // get the activity name
-            try {
-                String name = event.getValueAsString(0);
-
-                // get the launch time
-                Object value = event.getValue(1);
-                if (value instanceof Long) {
-                    addLaunchTime(name, (Long)value);
-                }
-
-            } catch (InvalidTypeException e) {
-                // Couldn't get the name as a string...
-                // Ignore this event.
-            }
-        }
-    }
-
-    private void addLaunchTime(String name, Long value) {
-        ArrayList<Long> list = mLaunchMap.get(name);
-
-        if (list == null) {
-            list = new ArrayList<Long>();
-            mLaunchMap.put(name, list);
-        }
-
-        list.add(value);
-    }
-
-    private void checkInputValidity(String option) {
-        if (mInputTextFile != null || mInputBinaryFile != null) {
-            printAndExit(String.format("ERROR: %1$s cannot be used with an input file.", option),
-                    false /* terminate */);
-        } else if (mInputFolder != null) {
-            printAndExit(String.format("ERROR: %1$s cannot be used with an input file.", option),
-                    false /* terminate */);
-        } else if (mInputDevice != null) {
-            printAndExit(String.format("ERROR: %1$s cannot be used with an input device serial number.",
-                    option), false /* terminate */);
-        }
-    }
-
-    private static void printUsageAndQuit() {
-        // 80 cols marker:  01234567890123456789012345678901234567890123456789012345678901234567890123456789
-        System.out.println("Usage:");
-        System.out.println("   eventanalyzer [-t <TAG_FILE>] <SOURCE> <OUTPUT>");
-        System.out.println("");
-        System.out.println("Possible sources:");
-        System.out.println("   -fb <file>    The path to a binary event log, gathered by dumpeventlog");
-        System.out.println("   -ft <file>    The path to a text event log, gathered by adb logcat -b events");
-        System.out.println("   -F <folder>   The path to a folder containing multiple text log files.");
-        System.out.println("   -s <serial>   The serial number of the Device to grab the event log from.");
-        System.out.println("Options:");
-        System.out.println("   -t <file>     The path to tag file to use in case the one associated with");
-        System.out.println("                 the source is missing");
-
-        System.exit(1);
-    }
-
-
-    private static void printAndExit(String message, boolean terminate) {
-        System.out.println(message);
-        if (terminate) {
-            AndroidDebugBridge.terminate();
-        }
-        System.exit(1);
-    }
-}
diff --git a/tools/hierarchyviewer/Android.mk b/tools/hierarchyviewer/Android.mk
deleted file mode 100644
index 110e2ed..0000000
--- a/tools/hierarchyviewer/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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.
-
-HIERARCHYVIEWER_LOCAL_DIR := $(call my-dir)
-include $(HIERARCHYVIEWER_LOCAL_DIR)/etc/Android.mk
-include $(HIERARCHYVIEWER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/hierarchyviewer/MODULE_LICENSE_APACHE2 b/tools/hierarchyviewer/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/hierarchyviewer/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/hierarchyviewer/etc/Android.mk b/tools/hierarchyviewer/etc/Android.mk
deleted file mode 100644
index 2794a7f..0000000
--- a/tools/hierarchyviewer/etc/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := hierarchyviewer
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/hierarchyviewer/etc/hierarchyviewer b/tools/hierarchyviewer/etc/hierarchyviewer
deleted file mode 100755
index 4244434..0000000
--- a/tools/hierarchyviewer/etc/hierarchyviewer
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-# Copyright 2008, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=hierarchyviewer.jar
-frameworkdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx512M -Djava.ext.dirs="$frameworkdir" -Dhierarchyviewer.adb="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/hierarchyviewer/etc/hierarchyviewer.bat b/tools/hierarchyviewer/etc/hierarchyviewer.bat
deleted file mode 100755
index 2024a79..0000000
--- a/tools/hierarchyviewer/etc/hierarchyviewer.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-@echo off
-rem Copyright (C) 2008 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-set jarfile=hierarchyviewer.jar
-set frameworkdir=
-set libdir=
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=lib\
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=..\framework\
-
-:JarFileOk
-
-set jarpath=%frameworkdir%%jarfile%
-
-call java -Xmx512m -Djava.ext.dirs=%frameworkdir% -Dhierarchyviewer.adb= -jar %jarpath% %*
diff --git a/tools/hierarchyviewer/etc/manifest.txt b/tools/hierarchyviewer/etc/manifest.txt
deleted file mode 100644
index f7ddfa9..0000000
--- a/tools/hierarchyviewer/etc/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Main-Class: com.android.hierarchyviewer.HierarchyViewer
-Class-Path: ddmlib.jar swing-worker-1.1.jar org-openide-util.jar org-netbeans-api-visual.jar
diff --git a/tools/hierarchyviewer/src/Android.mk b/tools/hierarchyviewer/src/Android.mk
deleted file mode 100644
index 0bc1f1e..0000000
--- a/tools/hierarchyviewer/src/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	ddmlib \
-	swing-worker-1.1 \
-	org-openide-util \
-	org-netbeans-api-visual
-LOCAL_MODULE := hierarchyviewer
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/HierarchyViewer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/HierarchyViewer.java
deleted file mode 100644
index 59ce67f..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/HierarchyViewer.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.android.hierarchyviewer;
-
-import com.android.hierarchyviewer.ui.Workspace;
-import com.android.hierarchyviewer.device.DeviceBridge;
-
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-
-public class HierarchyViewer {
-    private static final CharSequence OS_WINDOWS = "Windows";
-    private static final CharSequence OS_MACOSX = "Mac OS X";
-
-    private static void initUserInterface() {
-        System.setProperty("apple.laf.useScreenMenuBar", "true");
-        System.setProperty("apple.awt.brushMetalLook", "true");
-        System.setProperty("com.apple.mrj.application.apple.menu.about.name", "HierarchyViewer");
-
-        final String os = System.getProperty("os.name");
-
-        try {
-            if (os.contains(OS_WINDOWS) || os.contains(OS_MACOSX)) {
-                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-            } else {
-                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());                
-            }
-        } catch (ClassNotFoundException e) {
-            e.printStackTrace();
-        } catch (InstantiationException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (UnsupportedLookAndFeelException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public static void main(String[] args) {
-        initUserInterface();
-        DeviceBridge.initDebugBridge();
-
-        SwingUtilities.invokeLater(new Runnable() {
-            public void run() {
-                Workspace workspace = new Workspace();
-                workspace.setDefaultCloseOperation(Workspace.EXIT_ON_CLOSE);
-                workspace.setLocationRelativeTo(null);
-                workspace.setVisible(true);
-            }
-        });
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Configuration.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Configuration.java
deleted file mode 100644
index 090730f..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Configuration.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.android.hierarchyviewer.device;
-
-public class Configuration {
-    public static final int DEFAULT_SERVER_PORT = 4939;
-
-    // These codes must match the auto-generated codes in IWindowManager.java
-    // See IWindowManager.aidl as well
-    public static final int SERVICE_CODE_START_SERVER = 1;
-    public static final int SERVICE_CODE_STOP_SERVER = 2;
-    public static final int SERVICE_CODE_IS_SERVER_RUNNING = 3;
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
deleted file mode 100644
index 0f60be6..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.android.hierarchyviewer.device;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-
-import java.io.IOException;
-import java.io.File;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class DeviceBridge {
-    private static AndroidDebugBridge bridge;
-
-    private static final HashMap<IDevice, Integer> devicePortMap = new HashMap<IDevice, Integer>();
-    private static int nextLocalPort = Configuration.DEFAULT_SERVER_PORT;
-
-    public static void initDebugBridge() {
-        if (bridge == null) {
-            AndroidDebugBridge.init(false /* debugger support */);
-        }
-        if (bridge == null || !bridge.isConnected()) {
-            String adbLocation = System.getProperty("hierarchyviewer.adb");
-            if (adbLocation != null && adbLocation.length() != 0) {
-                adbLocation += File.separator + "adb";
-            } else {
-                adbLocation = "adb";
-            }
-
-            bridge = AndroidDebugBridge.createBridge(adbLocation, true);
-        }
-    }
-
-    public static void startListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
-        AndroidDebugBridge.addDeviceChangeListener(listener);
-    }
-
-    public static void stopListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
-        AndroidDebugBridge.removeDeviceChangeListener(listener);
-    }
-
-    public static IDevice[] getDevices() {
-        return bridge.getDevices();
-    }
-
-    public static boolean isViewServerRunning(IDevice device) {
-        initDebugBridge();
-        final boolean[] result = new boolean[1];
-        try {
-            if (device.isOnline()) {
-                device.executeShellCommand(buildIsServerRunningShellCommand(),
-                        new BooleanResultReader(result));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return result[0];
-    }
-
-    public static boolean startViewServer(IDevice device) {
-        return startViewServer(device, Configuration.DEFAULT_SERVER_PORT);
-    }
-
-    public static boolean startViewServer(IDevice device, int port) {
-        initDebugBridge();
-        final boolean[] result = new boolean[1];
-        try {
-            if (device.isOnline()) {
-                device.executeShellCommand(buildStartServerShellCommand(port),
-                        new BooleanResultReader(result));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return result[0];
-    }
-
-    public static boolean stopViewServer(IDevice device) {
-        initDebugBridge();
-        final boolean[] result = new boolean[1];
-        try {
-            if (device.isOnline()) {
-                device.executeShellCommand(buildStopServerShellCommand(),
-                        new BooleanResultReader(result));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return result[0];
-    }
-
-    public static void terminate() {
-        AndroidDebugBridge.terminate();
-    }
-
-    /**
-     * Sets up a just-connected device to work with the view server.
-     * <p/>This starts a port forwarding between a local port and a port on the device.
-     * @param device
-     */
-    public static void setupDeviceForward(IDevice device) {
-        synchronized (devicePortMap) {
-            if (device.getState() == IDevice.DeviceState.ONLINE) {
-                int localPort = nextLocalPort++;
-                device.createForward(localPort, Configuration.DEFAULT_SERVER_PORT);
-                devicePortMap.put(device, localPort);
-            }
-        }
-    }
-
-    public static void removeDeviceForward(IDevice device) {
-        synchronized (devicePortMap) {
-            final Integer localPort = devicePortMap.get(device);
-            if (localPort != null) {
-                device.removeForward(localPort, Configuration.DEFAULT_SERVER_PORT);
-                devicePortMap.remove(device);
-            }
-        }
-    }
-
-    public static int getDeviceLocalPort(IDevice device) {
-        synchronized (devicePortMap) {
-            Integer port = devicePortMap.get(device);
-            if (port != null) {
-                return port;
-            }
-
-            Log.e("hierarchy", "Missing forwarded port for " + device.getSerialNumber());
-            return -1;
-        }
-
-    }
-
-    private static String buildStartServerShellCommand(int port) {
-        return String.format("service call window %d i32 %d",
-                Configuration.SERVICE_CODE_START_SERVER, port);
-    }
-
-    private static String buildStopServerShellCommand() {
-        return String.format("service call window %d", Configuration.SERVICE_CODE_STOP_SERVER);
-    }
-
-    private static String buildIsServerRunningShellCommand() {
-        return String.format("service call window %d",
-                Configuration.SERVICE_CODE_IS_SERVER_RUNNING);
-    }
-
-    private static class BooleanResultReader extends MultiLineReceiver {
-        private final boolean[] mResult;
-
-        public BooleanResultReader(boolean[] result) {
-            mResult = result;
-        }
-
-        @Override
-        public void processNewLines(String[] strings) {
-            if (strings.length > 0) {
-                Pattern pattern = Pattern.compile(".*?\\([0-9]{8} ([0-9]{8}).*");
-                Matcher matcher = pattern.matcher(strings[0]);
-                if (matcher.matches()) {
-                    if (Integer.parseInt(matcher.group(1)) == 1) {
-                        mResult[0] = true;
-                    }
-                }
-            }
-        }
-
-        public boolean isCancelled() {
-            return false;
-        }
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java
deleted file mode 100644
index 0417df6..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.android.hierarchyviewer.device;
-
-public class Window {
-    public static final Window FOCUSED_WINDOW = new Window("<Focused Window>", -1);
-
-    private String title;
-    private int hashCode;
-
-    public Window(String title, int hashCode) {
-        this.title = title;
-        this.hashCode = hashCode;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public int getHashCode() {
-        return hashCode;
-    }
-
-    public String encode() {
-        return Integer.toHexString(hashCode);
-    }
-
-    public String toString() {
-        return title;
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java
deleted file mode 100644
index 401fb3e..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.android.hierarchyviewer.laf;
-
-import javax.swing.border.AbstractBorder;
-import java.awt.*;
-
-public class UnifiedContentBorder extends AbstractBorder {
-    private static final Color BORDER_TOP_COLOR1 = new Color(0x575757);
-    private static final Color BORDER_BOTTOM_COLOR1 = new Color(0x404040);
-    private static final Color BORDER_BOTTOM_COLOR2 = new Color(0xd8d8d8);
-
-    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
-        g.setColor(BORDER_TOP_COLOR1);
-        g.drawLine(x, y, x + width, y);
-        g.setColor(BORDER_BOTTOM_COLOR1);
-        g.drawLine(x, y + height - 2, x + width, y + height - 2);
-        g.setColor(BORDER_BOTTOM_COLOR2);
-        g.drawLine(x, y + height - 1, x + width, y + height - 1);
-    }
-
-    public Insets getBorderInsets(Component component) {
-        return new Insets(1, 0, 2, 0);
-    }
-
-    public boolean isBorderOpaque() {
-        return true;
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java
deleted file mode 100644
index c512ac2..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.android.hierarchyviewer.scene;
-
-import com.android.ddmlib.IDevice;
-import com.android.hierarchyviewer.device.Configuration;
-import com.android.hierarchyviewer.device.Window;
-import com.android.hierarchyviewer.device.DeviceBridge;
-
-import java.awt.Image;
-import java.io.BufferedInputStream;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import javax.imageio.ImageIO;
-
-public class CaptureLoader {
-    public static Image loadCapture(IDevice device, Window window, String params) {
-        Socket socket = null;
-        BufferedInputStream in = null;
-        BufferedWriter out = null;
-
-        try {
-            socket = new Socket();
-            socket.connect(new InetSocketAddress("127.0.0.1",
-                    DeviceBridge.getDeviceLocalPort(device)));
-
-            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-            in = new BufferedInputStream(socket.getInputStream());
-
-            out.write("CAPTURE " + window.encode() + " " + params);
-            out.newLine();
-            out.flush();
-
-            return ImageIO.read(in);
-        } catch (IOException e) {
-            // Empty
-        } finally {
-            try {
-                if (out != null) {
-                    out.close();
-                }
-                if (in != null) {
-                    in.close();
-                }
-                if (socket != null) {
-                    socket.close();
-                }
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ProfilesLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ProfilesLoader.java
deleted file mode 100644
index b91db79..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ProfilesLoader.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.hierarchyviewer.scene;
-
-import com.android.ddmlib.IDevice;
-import com.android.hierarchyviewer.device.Window;
-import com.android.hierarchyviewer.device.DeviceBridge;
-
-import java.net.Socket;
-import java.net.InetSocketAddress;
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-public class ProfilesLoader {
-    public static double[] loadProfiles(IDevice device, Window window, String params) {
-        Socket socket = null;
-        BufferedReader in = null;
-        BufferedWriter out = null;
-
-        try {
-            socket = new Socket();
-            socket.connect(new InetSocketAddress("127.0.0.1",
-                    DeviceBridge.getDeviceLocalPort(device)));
-
-            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
-            out.write("PROFILE " + window.encode() + " " + params);
-            out.newLine();
-            out.flush();
-
-            String response = in.readLine();
-            String[] data = response.split(" ");
-
-            double[] profiles = new double[data.length];
-            for (int i = 0; i < data.length; i++) {
-                profiles[i] = (Long.parseLong(data[i]) / 1000.0) / 1000.0; // convert to ms
-            }
-            return profiles;
-        } catch (IOException e) {
-            // Empty
-        } finally {
-            try {
-                if (out != null) {
-                    out.close();
-                }
-                if (in != null) {
-                    in.close();
-                }
-                if (socket != null) {
-                    socket.close();
-                }
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java
deleted file mode 100644
index 6254262..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.android.hierarchyviewer.scene;
-
-import com.android.ddmlib.IDevice;
-import com.android.hierarchyviewer.device.DeviceBridge;
-import com.android.hierarchyviewer.device.Window;
-
-import org.openide.util.Exceptions;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Stack;
-import java.util.regex.Pattern;
-
-public class ViewHierarchyLoader {
-    @SuppressWarnings("empty-statement")
-    public static ViewHierarchyScene loadScene(IDevice device, Window window) {
-        ViewHierarchyScene scene = new ViewHierarchyScene();
-
-        // Read the views tree
-        Socket socket = null;
-        BufferedReader in = null;
-        BufferedWriter out = null;
-
-        String line;
-
-        try {
-            System.out.println("==> Starting client");
-
-            socket = new Socket();
-            socket.connect(new InetSocketAddress("127.0.0.1",
-                    DeviceBridge.getDeviceLocalPort(device)));
-
-            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
-            System.out.println("==> DUMP");
-
-            out.write("DUMP " + window.encode());
-            out.newLine();
-            out.flush();
-
-            Stack<ViewNode> stack = new Stack<ViewNode>();
-
-            boolean setRoot = true;
-            ViewNode lastNode = null;
-            int lastWhitespaceCount = Integer.MAX_VALUE;
-
-            while ((line = in.readLine()) != null) {
-                if ("DONE.".equalsIgnoreCase(line)) {
-                    break;
-                }
-
-                int whitespaceCount = countFrontWhitespace(line);
-                if (lastWhitespaceCount < whitespaceCount) {
-                    stack.push(lastNode);
-                } else if (!stack.isEmpty()) {
-                    final int count = lastWhitespaceCount - whitespaceCount;
-                    for (int i = 0; i < count; i++) {
-                        stack.pop();
-                    }
-                }
-
-                lastWhitespaceCount = whitespaceCount;
-                line = line.trim();
-                int index = line.indexOf(' ');
-
-                lastNode = new ViewNode();
-                lastNode.name = line.substring(0, index);
-
-                line = line.substring(index + 1);
-                loadProperties(lastNode, line);
-
-                scene.addNode(lastNode);
-
-                if (setRoot) {
-                    scene.setRoot(lastNode);
-                    setRoot = false;
-                }
-
-                if (!stack.isEmpty()) {
-                    final ViewNode parent = stack.peek();
-                    final String edge = parent.name + lastNode.name;
-                    scene.addEdge(edge);
-                    scene.setEdgeSource(edge, parent);
-                    scene.setEdgeTarget(edge, lastNode);
-                    lastNode.parent = parent;
-                    parent.children.add(lastNode);
-                }
-            }
-
-            updateIndices(scene.getRoot());
-
-        } catch (IOException ex) {
-            Exceptions.printStackTrace(ex);
-        } finally {
-            try {
-                if (out != null) {
-                    out.close();
-                }
-                if (in != null) {
-                    in.close();
-                }
-                socket.close();
-            } catch (IOException ex) {
-                Exceptions.printStackTrace(ex);
-            }
-        }
-
-        System.out.println("==> DONE");
-
-        return scene;
-    }
-
-    private static void updateIndices(ViewNode root) {
-        if (root == null) return;
-
-        root.computeIndex();
-
-        for (ViewNode node : root.children) {
-            updateIndices(node);
-        }
-    }
-
-    private static int countFrontWhitespace(String line) {
-        int count = 0;
-        while (line.charAt(count) == ' ') {
-            count++;
-        }
-        return count;
-    }
-
-    private static void loadProperties(ViewNode node, String data) {
-        int start = 0;
-        boolean stop;
-
-        do {
-            int index = data.indexOf('=', start);
-            ViewNode.Property property = new ViewNode.Property();
-            property.name = data.substring(start, index);
-
-            int index2 = data.indexOf(',', index + 1);
-            int length = Integer.parseInt(data.substring(index + 1, index2));
-            start = index2 + 1 + length;
-            property.value = data.substring(index2 + 1, index2 + 1 + length);
-
-            node.properties.add(property);
-            node.namedProperties.put(property.name, property);
-
-            stop = start >= data.length();
-            if (!stop) {
-                start += 1;
-            }
-        } while (!stop);
-
-        Collections.sort(node.properties, new Comparator<ViewNode.Property>() {
-            public int compare(ViewNode.Property source, ViewNode.Property destination) {
-                return source.name.compareTo(destination.name);
-            }
-        });
-
-        node.decode();
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java
deleted file mode 100644
index 08dc395..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * 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.android.hierarchyviewer.scene;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.GradientPaint;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.geom.Point2D;
-
-import org.netbeans.api.visual.action.ActionFactory;
-import org.netbeans.api.visual.action.WidgetAction;
-import org.netbeans.api.visual.anchor.AnchorFactory;
-import org.netbeans.api.visual.border.BorderFactory;
-import org.netbeans.api.visual.graph.GraphScene;
-import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.netbeans.api.visual.widget.LabelWidget;
-import org.netbeans.api.visual.widget.LayerWidget;
-import org.netbeans.api.visual.widget.Widget;
-
-public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
-    private ViewNode root;
-    private LayerWidget widgetLayer;
-    private LayerWidget connectionLayer;
-
-    private WidgetAction moveAction = ActionFactory.createMoveAction();
-
-    public ViewHierarchyScene() {
-        widgetLayer = new LayerWidget(this);
-        connectionLayer = new LayerWidget(this);
-
-        addChild(widgetLayer);
-        addChild(connectionLayer);
-    }
-    
-    public ViewNode getRoot() {
-        return root;
-    }
-    
-    void setRoot(ViewNode root) {
-        this.root = root;
-    }
-
-    @Override
-    protected Widget attachNodeWidget(ViewNode node) {
-        Widget widget = createBox(node, node.name, node.id);
-        widget.getActions().addAction(createSelectAction());
-        widget.getActions().addAction(moveAction);
-        widgetLayer.addChild(widget);
-        return widget;
-    }
-
-    private Widget createBox(ViewNode node, String nodeName, String id) {
-        final String shortName = getShortName(nodeName);
-        node.setShortName(shortName);
-
-        GradientWidget box = new GradientWidget(this, node);
-        box.setLayout(LayoutFactory.createVerticalFlowLayout());
-        box.setBorder(BorderFactory.createLineBorder(2, Color.BLACK));
-        box.setOpaque(true);
-
-        LabelWidget label = new LabelWidget(this);
-        label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 12.0f));
-        label.setLabel(shortName);
-        label.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6));
-        label.setAlignment(LabelWidget.Alignment.CENTER);
-
-        box.addChild(label);
-        
-        label = new LabelWidget(this);
-        label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
-        label.setLabel(getAddress(nodeName));
-        label.setBorder(BorderFactory.createEmptyBorder(3, 6, 0, 6));
-        label.setAlignment(LabelWidget.Alignment.CENTER);
-
-        box.addressWidget = label;
-        
-        box.addChild(label);
-        
-        label = new LabelWidget(this);
-        label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
-        label.setLabel(id);
-        label.setBorder(BorderFactory.createEmptyBorder(3, 6, 6, 6));
-        label.setAlignment(LabelWidget.Alignment.CENTER);
-        
-        box.addChild(label);
-
-        return box;
-    }
-    
-    private static String getAddress(String name) {
-        String[] nameAndHashcode = name.split("@");
-        return "@" + nameAndHashcode[1];
-    }
-    
-    private static String getShortName(String name) {
-        String[] nameAndHashcode = name.split("@");
-        String[] packages = nameAndHashcode[0].split("\\.");
-        return packages[packages.length - 1];
-    }
-
-    @Override
-    protected Widget attachEdgeWidget(String edge) {
-        ConnectionWidget connectionWidget = new ConnectionWidget(this);
-        connectionLayer.addChild(connectionWidget);
-        return connectionWidget;
-    }
-
-    @Override
-    protected void attachEdgeSourceAnchor(String edge, ViewNode oldSourceNode, ViewNode sourceNode) {
-        final ConnectionWidget connection = (ConnectionWidget) findWidget(edge);
-        final Widget source = findWidget(sourceNode);
-        connection.bringToBack();
-        source.bringToFront();
-        connection.setSourceAnchor(AnchorFactory.createRectangularAnchor(source));
-    }
-
-    @Override
-    protected void attachEdgeTargetAnchor(String edge, ViewNode oldTargetNode, ViewNode targetNode) {
-        final ConnectionWidget connection = (ConnectionWidget) findWidget(edge);
-        final Widget target = findWidget(targetNode);
-        connection.bringToBack();
-        target.bringToFront();
-        connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
-    }
-    
-    private static class GradientWidget extends Widget implements ViewNode.StateListener {
-        public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(168, 204, 241),
-                new Point2D.Double(0, 1),
-                new Color(44, 61, 146));
-        public static final GradientPaint MAC_OSX_SELECTED = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(81, 141, 236),
-                new Point2D.Double(0, 1),
-                new Color(36, 96, 192));
-        public static final GradientPaint MAC_OSX = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(167, 210, 250),
-                new Point2D.Double(0, 1),
-                new Color(99, 147, 206));
-        public static final GradientPaint AERITH = new GradientPaint(
-                new Point2D.Double(0, 0),
-                Color.WHITE,
-                new Point2D.Double(0, 1),
-                new Color(64, 110, 161));
-        public static final GradientPaint GRAY = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(226, 226, 226),
-                new Point2D.Double(0, 1),
-                new Color(250, 248, 248));
-        public static final GradientPaint RED_XP = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(236, 81, 81),
-                new Point2D.Double(0, 1),
-                new Color(192, 36, 36));
-        public static final GradientPaint NIGHT_GRAY = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(102, 111, 127),
-                new Point2D.Double(0, 1),
-                new Color(38, 45, 61));
-        public static final GradientPaint NIGHT_GRAY_LIGHT = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(129, 138, 155),
-                new Point2D.Double(0, 1),
-                new Color(58, 66, 82));
-        public static final GradientPaint NIGHT_GRAY_VERY_LIGHT = new GradientPaint(
-                new Point2D.Double(0, 0),
-                new Color(129, 138, 155, 60),
-                new Point2D.Double(0, 1),
-                new Color(58, 66, 82, 60));
-
-        private static Color UNSELECTED = Color.BLACK;
-        private static Color SELECTED = Color.WHITE;
-
-        private final ViewNode node;
-
-        private LabelWidget addressWidget;
-
-        private boolean isSelected = false;
-        private final GradientPaint selectedGradient = MAC_OSX_SELECTED;
-        private final GradientPaint filteredGradient = RED_XP;
-        private final GradientPaint focusGradient = NIGHT_GRAY_VERY_LIGHT;
-
-        public GradientWidget(ViewHierarchyScene scene, ViewNode node) {
-            super(scene);
-            this.node = node;
-            node.setStateListener(this);
-        }
-
-        @Override
-        protected void notifyStateChanged(ObjectState previous, ObjectState state) {
-            super.notifyStateChanged(previous, state);
-            isSelected = state.isSelected() || state.isFocused() || state.isWidgetFocused();
-
-            pickChildrenColor();
-        }
-
-        private void pickChildrenColor() {
-            for (Widget child : getChildren()) {
-                child.setForeground(isSelected || node.filtered ? SELECTED : UNSELECTED);
-            }
-
-            repaint();
-        }
-
-        @Override
-        protected void paintBackground() {
-            super.paintBackground();
-
-            Graphics2D g2 = getGraphics();
-            Rectangle bounds = getBounds();
-
-            if (!isSelected) {
-                if (!node.filtered) {
-                    if (!node.hasFocus) {
-                        g2.setColor(Color.WHITE);
-                    } else {
-                        g2.setPaint(new GradientPaint(bounds.x, bounds.y,
-                                focusGradient.getColor1(), bounds.x, bounds.x + bounds.height,
-                                focusGradient.getColor2()));
-                    }
-                } else {
-                    g2.setPaint(new GradientPaint(bounds.x, bounds.y, filteredGradient.getColor1(),
-                        bounds.x, bounds.x + bounds.height, filteredGradient.getColor2()));
-                }
-            } else {
-                g2.setPaint(new GradientPaint(bounds.x, bounds.y, selectedGradient.getColor1(),
-                        bounds.x, bounds.x + bounds.height, selectedGradient.getColor2()));
-            }
-            g2.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
-        }
-
-        public void nodeStateChanged(ViewNode node) {
-            pickChildrenColor();
-        }
-
-        public void nodeIndexChanged(ViewNode node) {
-            if (addressWidget != null) {
-                addressWidget.setLabel("#" + node.index + addressWidget.getLabel());
-            }
-        }
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java
deleted file mode 100644
index df2a63e..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.android.hierarchyviewer.scene;
-
-import com.android.ddmlib.IDevice;
-import com.android.hierarchyviewer.device.Window;
-import com.android.hierarchyviewer.device.DeviceBridge;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-
-public class ViewManager {
-    public static void invalidate(IDevice device, Window window, String params) {
-        sendCommand("INVALIDATE", device, window, params);
-    }
-
-    public static void requestLayout(IDevice device, Window window, String params) {
-        sendCommand("REQUEST_LAYOUT", device, window, params);
-    }
-
-    private static void sendCommand(String command, IDevice device, Window window, String params) {
-        Socket socket = null;
-        BufferedWriter out = null;
-
-        try {
-            socket = new Socket();
-            socket.connect(new InetSocketAddress("127.0.0.1",
-                    DeviceBridge.getDeviceLocalPort(device)));
-
-            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-
-            out.write(command + " " + window.encode() + " " + params);
-            out.newLine();
-            out.flush();
-        } catch (IOException e) {
-            // Empty
-        } finally {
-            try {
-                if (out != null) {
-                    out.close();
-                }
-                if (socket != null) {
-                    socket.close();
-                }
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-        }
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java
deleted file mode 100644
index 64c0703..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.android.hierarchyviewer.scene;
-
-import java.awt.Image;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-public class ViewNode {
-    public String id;
-    public String name;
-
-    public List<Property> properties = new ArrayList<Property>();
-    public Map<String, Property> namedProperties = new HashMap<String, Property>();
-
-    public ViewNode parent;
-    public List<ViewNode> children = new ArrayList<ViewNode>();
-
-    public Image image;
-    
-    public int left;
-    public int top;
-    public int width;
-    public int height;
-    public int scrollX;
-    public int scrollY;
-    public int paddingLeft;
-    public int paddingRight;
-    public int paddingTop;
-    public int paddingBottom;
-    public int marginLeft;
-    public int marginRight;
-    public int marginTop;
-    public int marginBottom;
-    public int baseline;
-    public boolean willNotDraw;
-    public boolean hasMargins;
-    
-    boolean hasFocus;
-    int index;
-
-    public boolean decoded;
-    public boolean filtered;
-
-    private String shortName;
-    private StateListener listener;
-
-    void decode() {
-        id = namedProperties.get("mID").value;
-
-        left = getInt("mLeft", 0);
-        top = getInt("mTop", 0);
-        width = getInt("getWidth()", 0);
-        height = getInt("getHeight()", 0);
-        scrollX = getInt("mScrollX", 0);
-        scrollY = getInt("mScrollY", 0);
-        paddingLeft = getInt("mPaddingLeft", 0);
-        paddingRight = getInt("mPaddingRight", 0);
-        paddingTop = getInt("mPaddingTop", 0);
-        paddingBottom = getInt("mPaddingBottom", 0);
-        marginLeft = getInt("layout_leftMargin", Integer.MIN_VALUE);
-        marginRight = getInt("layout_rightMargin", Integer.MIN_VALUE);
-        marginTop = getInt("layout_topMargin", Integer.MIN_VALUE);
-        marginBottom = getInt("layout_bottomMargin", Integer.MIN_VALUE);
-        baseline = getInt("getBaseline()", 0);
-        willNotDraw = getBoolean("willNotDraw()", false);
-        hasFocus = getBoolean("hasFocus()", false);
-
-        hasMargins = marginLeft != Integer.MIN_VALUE &&
-                marginRight != Integer.MIN_VALUE &&
-                marginTop != Integer.MIN_VALUE &&
-                marginBottom != Integer.MIN_VALUE;
-
-        decoded = true;
-    }
-
-    private boolean getBoolean(String name, boolean defaultValue) {
-        Property p = namedProperties.get(name);
-        if (p != null) {
-            try {
-                return Boolean.parseBoolean(p.value);
-            } catch (NumberFormatException e) {
-                return defaultValue;
-            }   
-        }
-        return defaultValue;
-    }
-
-    private int getInt(String name, int defaultValue) {
-        Property p = namedProperties.get(name);
-        if (p != null) {
-            try {
-                return Integer.parseInt(p.value);
-            } catch (NumberFormatException e) {
-                return defaultValue;
-            }
-        }
-        return defaultValue;
-    }
-
-    public void filter(Pattern pattern) {
-        if (pattern == null || pattern.pattern().length() == 0) {
-            filtered = false;
-        } else {
-            filtered = pattern.matcher(shortName).find() || pattern.matcher(id).find();
-        }
-        listener.nodeStateChanged(this);
-    }
-
-    void computeIndex() {
-        index = parent == null ? 0 : parent.children.indexOf(this);
-        listener.nodeIndexChanged(this);
-    }
-
-    void setShortName(String shortName) {
-        this.shortName = shortName;
-    }
-
-    void setStateListener(StateListener listener) {
-        this.listener = listener;
-    }
-
-    @SuppressWarnings({"StringEquality"})
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final ViewNode other = (ViewNode) obj;
-        return !(this.name != other.name && (this.name == null || !this.name.equals(other.name)));
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 5;
-        hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
-        return hash;
-    }
-
-    public static class Property {
-        public String name;
-        public String value;
-
-        @Override
-        public String toString() {
-            return name + '=' + value;
-        }
-        
-        @SuppressWarnings({"StringEquality"})
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            final Property other = (Property) obj;
-            if (this.name != other.name && (this.name == null || !this.name.equals(other.name))) {
-                return false;
-            }
-            return !(this.value != other.value && (this.value == null || !this.value.equals(other.value)));
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 5;
-            hash = 61 * hash + (this.name != null ? this.name.hashCode() : 0);
-            hash = 61 * hash + (this.value != null ? this.value.hashCode() : 0);
-            return hash;
-        }
-    }
-
-    interface StateListener {
-        void nodeStateChanged(ViewNode node);
-        void nodeIndexChanged(ViewNode node);
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java
deleted file mode 100644
index ef93707..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.android.hierarchyviewer.scene;
-
-import com.android.ddmlib.IDevice;
-import com.android.hierarchyviewer.device.DeviceBridge;
-import com.android.hierarchyviewer.device.Window;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-
-public class WindowsLoader {
-    public static Window[] loadWindows(IDevice device) {
-        Socket socket = null;
-        BufferedReader in = null;
-        BufferedWriter out = null;
-
-        try {
-            ArrayList<Window> windows = new ArrayList<Window>();
-
-            socket = new Socket();
-            socket.connect(new InetSocketAddress("127.0.0.1",
-                    DeviceBridge.getDeviceLocalPort(device)));
-
-            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
-            out.write("LIST");
-            out.newLine();
-            out.flush();
-
-            String line;
-            while ((line = in.readLine()) != null) {
-                if ("DONE.".equalsIgnoreCase(line)) {
-                    break;
-                }
-
-                int index = line.indexOf(' ');
-                if (index != -1) {
-                    Window w = new Window(line.substring(index + 1),
-                            Integer.parseInt(line.substring(0, index), 16));
-                    windows.add(w);
-                }
-            }
-
-            return windows.toArray(new Window[windows.size()]);
-        } catch (IOException e) {
-            // Empty
-        } finally {
-            try {
-                if (out != null) {
-                    out.close();
-                }
-                if (in != null) {
-                    in.close();
-                }
-                if (socket != null) {
-                    socket.close();
-                }
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-        }
-
-        return new Window[0];
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/CaptureRenderer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/CaptureRenderer.java
deleted file mode 100644
index 7ccc818..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/CaptureRenderer.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui;
-
-import com.android.hierarchyviewer.scene.ViewNode;
-
-import javax.swing.*;
-import java.awt.*;
-
-class CaptureRenderer extends JLabel {
-    private ViewNode node;
-    private boolean showExtras;
-
-    CaptureRenderer(ImageIcon icon, ViewNode node) {
-        super(icon);
-        this.node = node;
-        setBackground(Color.BLACK);
-    }
-
-    @Override
-    public Dimension getPreferredSize() {
-        Dimension d = super.getPreferredSize();
-
-        if (node.hasMargins) {
-            d.width += node.marginLeft + node.marginRight;
-            d.height += node.marginTop + node.marginBottom;
-        }
-
-        return d;
-    }
-
-    public void setShowExtras(boolean showExtras) {
-        this.showExtras = showExtras;
-        repaint();
-    }
-
-    @Override
-    protected void paintComponent(Graphics g) {
-        Icon icon = getIcon();
-        int width = icon.getIconWidth();
-        int height = icon.getIconHeight();
-
-        int x = (getWidth() - width) / 2;
-        int y = (getHeight() - height) / 2;
-
-        icon.paintIcon(this, g, x, y);
-
-        if (showExtras) {
-            g.translate(x, y);
-            g.setXORMode(Color.WHITE);
-            if ((node.paddingBottom | node.paddingLeft |
-                    node.paddingTop | node.paddingRight) != 0) {
-                g.setColor(Color.RED);
-                g.drawRect(node.paddingLeft, node.paddingTop,
-                        width - node.paddingRight - node.paddingLeft,
-                        height - node.paddingBottom - node.paddingTop);
-            }
-            if (node.baseline != -1) {
-                g.setColor(Color.BLUE);
-                g.drawLine(0, node.baseline, width, node.baseline);
-            }
-            if (node.hasMargins && (node.marginLeft | node.marginBottom |
-                    node.marginRight | node.marginRight) != 0) {
-                g.setColor(Color.BLACK);
-                g.drawRect(-node.marginLeft, -node.marginTop,
-                        node.marginLeft + width + node.marginRight,
-                        node.marginTop + height + node.marginBottom);
-            }
-            g.translate(-x, -y);
-        }
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java
deleted file mode 100644
index 8943834..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui;
-
-import com.android.hierarchyviewer.scene.ViewHierarchyScene;
-import com.android.hierarchyviewer.scene.ViewNode;
-
-import javax.swing.JComponent;
-import javax.swing.BorderFactory;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Insets;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.util.Set;
-
-class LayoutRenderer extends JComponent {
-    private static final int EMULATED_SCREEN_WIDTH = 320;
-    private static final int EMULATED_SCREEN_HEIGHT = 480;
-    private static final int SCREEN_MARGIN = 24;
-
-    private boolean showExtras;
-    private ViewHierarchyScene scene;
-    private JComponent sceneView;
-
-    LayoutRenderer(ViewHierarchyScene scene, JComponent sceneView) {
-        this.scene = scene;
-        this.sceneView = sceneView;
-
-        setOpaque(true);
-        setBorder(BorderFactory.createEmptyBorder(0, 0, 12, 0));
-        setBackground(Color.BLACK);
-        setForeground(Color.WHITE);
-
-        addMouseListener(new MouseAdapter() {
-            @Override
-            public void mousePressed(MouseEvent event) {
-                selectChild(event.getX(), event.getY());
-            }
-        });
-    }
-
-    @Override
-    public Dimension getPreferredSize() {
-        return new Dimension(EMULATED_SCREEN_WIDTH + SCREEN_MARGIN,
-                EMULATED_SCREEN_HEIGHT + SCREEN_MARGIN);
-    }
-
-    @Override
-    protected void paintComponent(Graphics g) {
-        g.setColor(getBackground());
-        g.fillRect(0, 0, getWidth(), getHeight());
-
-        Insets insets = getInsets();
-        g.clipRect(insets.left, insets.top,
-                getWidth() - insets.left - insets.right,
-                getHeight() - insets.top - insets.bottom);
-
-        if (scene == null) {
-            return;
-        }
-
-        ViewNode root = scene.getRoot();
-        if (root == null) {
-            return;
-        }
-
-        int x = (getWidth() - insets.left - insets.right - root.width) / 2;
-        int y = (getHeight() - insets.top - insets.bottom - root.height) / 2;
-        g.translate(insets.left + x, insets.top + y);
-
-        g.setColor(getForeground());
-        g.drawRect(root.left, root.top, root.width - 1, root.height - 1);
-        g.clipRect(root.left - 1, root.top - 1, root.width + 1, root.height + 1);
-        drawChildren(g, root, -root.scrollX, -root.scrollY);
-
-        Set<?> selection = scene.getSelectedObjects();
-        if (selection.size() > 0) {
-            ViewNode node = (ViewNode) selection.iterator().next();
-            g.setColor(Color.RED);
-            Graphics s = g.create();
-            ViewNode p = node.parent;
-            while (p != null) {
-                s.translate(p.left - p.scrollX, p.top - p.scrollY);
-                p = p.parent;
-            }
-            if (showExtras && node.image != null) {
-                s.drawImage(node.image, node.left, node.top, null);
-            }
-            s.drawRect(node.left, node.top, node.width - 1, node.height - 1);
-            s.dispose();
-        }
-
-        g.translate(-insets.left - x, -insets.top - y);
-    }
-
-    private void drawChildren(Graphics g, ViewNode root, int x, int y) {
-        g.translate(x, y);
-        for (ViewNode node : root.children) {
-            if (!node.willNotDraw) {
-                g.drawRect(node.left, node.top, node.width - 1, node.height - 1);
-            }
-
-            if (node.children.size() > 0) {
-                drawChildren(g, node,
-                        node.left - node.parent.scrollX,
-                        node.top - node.parent.scrollY);
-            }
-        }
-        g.translate(-x, -y);
-    }
-
-    public void setShowExtras(boolean showExtras) {
-        this.showExtras = showExtras;
-        repaint();
-    }
-
-    private void selectChild(int x, int y) {
-
-        if (scene == null) {
-            return;
-        }
-
-        ViewNode root = scene.getRoot();
-        if (root == null) {
-            return;
-        }
-
-        Insets insets = getInsets();
-
-        int xoffset = (getWidth() - insets.left - insets.right - root.width) / 2 + insets.left + 1;
-        int yoffset = (getHeight() - insets.top - insets.bottom - root.height) / 2 + insets.top + 1;
-
-        x -= xoffset;
-        y -= yoffset;
-        if (x >= 0 && x < EMULATED_SCREEN_WIDTH && y >= 0 && y < EMULATED_SCREEN_HEIGHT) {
-            ViewNode hit = findChild(root, root, x, y);
-            scene.setFocusedObject(hit);
-            sceneView.repaint();
-        }
-    }
-
-    private ViewNode findChild(ViewNode root, ViewNode besthit, int x, int y) {
-        ViewNode hit = besthit;
-        for (ViewNode node : root.children) {
-
-            if (node.left <= x && x < node.left + node.width &&
-                node.top <= y && y < node.top + node.height) {
-                if (node.width <= hit.width && node.height <= hit.height) {
-                    hit = node;
-                }
-            }
-
-            if (node.children.size() > 0) {
-                hit = findChild(node, hit,
-                        x - (node.left - node.parent.scrollX),
-                        y - (node.top - node.parent.scrollY));
-            }
-        }
-        return hit;
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java
deleted file mode 100644
index 7c17c90..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java
+++ /dev/null
@@ -1,749 +0,0 @@
-package com.android.hierarchyviewer.ui;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.RawImage;
-import com.android.hierarchyviewer.util.WorkerThread;
-import com.android.hierarchyviewer.scene.ViewNode;
-import com.android.hierarchyviewer.ui.util.PngFileFilter;
-import com.android.hierarchyviewer.ui.util.IconLoader;
-
-import javax.swing.JComponent;
-import javax.swing.Timer;
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-import javax.swing.BorderFactory;
-import javax.swing.JLabel;
-import javax.swing.JSlider;
-import javax.swing.Box;
-import javax.swing.JCheckBox;
-import javax.swing.JButton;
-import javax.swing.JFileChooser;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.ChangeEvent;
-import javax.imageio.ImageIO;
-
-import org.jdesktop.swingworker.SwingWorker;
-
-import java.io.IOException;
-import java.io.File;
-import java.awt.image.BufferedImage;
-import java.awt.Graphics;
-import java.awt.Dimension;
-import java.awt.BorderLayout;
-import java.awt.Graphics2D;
-import java.awt.Color;
-import java.awt.Rectangle;
-import java.awt.Point;
-import java.awt.GridBagLayout;
-import java.awt.GridBagConstraints;
-import java.awt.Insets;
-import java.awt.FlowLayout;
-import java.awt.AlphaComposite;
-import java.awt.RenderingHints;
-import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseMotionAdapter;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.util.concurrent.ExecutionException;
-
-class ScreenViewer extends JPanel implements ActionListener {
-    private final Workspace workspace;
-    private final IDevice device;
-
-    private GetScreenshotTask task;
-    private BufferedImage image;
-    private int[] scanline;
-    private volatile boolean isLoading;
-
-    private BufferedImage overlay;
-    private AlphaComposite overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
-
-    private ScreenViewer.LoupeStatus status;
-    private ScreenViewer.LoupeViewer loupe;
-    private ScreenViewer.Crosshair crosshair;
-
-    private int zoom = 8;
-    private int y = 0;
-
-    private Timer timer;
-    private ViewNode node;
-
-    private JSlider zoomSlider;
-
-    ScreenViewer(Workspace workspace, IDevice device, int spacing) {
-        setLayout(new BorderLayout());
-        setOpaque(false);
-
-        this.workspace = workspace;
-        this.device = device;
-
-        timer = new Timer(5000, this);
-        timer.setInitialDelay(0);
-        timer.setRepeats(true);
-
-        JPanel panel = buildViewerAndControls();
-        add(panel, BorderLayout.WEST);
-
-        JPanel loupePanel = buildLoupePanel(spacing);
-        add(loupePanel, BorderLayout.CENTER);
-
-        SwingUtilities.invokeLater(new Runnable() {
-            public void run() {
-                timer.start();
-            }
-        });
-    }
-
-    private JPanel buildLoupePanel(int spacing) {
-        loupe = new LoupeViewer();
-        loupe.addMouseWheelListener(new WheelZoomListener());
-        CrosshairPanel crosshairPanel = new CrosshairPanel(loupe);
-
-        JPanel loupePanel = new JPanel(new BorderLayout());
-        loupePanel.add(crosshairPanel);
-        status = new LoupeStatus();
-        loupePanel.add(status, BorderLayout.SOUTH);
-
-        loupePanel.setBorder(BorderFactory.createEmptyBorder(0, spacing, 0, 0));
-        return loupePanel;
-    }
-
-    private class WheelZoomListener implements MouseWheelListener {
-        public void mouseWheelMoved(MouseWheelEvent e) {
-            if (zoomSlider != null) {
-                int val = zoomSlider.getValue();
-                val -= e.getWheelRotation() * 2;
-                zoomSlider.setValue(val);
-            }
-        }
-    }
-
-    private JPanel buildViewerAndControls() {
-        JPanel panel = new JPanel(new GridBagLayout());
-        crosshair = new Crosshair(new ScreenshotViewer());
-        crosshair.addMouseWheelListener(new WheelZoomListener());
-        panel.add(crosshair,
-                new GridBagConstraints(0, y++, 2, 1, 1.0f, 0.0f,
-                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 0), 0, 0));
-        buildSlider(panel, "Overlay:", "0%", "100%", 0, 100, 30, 1).addChangeListener(
-                new ChangeListener() {
-                    public void stateChanged(ChangeEvent event) {
-                        float opacity = ((JSlider) event.getSource()).getValue() / 100.0f;
-                        overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
-                        repaint();
-                    }
-        });
-        buildOverlayExtraControls(panel);
-        buildSlider(panel, "Refresh Rate:", "1s", "40s", 1, 40, 5, 1).addChangeListener(
-                new ChangeListener() {
-                    public void stateChanged(ChangeEvent event) {
-                        int rate = ((JSlider) event.getSource()).getValue() * 1000;
-                        timer.setDelay(rate);
-                        timer.setInitialDelay(0);
-                        timer.restart();
-                    }
-        });
-        zoomSlider = buildSlider(panel, "Zoom:", "2x", "24x", 2, 24, 8, 2);
-        zoomSlider.addChangeListener(
-                new ChangeListener() {
-                    public void stateChanged(ChangeEvent event) {
-                        zoom = ((JSlider) event.getSource()).getValue();
-                        loupe.clearGrid = true;
-                        loupe.moveToPoint(crosshair.crosshair.x, crosshair.crosshair.y);
-                        repaint();
-                    }
-        });
-        panel.add(Box.createVerticalGlue(),
-                new GridBagConstraints(0, y++, 2, 1, 1.0f, 1.0f,
-                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 0), 0, 0));
-        return panel;
-    }
-
-    private void buildOverlayExtraControls(JPanel panel) {
-        JPanel extras = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
-
-        JButton loadOverlay = new JButton("Load...");
-        loadOverlay.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent event) {
-                SwingWorker<?, ?> worker = openOverlay();
-                if (worker != null) {
-                    worker.execute();
-                }
-            }
-        });
-        extras.add(loadOverlay);
-
-        JCheckBox showInLoupe = new JCheckBox("Show in Loupe");
-        showInLoupe.setSelected(false);
-        showInLoupe.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent event) {
-                loupe.showOverlay = ((JCheckBox) event.getSource()).isSelected();
-                loupe.repaint();
-            }
-        });
-        extras.add(showInLoupe);
-
-        panel.add(extras, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                        new Insets(0, 0, 0, 0), 0, 0));
-    }
-
-    public SwingWorker<?, ?> openOverlay() {
-        JFileChooser chooser = new JFileChooser();
-        chooser.setFileFilter(new PngFileFilter());
-        int choice = chooser.showOpenDialog(this);
-        if (choice == JFileChooser.APPROVE_OPTION) {
-            return new OpenOverlayTask(chooser.getSelectedFile());
-        } else {
-            return null;
-        }
-    }
-
-    private JSlider buildSlider(JPanel panel, String title, String minName, String maxName,
-            int min, int max, int value, int tick) {
-        panel.add(new JLabel(title), new GridBagConstraints(0, y, 1, 1, 1.0f, 0.0f,
-                    GridBagConstraints.LINE_END, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 6), 0, 0));
-        JPanel sliderPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
-        sliderPanel.add(new JLabel(minName));
-        JSlider slider = new JSlider(min, max, value);
-        slider.setMinorTickSpacing(tick);
-        slider.setMajorTickSpacing(tick);
-        slider.setSnapToTicks(true);
-        sliderPanel.add(slider);
-        sliderPanel.add(new JLabel(maxName));
-        panel.add(sliderPanel, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f,
-                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
-                        new Insets(0, 0, 0, 0), 0, 0));
-        return slider;
-    }
-
-    void stop() {
-        timer.stop();
-    }
-
-    void start() {
-        timer.start();
-    }
-
-    void select(ViewNode node) {
-        this.node = node;
-        repaint();
-    }
-
-    class LoupeViewer extends JComponent {
-        private final Color lineColor = new Color(1.0f, 1.0f, 1.0f, 0.3f);
-
-        private int width;
-        private int height;
-        private BufferedImage grid;
-        private int left;
-        private int top;
-        public boolean clearGrid;
-
-        private final Rectangle clip = new Rectangle();
-        private boolean showOverlay = false;
-
-        LoupeViewer() {
-            addMouseListener(new MouseAdapter() {
-                @Override
-                public void mousePressed(MouseEvent event) {
-                    moveToPoint(event);
-                }
-            });
-            addMouseMotionListener(new MouseMotionAdapter() {
-                @Override
-                public void mouseDragged(MouseEvent event) {
-                    moveToPoint(event);
-                }
-            });
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            if (isLoading) {
-                return;
-            }
-
-            g.translate(-left, -top);
-
-            if (image != null) {
-                Graphics2D g2 = (Graphics2D) g.create();
-                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
-                g2.scale(zoom, zoom);
-                g2.drawImage(image, 0, 0, null);
-                if (overlay != null && showOverlay) {
-                    g2.setComposite(overlayAlpha);
-                    g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null);
-                }
-                g2.dispose();
-            }
-
-            int width = getWidth();
-            int height = getHeight();
-
-            Graphics2D g2 = null;
-            if (width != this.width || height != this.height) {
-                this.width = width;
-                this.height = height;
-
-                grid = new BufferedImage(width + zoom + 1, height + zoom + 1,
-                        BufferedImage.TYPE_INT_ARGB);
-                clearGrid = true;
-                g2 = grid.createGraphics();
-            } else if (clearGrid) {
-                g2 = grid.createGraphics();
-                g2.setComposite(AlphaComposite.Clear);
-                g2.fillRect(0, 0, grid.getWidth(), grid.getHeight());
-                g2.setComposite(AlphaComposite.SrcOver);
-            }
-
-            if (clearGrid) {
-                clearGrid = false;
-
-                g2.setColor(lineColor);
-                width += zoom;
-                height += zoom;
-
-                for (int x = zoom; x <= width; x += zoom) {
-                    g2.drawLine(x, 0, x, height);
-                }
-
-                for (int y = 0; y <= height; y += zoom) {
-                    g2.drawLine(0, y, width, y);
-                }
-
-                g2.dispose();
-            }
-
-            if (image != null) {
-                g.getClipBounds(clip);
-                g.clipRect(0, 0, image.getWidth() * zoom + 1, image.getHeight() * zoom + 1);
-                g.drawImage(grid, clip.x - clip.x % zoom, clip.y - clip.y % zoom, null);
-            }
-
-            g.translate(left, top);
-        }
-
-        void moveToPoint(MouseEvent event) {
-            int x = Math.max(0, Math.min((event.getX() + left) / zoom, image.getWidth() - 1));
-            int y = Math.max(0, Math.min((event.getY() + top) / zoom, image.getHeight() - 1));
-            moveToPoint(x, y);
-            crosshair.moveToPoint(x, y);
-        }
-
-        void moveToPoint(int x, int y) {
-            left = x * zoom - width / 2 + zoom / 2;
-            top = y * zoom - height / 2 + zoom / 2;
-            repaint();
-        }
-    }
-
-    class LoupeStatus extends JPanel {
-        private JLabel xLabel;
-        private JLabel yLabel;
-        private JLabel rLabel;
-        private JLabel gLabel;
-        private JLabel bLabel;
-        private JLabel hLabel;
-        private ScreenViewer.LoupeStatus.ColoredSquare square;
-        private Color color;
-
-        LoupeStatus() {
-            setOpaque(true);
-            setLayout(new GridBagLayout());
-            setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
-
-            square = new ColoredSquare();
-            add(square, new GridBagConstraints(0, 0, 1, 2, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 12), 0, 0 ));
-
-            JLabel label;
-
-            add(label = new JLabel("#ffffff"), new GridBagConstraints(0, 2, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 12), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            hLabel = label;
-
-            add(label = new JLabel("R:"), new GridBagConstraints(1, 0, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 6, 0, 6), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            add(label = new JLabel("255"), new GridBagConstraints(2, 0, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 12), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            rLabel = label;
-
-            add(label = new JLabel("G:"), new GridBagConstraints(1, 1, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 6, 0, 6), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            add(label = new JLabel("255"), new GridBagConstraints(2, 1, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 12), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            gLabel = label;
-
-            add(label = new JLabel("B:"), new GridBagConstraints(1, 2, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 6, 0, 6), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            add(label = new JLabel("255"), new GridBagConstraints(2, 2, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 12), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            bLabel = label;
-
-            add(label = new JLabel("X:"), new GridBagConstraints(3, 0, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 6, 0, 6), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            add(label = new JLabel("0 px"), new GridBagConstraints(4, 0, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 12), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            xLabel = label;
-
-            add(label = new JLabel("Y:"), new GridBagConstraints(3, 1, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 6, 0, 6), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            add(label = new JLabel("0 px"), new GridBagConstraints(4, 1, 1, 1, 0.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
-                    new Insets(0, 0, 0, 12), 0, 0 ));
-            label.setForeground(Color.WHITE);
-            yLabel = label;
-
-            add(Box.createHorizontalGlue(), new GridBagConstraints(5, 0, 1, 1, 1.0f, 0.0f,
-                    GridBagConstraints.LINE_START, GridBagConstraints.BOTH,
-                    new Insets(0, 0, 0, 0), 0, 0 ));
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            g.setColor(Color.BLACK);
-            g.fillRect(0, 0, getWidth(), getHeight());
-        }
-
-        void showPixel(int x, int y) {
-            xLabel.setText(x + " px");
-            yLabel.setText(y + " px");
-
-            int pixel = image.getRGB(x, y);
-            color = new Color(pixel);
-            hLabel.setText("#" + Integer.toHexString(pixel));
-            rLabel.setText(String.valueOf((pixel >> 16) & 0xff));
-            gLabel.setText(String.valueOf((pixel >>  8) & 0xff));
-            bLabel.setText(String.valueOf((pixel      ) & 0xff));
-
-            square.repaint();
-        }
-
-        private class ColoredSquare extends JComponent {
-            @Override
-            public Dimension getPreferredSize() {
-                Dimension d = super.getPreferredSize();
-                d.width = 60;
-                d.height = 30;
-                return d;
-            }
-
-            @Override
-            protected void paintComponent(Graphics g) {
-                g.setColor(color);
-                g.fillRect(0, 0, getWidth(), getHeight());
-
-                g.setColor(Color.WHITE);
-                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
-            }
-        }
-    }
-
-    class Crosshair extends JPanel {
-        // magenta = 0xff5efe
-        private final Color crosshairColor = new Color(0x00ffff);
-        Point crosshair = new Point();
-        private int width;
-        private int height;
-
-        Crosshair(ScreenshotViewer screenshotViewer) {
-            setOpaque(true);
-            setLayout(new BorderLayout());
-            add(screenshotViewer);
-            addMouseListener(new MouseAdapter() {
-                @Override
-                public void mousePressed(MouseEvent event) {
-                    moveToPoint(event);
-                }
-            });
-            addMouseMotionListener(new MouseMotionAdapter() {
-                @Override
-                public void mouseDragged(MouseEvent event) {
-                    moveToPoint(event);
-                }
-            });
-        }
-
-        void moveToPoint(int x, int y) {
-            crosshair.x = x;
-            crosshair.y = y;
-            status.showPixel(crosshair.x, crosshair.y);
-            repaint();
-        }
-
-        private void moveToPoint(MouseEvent event) {
-            crosshair.x = Math.max(0, Math.min(image.getWidth() - 1, event.getX()));
-            crosshair.y = Math.max(0, Math.min(image.getHeight() - 1, event.getY()));
-            loupe.moveToPoint(crosshair.x, crosshair.y);
-            status.showPixel(crosshair.x, crosshair.y);
-
-            repaint();
-        }
-
-        @Override
-        public void paint(Graphics g) {
-            super.paint(g);
-
-            if (crosshair == null || width != getWidth() || height != getHeight()) {
-                width = getWidth();
-                height = getHeight();
-                crosshair = new Point(width / 2, height / 2);
-            }
-
-            g.setColor(crosshairColor);
-
-            g.drawLine(crosshair.x, 0, crosshair.x, height);
-            g.drawLine(0, crosshair.y, width, crosshair.y);
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            super.paintComponent(g);
-            g.setColor(Color.BLACK);
-            g.fillRect(0, 0, getWidth(), getHeight());
-        }
-    }
-
-    class ScreenshotViewer extends JComponent {
-        private final Color boundsColor = new Color(0xff5efe);
-
-        ScreenshotViewer() {
-            setOpaque(true);
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            g.setColor(Color.BLACK);
-            g.fillRect(0, 0, getWidth(), getHeight());
-
-            if (isLoading) {
-                return;
-            }
-
-            if (image != null) {
-                g.drawImage(image, 0, 0, null);
-                if (overlay != null) {
-                    Graphics2D g2 = (Graphics2D) g.create();
-                    g2.setComposite(overlayAlpha);
-                    g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null);
-                }
-            }
-
-            if (node != null) {
-                Graphics s = g.create();
-                s.setColor(boundsColor);
-                ViewNode p = node.parent;
-                while (p != null) {
-                    s.translate(p.left - p.scrollX, p.top - p.scrollY);
-                    p = p.parent;
-                }
-                s.drawRect(node.left, node.top, node.width - 1, node.height - 1);
-                s.translate(node.left, node.top);
-
-                s.setXORMode(Color.WHITE);
-                if ((node.paddingBottom | node.paddingLeft |
-                        node.paddingTop | node.paddingRight) != 0) {
-                    s.setColor(Color.BLACK);
-                    s.drawRect(node.paddingLeft, node.paddingTop,
-                            node.width - node.paddingRight - node.paddingLeft - 1,
-                            node.height - node.paddingBottom - node.paddingTop - 1);
-                }
-                if (node.hasMargins && (node.marginLeft | node.marginBottom |
-                        node.marginRight | node.marginRight) != 0) {
-                    s.setColor(Color.BLACK);
-                    s.drawRect(-node.marginLeft, -node.marginTop,
-                            node.marginLeft + node.width + node.marginRight - 1,
-                            node.marginTop + node.height + node.marginBottom - 1);
-                }
-
-                s.dispose();
-            }
-        }
-
-        @Override
-        public Dimension getPreferredSize() {
-            if (image == null) {
-                return new Dimension(320, 480);
-            }
-            return new Dimension(image.getWidth(), image.getHeight());
-        }
-    }
-
-    private class CrosshairPanel extends JPanel {
-        private final Color crosshairColor = new Color(0xff5efe);
-        private final Insets insets = new Insets(0, 0, 0, 0);
-
-        CrosshairPanel(LoupeViewer loupe) {
-            setLayout(new BorderLayout());
-            add(loupe);
-        }
-
-        @Override
-        public void paint(Graphics g) {
-            super.paint(g);
-
-            g.setColor(crosshairColor);
-
-            int width = getWidth();
-            int height = getHeight();
-
-            getInsets(insets);
-
-            int x = (width - insets.left - insets.right) / 2;
-            int y = (height - insets.top - insets.bottom) / 2;
-
-            g.drawLine(insets.left + x, insets.top, insets.left + x, height - insets.bottom);
-            g.drawLine(insets.left, insets.top + y, width - insets.right, insets.top + y);
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            g.setColor(Color.BLACK);
-            Insets insets = getInsets();
-            g.fillRect(insets.left, insets.top, getWidth() - insets.left - insets.right,
-                    getHeight() - insets.top - insets.bottom);
-        }
-    }
-
-    public void actionPerformed(ActionEvent event) {
-        if (task != null && !task.isDone()) {
-            return;
-        }
-        task = new GetScreenshotTask();
-        task.execute();
-    }
-
-    private class GetScreenshotTask extends SwingWorker<Boolean, Void> {
-        private GetScreenshotTask() {
-            workspace.beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Boolean doInBackground() throws Exception {
-            RawImage rawImage;
-            try {
-                rawImage = device.getScreenshot();
-            } catch (IOException ioe) {
-                return false;
-            }
-
-            boolean resize = false;
-            isLoading = true;
-            try {
-                if (rawImage != null && rawImage.bpp == 16) {
-                    if (image == null || rawImage.width != image.getWidth() ||
-                            rawImage.height != image.getHeight()) {
-                        image = new BufferedImage(rawImage.width, rawImage.height,
-                                BufferedImage.TYPE_INT_ARGB);
-                        scanline = new int[rawImage.width];
-                        resize = true;
-                    }
-
-                    byte[] buffer = rawImage.data;
-                    int index = 0;
-                    for (int y = 0 ; y < rawImage.height ; y++) {
-                        for (int x = 0 ; x < rawImage.width ; x++) {
-                            int value = buffer[index++] & 0x00FF;
-                            value |= (buffer[index++] << 8) & 0x0FF00;
-
-                            int r = ((value >> 11) & 0x01F) << 3;
-                            int g = ((value >> 5) & 0x03F) << 2;
-                            int b = ((value     ) & 0x01F) << 3;
-
-                            scanline[x] = 0xFF << 24 | r << 16 | g << 8 | b;
-                        }
-                        image.setRGB(0, y, rawImage.width, 1, scanline,
-                                0, rawImage.width);
-                    }
-                }
-            } finally {
-                isLoading = false;
-            }
-
-            return resize;
-        }
-
-        @Override
-        protected void done() {
-            workspace.endTask();
-            try {
-                if (get()) {
-                    validate();
-                    crosshair.crosshair = new Point(image.getWidth() / 2,
-                            image.getHeight() / 2);
-                    status.showPixel(image.getWidth() / 2, image.getHeight() / 2);
-                    loupe.moveToPoint(image.getWidth() / 2, image.getHeight() / 2);
-                }
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            } catch (ExecutionException e) {
-                e.printStackTrace();
-            }
-            repaint();
-        }
-    }
-
-    private class OpenOverlayTask extends SwingWorker<BufferedImage, Void> {
-        private File file;
-
-        private OpenOverlayTask(File file) {
-            this.file = file;
-            workspace.beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected BufferedImage doInBackground() {
-            try {
-                return IconLoader.toCompatibleImage(ImageIO.read(file));
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-            return null;
-        }
-
-        @Override
-        protected void done() {
-            try {
-                overlay = get();
-                repaint();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            } catch (ExecutionException e) {
-                e.printStackTrace();
-            } finally {
-                workspace.endTask();
-            }
-        }
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java
deleted file mode 100644
index 1361243..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java
+++ /dev/null
@@ -1,1504 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.hierarchyviewer.device.DeviceBridge;
-import com.android.hierarchyviewer.device.Window;
-import com.android.hierarchyviewer.laf.UnifiedContentBorder;
-import com.android.hierarchyviewer.scene.CaptureLoader;
-import com.android.hierarchyviewer.scene.ViewHierarchyLoader;
-import com.android.hierarchyviewer.scene.ViewHierarchyScene;
-import com.android.hierarchyviewer.scene.ViewManager;
-import com.android.hierarchyviewer.scene.ViewNode;
-import com.android.hierarchyviewer.scene.WindowsLoader;
-import com.android.hierarchyviewer.scene.ProfilesLoader;
-import com.android.hierarchyviewer.util.OS;
-import com.android.hierarchyviewer.util.WorkerThread;
-import com.android.hierarchyviewer.ui.action.ShowDevicesAction;
-import com.android.hierarchyviewer.ui.action.RequestLayoutAction;
-import com.android.hierarchyviewer.ui.action.InvalidateAction;
-import com.android.hierarchyviewer.ui.action.CaptureNodeAction;
-import com.android.hierarchyviewer.ui.action.RefreshWindowsAction;
-import com.android.hierarchyviewer.ui.action.StopServerAction;
-import com.android.hierarchyviewer.ui.action.StartServerAction;
-import com.android.hierarchyviewer.ui.action.ExitAction;
-import com.android.hierarchyviewer.ui.action.LoadGraphAction;
-import com.android.hierarchyviewer.ui.action.SaveSceneAction;
-import com.android.hierarchyviewer.ui.util.PngFileFilter;
-import com.android.hierarchyviewer.ui.util.IconLoader;
-import com.android.hierarchyviewer.ui.model.PropertiesTableModel;
-import com.android.hierarchyviewer.ui.model.ViewsTreeModel;
-import com.android.hierarchyviewer.ui.model.ProfilesTableModel;
-import org.jdesktop.swingworker.SwingWorker;
-import org.netbeans.api.visual.graph.layout.TreeGraphLayout;
-import org.netbeans.api.visual.model.ObjectSceneEvent;
-import org.netbeans.api.visual.model.ObjectSceneEventType;
-import org.netbeans.api.visual.model.ObjectSceneListener;
-import org.netbeans.api.visual.model.ObjectState;
-
-import javax.imageio.ImageIO;
-import javax.swing.ActionMap;
-import javax.swing.BorderFactory;
-import javax.swing.ButtonGroup;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JPanel;
-import javax.swing.JProgressBar;
-import javax.swing.JScrollPane;
-import javax.swing.JScrollBar;
-import javax.swing.JSlider;
-import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.JToggleButton;
-import javax.swing.JToolBar;
-import javax.swing.ListSelectionModel;
-import javax.swing.SwingUtilities;
-import javax.swing.JTree;
-import javax.swing.Box;
-import javax.swing.JTextField;
-import javax.swing.text.Document;
-import javax.swing.text.BadLocationException;
-import javax.swing.tree.TreePath;
-import javax.swing.tree.DefaultTreeCellRenderer;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.event.TreeSelectionListener;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.event.DocumentEvent;
-import javax.swing.table.DefaultTableModel;
-import java.awt.image.BufferedImage;
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.GridBagLayout;
-import java.awt.GridBagConstraints;
-import java.awt.Insets;
-import java.awt.FlowLayout;
-import java.awt.Color;
-import java.awt.Image;
-import java.awt.Graphics2D;
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-import java.util.concurrent.ExecutionException;
-
-public class Workspace extends JFrame {
-    private JLabel viewCountLabel;
-    private JSlider zoomSlider;
-    private JSplitPane sideSplitter;
-    private JSplitPane mainSplitter;
-    private JTable propertiesTable;
-    private JTable profilingTable;
-    private JComponent pixelPerfectPanel;
-    private JTree pixelPerfectTree;
-    private ScreenViewer screenViewer;
-
-    private JPanel extrasPanel;
-    private LayoutRenderer layoutView;
-
-    private JScrollPane sceneScroller;
-    private JComponent sceneView;
-
-    private ViewHierarchyScene scene;
-
-    private ActionMap actionsMap;
-    private JPanel mainPanel;
-    private JProgressBar progress;
-    private JToolBar buttonsPanel;
-
-    private JComponent deviceSelector;
-    private DevicesTableModel devicesTableModel;
-    private WindowsTableModel windowsTableModel;
-
-    private IDevice currentDevice;
-    private Window currentWindow = Window.FOCUSED_WINDOW;
-
-    private JButton displayNodeButton;
-    private JButton invalidateButton;
-    private JButton requestLayoutButton;
-    private JButton loadButton;
-    private JButton startButton;
-    private JButton stopButton;
-    private JButton showDevicesButton;
-    private JButton refreshButton;
-    private JToggleButton graphViewButton;
-    private JToggleButton pixelPerfectViewButton;
-    private JMenuItem saveMenuItem;
-    private JMenuItem showDevicesMenuItem;
-    private JMenuItem loadMenuItem;
-    private JMenuItem startMenuItem;
-    private JMenuItem stopMenuItem;
-    private JTable devices;
-    private JTable windows;
-    private JLabel minZoomLabel;
-    private JLabel maxZoomLabel;
-    private JTextField filterText;
-    private JLabel filterLabel;
-
-    public Workspace() {
-        super("Hierarchy Viewer");
-
-        buildActions();
-        add(buildMainPanel());
-        setJMenuBar(buildMenuBar());
-
-        devices.changeSelection(0, 0, false, false);
-        currentDeviceChanged();
-
-        pack();
-    }
-
-    private void buildActions() {
-        actionsMap = new ActionMap();
-        actionsMap.put(ExitAction.ACTION_NAME, new ExitAction(this));
-        actionsMap.put(ShowDevicesAction.ACTION_NAME, new ShowDevicesAction(this));
-        actionsMap.put(LoadGraphAction.ACTION_NAME, new LoadGraphAction(this));
-        actionsMap.put(SaveSceneAction.ACTION_NAME, new SaveSceneAction(this));
-        actionsMap.put(StartServerAction.ACTION_NAME, new StartServerAction(this));
-        actionsMap.put(StopServerAction.ACTION_NAME, new StopServerAction(this));
-        actionsMap.put(InvalidateAction.ACTION_NAME, new InvalidateAction(this));
-        actionsMap.put(RequestLayoutAction.ACTION_NAME, new RequestLayoutAction(this));
-        actionsMap.put(CaptureNodeAction.ACTION_NAME, new CaptureNodeAction(this));
-        actionsMap.put(RefreshWindowsAction.ACTION_NAME, new RefreshWindowsAction(this));
-    }
-
-    private JComponent buildMainPanel() {
-        mainPanel = new JPanel();
-        mainPanel.setLayout(new BorderLayout());
-        mainPanel.add(buildToolBar(), BorderLayout.PAGE_START);
-        mainPanel.add(deviceSelector = buildDeviceSelector(), BorderLayout.CENTER);
-        mainPanel.add(buildStatusPanel(), BorderLayout.SOUTH);
-
-        mainPanel.setPreferredSize(new Dimension(950, 800));
-
-        return mainPanel;
-    }
-
-    private JComponent buildGraphPanel() {
-        sceneScroller = new JScrollPane();
-        sceneScroller.setBorder(null);
-
-        mainSplitter = new JSplitPane();
-        mainSplitter.setResizeWeight(1.0);
-        mainSplitter.setContinuousLayout(true);
-        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
-            mainSplitter.setBorder(new UnifiedContentBorder());
-        }
-
-        mainSplitter.setLeftComponent(sceneScroller);
-        mainSplitter.setRightComponent(buildSideSplitter());
-
-        return mainSplitter;
-    }
-
-    private JComponent buildDeviceSelector() {
-        JPanel panel = new JPanel(new GridBagLayout());
-        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
-            panel.setBorder(new UnifiedContentBorder());
-        }
-
-        devicesTableModel = new DevicesTableModel();
-        for (IDevice device : DeviceBridge.getDevices()) {
-            DeviceBridge.setupDeviceForward(device);
-            devicesTableModel.addDevice(device);
-        }
-        DeviceBridge.startListenForDevices(devicesTableModel);
-
-        devices = new JTable(devicesTableModel);
-        devices.getSelectionModel().addListSelectionListener(new DeviceSelectedListener());
-        devices.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        devices.setBorder(null);
-        JScrollPane devicesScroller = new JScrollPane(devices);
-        devicesScroller.setBorder(null);
-        panel.add(devicesScroller, new GridBagConstraints(0, 0, 1, 1, 0.5, 1.0,
-                GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
-                0, 0));
-
-        windowsTableModel = new WindowsTableModel();
-        windowsTableModel.setVisible(false);
-
-        windows = new JTable(windowsTableModel);
-        windows.getSelectionModel().addListSelectionListener(new WindowSelectedListener());
-        windows.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        windows.setBorder(null);
-        JScrollPane windowsScroller = new JScrollPane(windows);
-        windowsScroller.setBorder(null);
-        panel.add(windowsScroller, new GridBagConstraints(2, 0, 1, 1, 0.5, 1.0,
-                GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
-                0, 0));
-
-        return panel;
-    }
-
-    private JComponent buildSideSplitter() {
-        propertiesTable = new JTable();
-        propertiesTable.setModel(new DefaultTableModel(new Object[][] { },
-                new String[] { "Property", "Value" }));
-        propertiesTable.setBorder(null);
-        propertiesTable.getTableHeader().setBorder(null);
-
-        JScrollPane tableScroller = new JScrollPane(propertiesTable);
-        tableScroller.setBorder(null);
-
-        profilingTable = new JTable();
-        profilingTable.setModel(new DefaultTableModel(new Object[][] {
-                { " " , " " }, { " " , " " }, { " " , " " } },
-                new String[] { "Operation", "Duration (ms)" }));
-        profilingTable.setBorder(null);
-        profilingTable.getTableHeader().setBorder(null);
-
-        JScrollPane firstTableScroller = new JScrollPane(profilingTable);
-        firstTableScroller.setBorder(null);
-
-        setVisibleRowCount(profilingTable, 5);
-        firstTableScroller.setMinimumSize(profilingTable.getPreferredScrollableViewportSize());
-
-        JSplitPane tablesSplitter = new JSplitPane();
-        tablesSplitter.setBorder(null);
-        tablesSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
-        tablesSplitter.setResizeWeight(0);
-        tablesSplitter.setLeftComponent(firstTableScroller);
-        tablesSplitter.setBottomComponent(tableScroller);
-        tablesSplitter.setContinuousLayout(true);
-
-        sideSplitter = new JSplitPane();
-        sideSplitter.setBorder(null);
-        sideSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
-        sideSplitter.setResizeWeight(0.5);
-        sideSplitter.setLeftComponent(tablesSplitter);
-        sideSplitter.setBottomComponent(null);
-        sideSplitter.setContinuousLayout(true);
-
-        return sideSplitter;
-    }
-
-    private JPanel buildStatusPanel() {
-        JPanel statusPanel = new JPanel();
-        statusPanel.setLayout(new BorderLayout());
-
-        JPanel leftSide = new JPanel();
-        leftSide.setOpaque(false);
-        leftSide.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
-        leftSide.add(Box.createHorizontalStrut(6));
-
-        ButtonGroup group = new ButtonGroup();
-
-        graphViewButton = new JToggleButton(IconLoader.load(getClass(),
-                "/images/icon-graph-view.png"));
-        graphViewButton.setSelectedIcon(IconLoader.load(getClass(),
-                "/images/icon-graph-view-selected.png"));
-        graphViewButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        graphViewButton.putClientProperty("JButton.segmentPosition", "first");
-        graphViewButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                toggleGraphView();
-            }
-        });
-        group.add(graphViewButton);
-        leftSide.add(graphViewButton);
-
-        pixelPerfectViewButton = new JToggleButton(IconLoader.load(getClass(),
-                "/images/icon-pixel-perfect-view.png"));
-        pixelPerfectViewButton.setSelectedIcon(IconLoader.load(getClass(),
-                "/images/icon-pixel-perfect-view-selected.png"));
-        pixelPerfectViewButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        pixelPerfectViewButton.putClientProperty("JButton.segmentPosition", "last");
-        pixelPerfectViewButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                togglePixelPerfectView();
-            }
-        });
-        group.add(pixelPerfectViewButton);
-        leftSide.add(pixelPerfectViewButton);
-
-        graphViewButton.setSelected(true);
-
-        filterText = new JTextField(20);
-        filterText.putClientProperty("JComponent.sizeVariant", "small");
-        filterText.getDocument().addDocumentListener(new DocumentListener() {
-            public void insertUpdate(DocumentEvent e) {
-                updateFilter(e);
-            }
-
-            public void removeUpdate(DocumentEvent e) {
-                updateFilter(e);
-            }
-
-            public void changedUpdate(DocumentEvent e) {
-                updateFilter(e);
-            }
-        });
-
-        filterLabel = new JLabel("Filter by class or id:");
-        filterLabel.putClientProperty("JComponent.sizeVariant", "small");
-        filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6));
-
-        leftSide.add(filterLabel);
-        leftSide.add(filterText);
-
-        minZoomLabel = new JLabel();
-        minZoomLabel.setText("20%");
-        minZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
-        minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
-        leftSide.add(minZoomLabel);
-
-        zoomSlider = new JSlider();
-        zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
-        zoomSlider.setMaximum(200);
-        zoomSlider.setMinimum(20);
-        zoomSlider.setValue(100);
-        zoomSlider.addChangeListener(new ChangeListener() {
-            public void stateChanged(ChangeEvent evt) {
-                zoomSliderStateChanged(evt);
-            }
-        });
-        leftSide.add(zoomSlider);
-
-        maxZoomLabel = new JLabel();
-        maxZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
-        maxZoomLabel.setText("200%");
-        leftSide.add(maxZoomLabel);
-
-        viewCountLabel = new JLabel();
-        viewCountLabel.setText("0 views");
-        viewCountLabel.putClientProperty("JComponent.sizeVariant", "small");
-        viewCountLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
-        leftSide.add(viewCountLabel);
-
-        statusPanel.add(leftSide, BorderLayout.LINE_START);
-
-        JPanel rightSide = new JPanel();
-        rightSide.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 12));
-        rightSide.setLayout(new FlowLayout(FlowLayout.RIGHT));
-
-        progress = new JProgressBar();
-        progress.setVisible(false);
-        progress.setIndeterminate(true);
-        progress.putClientProperty("JComponent.sizeVariant", "mini");
-        progress.putClientProperty("JProgressBar.style", "circular");
-        rightSide.add(progress);
-
-        statusPanel.add(rightSide, BorderLayout.LINE_END);
-
-        hideStatusBarComponents();
-
-        return statusPanel;
-    }
-
-    private void hideStatusBarComponents() {
-        viewCountLabel.setVisible(false);
-        zoomSlider.setVisible(false);
-        minZoomLabel.setVisible(false);
-        maxZoomLabel.setVisible(false);
-        filterLabel.setVisible(false);
-        filterText.setVisible(false);
-    }
-
-    private JToolBar buildToolBar() {
-        JToolBar toolBar = new JToolBar();
-        toolBar.setFloatable(false);
-        toolBar.setRollover(true);
-
-        startButton = new JButton();
-        startButton.setAction(actionsMap.get(StartServerAction.ACTION_NAME));
-        startButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        startButton.putClientProperty("JButton.segmentPosition", "first");
-        toolBar.add(startButton);
-
-        stopButton = new JButton();
-        stopButton.setAction(actionsMap.get(StopServerAction.ACTION_NAME));
-        stopButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        stopButton.putClientProperty("JButton.segmentPosition", "middle");
-        toolBar.add(stopButton);
-
-        refreshButton = new JButton();
-        refreshButton.setAction(actionsMap.get(RefreshWindowsAction.ACTION_NAME));
-        refreshButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        refreshButton.putClientProperty("JButton.segmentPosition", "last");
-        toolBar.add(refreshButton);
-
-        showDevicesButton = new JButton();
-        showDevicesButton.setAction(actionsMap.get(ShowDevicesAction.ACTION_NAME));
-        showDevicesButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        showDevicesButton.putClientProperty("JButton.segmentPosition", "first");
-        toolBar.add(showDevicesButton);
-        showDevicesButton.setEnabled(false);
-
-        loadButton = new JButton();
-        loadButton.setAction(actionsMap.get(LoadGraphAction.ACTION_NAME));
-        loadButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        loadButton.putClientProperty("JButton.segmentPosition", "last");
-        toolBar.add(loadButton);
-
-        displayNodeButton = new JButton();
-        displayNodeButton.setAction(actionsMap.get(CaptureNodeAction.ACTION_NAME));
-        displayNodeButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        displayNodeButton.putClientProperty("JButton.segmentPosition", "first");
-        toolBar.add(displayNodeButton);
-
-        invalidateButton = new JButton();
-        invalidateButton.setAction(actionsMap.get(InvalidateAction.ACTION_NAME));
-        invalidateButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        invalidateButton.putClientProperty("JButton.segmentPosition", "middle");
-        toolBar.add(invalidateButton);
-
-        requestLayoutButton = new JButton();
-        requestLayoutButton.setAction(actionsMap.get(RequestLayoutAction.ACTION_NAME));
-        requestLayoutButton.putClientProperty("JButton.buttonType", "segmentedTextured");
-        requestLayoutButton.putClientProperty("JButton.segmentPosition", "last");
-        toolBar.add(requestLayoutButton);
-
-        return toolBar;
-    }
-
-    private JMenuBar buildMenuBar() {
-        JMenuBar menuBar = new JMenuBar();
-
-        JMenu fileMenu = new JMenu();
-        JMenu viewMenu = new JMenu();
-        JMenu viewHierarchyMenu = new JMenu();
-        JMenu serverMenu = new JMenu();
-
-        saveMenuItem = new JMenuItem();
-        JMenuItem exitMenuItem = new JMenuItem();
-
-        showDevicesMenuItem = new JMenuItem();
-
-        loadMenuItem = new JMenuItem();
-
-        startMenuItem = new JMenuItem();
-        stopMenuItem = new JMenuItem();
-
-        fileMenu.setText("File");
-
-        saveMenuItem.setAction(actionsMap.get(SaveSceneAction.ACTION_NAME));
-        fileMenu.add(saveMenuItem);
-
-        exitMenuItem.setAction(actionsMap.get(ExitAction.ACTION_NAME));
-        fileMenu.add(exitMenuItem);
-
-        menuBar.add(fileMenu);
-
-        viewMenu.setText("View");
-
-        showDevicesMenuItem.setAction(actionsMap.get(ShowDevicesAction.ACTION_NAME));
-        showDevicesMenuItem.setEnabled(false);
-        viewMenu.add(showDevicesMenuItem);
-
-        menuBar.add(viewMenu);
-
-        viewHierarchyMenu.setText("Hierarchy");
-
-        loadMenuItem.setAction(actionsMap.get(LoadGraphAction.ACTION_NAME));
-        viewHierarchyMenu.add(loadMenuItem);
-
-        menuBar.add(viewHierarchyMenu);
-
-        serverMenu.setText("Server");
-
-        startMenuItem.setAction(actionsMap.get(StartServerAction.ACTION_NAME));
-        serverMenu.add(startMenuItem);
-
-        stopMenuItem.setAction(actionsMap.get(StopServerAction.ACTION_NAME));
-        serverMenu.add(stopMenuItem);
-
-        menuBar.add(serverMenu);
-
-        return menuBar;
-    }
-
-    private JComponent buildPixelPerfectPanel() {
-        JSplitPane splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
-
-        pixelPerfectTree = new JTree(new Object[0]);
-        pixelPerfectTree.setBorder(null);
-        pixelPerfectTree.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
-        pixelPerfectTree.addTreeSelectionListener(new TreeSelectionListener() {
-            public void valueChanged(TreeSelectionEvent event) {
-                ViewNode node = (ViewNode) event.getPath().getLastPathComponent();
-                screenViewer.select(node);
-            }
-        });
-
-        JScrollPane scroller = new JScrollPane(pixelPerfectTree);
-        scroller.setBorder(null);
-        scroller.getViewport().setBorder(null);
-
-        splitter.setContinuousLayout(true);
-        splitter.setLeftComponent(scroller);
-        splitter.setRightComponent(buildPixelPerfectViewer(splitter));
-        splitter.setBorder(null);
-
-        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
-            splitter.setBorder(new UnifiedContentBorder());
-        }
-
-        return splitter;
-    }
-
-    private JComponent buildPixelPerfectViewer(JSplitPane splitter) {
-        screenViewer = new ScreenViewer(this, currentDevice, splitter.getDividerSize());
-        return screenViewer;
-    }
-
-    private void toggleGraphView() {
-        showStatusBarComponents();
-
-        screenViewer.stop();
-        mainPanel.remove(pixelPerfectPanel);
-        mainPanel.add(mainSplitter, BorderLayout.CENTER);
-
-        validate();
-        repaint();
-    }
-
-    private void showStatusBarComponents() {
-        viewCountLabel.setVisible(true);
-        zoomSlider.setVisible(true);
-        minZoomLabel.setVisible(true);
-        maxZoomLabel.setVisible(true);
-        filterLabel.setVisible(true);
-        filterText.setVisible(true);
-    }
-
-    private void togglePixelPerfectView() {
-        if (pixelPerfectPanel == null) {
-            pixelPerfectPanel = buildPixelPerfectPanel();
-            showPixelPerfectTree();
-        } else {
-            screenViewer.start();
-        }
-
-        hideStatusBarComponents();
-
-        mainPanel.remove(mainSplitter);
-        mainPanel.add(pixelPerfectPanel, BorderLayout.CENTER);
-
-        validate();
-        repaint();
-    }
-
-    private void zoomSliderStateChanged(ChangeEvent evt) {
-        JSlider slider = (JSlider) evt.getSource();
-        if (sceneView != null) {
-            scene.setZoomFactor(slider.getValue() / 100.0d);
-            sceneView.repaint();
-        }
-    }
-
-    private void showProperties(ViewNode node) {
-        propertiesTable.setModel(new PropertiesTableModel(node));
-    }
-
-    private void updateProfiles(double[] profiles) {
-        profilingTable.setModel(new ProfilesTableModel(profiles));
-        setVisibleRowCount(profilingTable, profiles.length + 1);
-    }
-
-    public static void setVisibleRowCount(JTable table, int rows) {
-        int height = 0;
-        for (int row = 0; row < rows; row++) {
-            height += table.getRowHeight(row);
-        }
-
-        Dimension size = new Dimension(table.getPreferredScrollableViewportSize().width, height);
-        table.setPreferredScrollableViewportSize(size);
-        table.revalidate();
-    }
-
-    private void showPixelPerfectTree() {
-        if (pixelPerfectTree == null) {
-            return;
-        }
-        pixelPerfectTree.setModel(new ViewsTreeModel(scene.getRoot()));
-        pixelPerfectTree.setCellRenderer(new ViewsTreeCellRenderer());
-        expandAll(pixelPerfectTree, true);
-
-    }
-
-    private static void expandAll(JTree tree, boolean expand) {
-        ViewNode root = (ViewNode) tree.getModel().getRoot();
-        expandAll(tree, new TreePath(root), expand);
-    }
-
-    private static void expandAll(JTree tree, TreePath parent, boolean expand) {
-        // Traverse children
-        ViewNode node = (ViewNode)parent.getLastPathComponent();
-        if (node.children != null) {
-            for (ViewNode n : node.children) {
-                TreePath path = parent.pathByAddingChild(n);
-                expandAll(tree, path, expand);
-            }
-        }
-
-        if (expand) {
-            tree.expandPath(parent);
-        } else {
-            tree.collapsePath(parent);
-        }
-    }
-
-    private void createGraph(ViewHierarchyScene scene) {
-        scene.addObjectSceneListener(new SceneFocusListener(),
-                ObjectSceneEventType.OBJECT_FOCUS_CHANGED);
-
-        if (mainSplitter == null) {
-            mainPanel.remove(deviceSelector);
-            mainPanel.add(buildGraphPanel(), BorderLayout.CENTER);
-            showDevicesButton.setEnabled(true);
-            showDevicesMenuItem.setEnabled(true);
-            graphViewButton.setEnabled(true);
-            pixelPerfectViewButton.setEnabled(true);
-
-            showStatusBarComponents();
-        }
-
-        sceneView = scene.createView();
-        sceneView.addMouseListener(new NodeClickListener());
-        sceneView.addMouseWheelListener(new WheelZoomListener());
-        sceneScroller.setViewportView(sceneView);
-
-        if (extrasPanel != null) {
-            sideSplitter.remove(extrasPanel);
-        }
-        sideSplitter.setBottomComponent(buildExtrasPanel());
-
-        mainSplitter.setDividerLocation(getWidth() - mainSplitter.getDividerSize() -
-                buttonsPanel.getPreferredSize().width);
-
-        saveMenuItem.setEnabled(true);
-        showPixelPerfectTree();
-
-        updateStatus();
-        layoutScene();
-    }
-
-    private void layoutScene() {
-        TreeGraphLayout<ViewNode, String> layout =
-                new TreeGraphLayout<ViewNode, String>(scene, 50, 50, 70, 30, true);
-        layout.layout(scene.getRoot());
-    }
-
-    private void updateStatus() {
-        viewCountLabel.setText("" + scene.getNodes().size() + " views");
-        zoomSlider.setEnabled(scene.getNodes().size() > 0);
-    }
-
-    private JPanel buildExtrasPanel() {
-        extrasPanel = new JPanel(new BorderLayout());
-        JScrollPane p = new JScrollPane(layoutView = new LayoutRenderer(scene, sceneView));
-        JScrollBar b = p.getVerticalScrollBar();
-        b.setUnitIncrement(10);
-        extrasPanel.add(p);
-        extrasPanel.add(scene.createSatelliteView(), BorderLayout.SOUTH);
-        extrasPanel.add(buildLayoutViewControlButtons(), BorderLayout.NORTH);
-        return extrasPanel;
-    }
-
-    private JComponent buildLayoutViewControlButtons() {
-        buttonsPanel = new JToolBar();
-        buttonsPanel.setFloatable(false);
-
-        ButtonGroup group = new ButtonGroup();
-
-        JToggleButton white = new JToggleButton("On White");
-        toggleColorOnSelect(white);
-        white.putClientProperty("JButton.buttonType", "segmentedTextured");
-        white.putClientProperty("JButton.segmentPosition", "first");
-        white.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                layoutView.setBackground(Color.WHITE);
-                layoutView.setForeground(Color.BLACK);
-            }
-        });
-        group.add(white);
-        buttonsPanel.add(white);
-
-        JToggleButton black = new JToggleButton("On Black");
-        toggleColorOnSelect(black);
-        black.putClientProperty("JButton.buttonType", "segmentedTextured");
-        black.putClientProperty("JButton.segmentPosition", "last");
-        black.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                layoutView.setBackground(Color.BLACK);
-                layoutView.setForeground(Color.WHITE);
-            }
-        });
-        group.add(black);
-        buttonsPanel.add(black);
-
-        black.setSelected(true);
-
-        JCheckBox showExtras = new JCheckBox("Show Extras");
-        showExtras.putClientProperty("JComponent.sizeVariant", "small");
-        showExtras.addChangeListener(new ChangeListener() {
-            public void stateChanged(ChangeEvent e) {
-                layoutView.setShowExtras(((JCheckBox) e.getSource()).isSelected());
-            }
-        });
-        buttonsPanel.add(showExtras);
-
-        return buttonsPanel;
-    }
-
-    private void showCaptureWindow(ViewNode node, String captureParams, Image image) {
-        if (image != null) {
-            layoutView.repaint();
-
-            JFrame frame = new JFrame(captureParams);
-            JPanel panel = new JPanel(new BorderLayout());
-
-            final CaptureRenderer label = new CaptureRenderer(new ImageIcon(image), node);
-            label.setBorder(BorderFactory.createEmptyBorder(24, 24, 24, 24));
-
-            final JPanel solidColor = new JPanel(new BorderLayout());
-            solidColor.setBackground(Color.BLACK);
-            solidColor.add(label);
-
-            JToolBar toolBar = new JToolBar();
-            toolBar.setFloatable(false);
-
-            ButtonGroup group = new ButtonGroup();
-
-            JToggleButton white = new JToggleButton("On White");
-            toggleColorOnSelect(white);
-            white.putClientProperty("JButton.buttonType", "segmentedTextured");
-            white.putClientProperty("JButton.segmentPosition", "first");
-            white.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent e) {
-                    solidColor.setBackground(Color.WHITE);
-                }
-            });
-            group.add(white);
-            toolBar.add(white);
-
-            JToggleButton black = new JToggleButton("On Black");
-            toggleColorOnSelect(black);
-            black.putClientProperty("JButton.buttonType", "segmentedTextured");
-            black.putClientProperty("JButton.segmentPosition", "last");
-            black.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent e) {
-                    solidColor.setBackground(Color.BLACK);
-                }
-            });
-            group.add(black);
-            toolBar.add(black);
-
-            black.setSelected(true);
-
-            JCheckBox showExtras = new JCheckBox("Show Extras");
-            showExtras.addChangeListener(new ChangeListener() {
-                public void stateChanged(ChangeEvent e) {
-                    label.setShowExtras(((JCheckBox) e.getSource()).isSelected());
-                }
-            });
-            toolBar.add(showExtras);
-
-            panel.add(toolBar, BorderLayout.NORTH);
-            panel.add(solidColor);
-            frame.add(panel);
-
-            frame.pack();
-            frame.setResizable(false);
-            frame.setLocationRelativeTo(Workspace.this);
-            frame.setVisible(true);
-        }
-    }
-
-    private void reset() {
-        currentDevice = null;
-        currentWindow = null;
-        currentDeviceChanged();
-        windowsTableModel.setVisible(false);
-        windowsTableModel.clear();
-
-        showDevicesSelector();
-    }
-
-    public void showDevicesSelector() {
-        if (mainSplitter != null) {
-            if (pixelPerfectPanel != null) {
-                screenViewer.start();
-            }
-            mainPanel.remove(graphViewButton.isSelected() ? mainSplitter : pixelPerfectPanel);
-            mainPanel.add(deviceSelector, BorderLayout.CENTER);
-            pixelPerfectPanel = mainSplitter = null;
-            graphViewButton.setSelected(true);
-
-            hideStatusBarComponents();
-
-            saveMenuItem.setEnabled(false);
-            showDevicesMenuItem.setEnabled(false);
-            showDevicesButton.setEnabled(false);
-            displayNodeButton.setEnabled(false);
-            invalidateButton.setEnabled(false);
-            requestLayoutButton.setEnabled(false);
-            graphViewButton.setEnabled(false);
-            pixelPerfectViewButton.setEnabled(false);
-
-            if (currentDevice != null) {
-                if (!DeviceBridge.isViewServerRunning(currentDevice)) {
-                    DeviceBridge.startViewServer(currentDevice);
-                }
-                loadWindows().execute();
-                windowsTableModel.setVisible(true);
-            }
-
-            validate();
-            repaint();
-        }
-    }
-
-    private void currentDeviceChanged() {
-        if (currentDevice == null) {
-            startButton.setEnabled(false);
-            startMenuItem.setEnabled(false);
-            stopButton.setEnabled(false);
-            stopMenuItem.setEnabled(false);
-            refreshButton.setEnabled(false);
-            saveMenuItem.setEnabled(false);
-            loadButton.setEnabled(false);
-            displayNodeButton.setEnabled(false);
-            invalidateButton.setEnabled(false);
-            graphViewButton.setEnabled(false);
-            pixelPerfectViewButton.setEnabled(false);
-            requestLayoutButton.setEnabled(false);
-            loadMenuItem.setEnabled(false);
-        } else {
-            loadMenuItem.setEnabled(true);
-            checkForServerOnCurrentDevice();
-        }
-    }
-
-    private void checkForServerOnCurrentDevice() {
-        if (DeviceBridge.isViewServerRunning(currentDevice)) {
-            startButton.setEnabled(false);
-            startMenuItem.setEnabled(false);
-            stopButton.setEnabled(true);
-            stopMenuItem.setEnabled(true);
-            loadButton.setEnabled(true);
-            refreshButton.setEnabled(true);
-        } else {
-            startButton.setEnabled(true);
-            startMenuItem.setEnabled(true);
-            stopButton.setEnabled(false);
-            stopMenuItem.setEnabled(false);
-            loadButton.setEnabled(false);
-            refreshButton.setEnabled(false);
-        }
-    }
-
-    public void cleanupDevices() {
-        for (IDevice device : devicesTableModel.getDevices()) {
-            DeviceBridge.removeDeviceForward(device);
-        }
-    }
-
-    private static void toggleColorOnSelect(JToggleButton button) {
-        if (!OS.isMacOsX() || !OS.isLeopardOrLater()) {
-            return;
-        }
-
-        button.addChangeListener(new ChangeListener() {
-            public void stateChanged(ChangeEvent event) {
-                JToggleButton button = (JToggleButton) event.getSource();
-                if (button.isSelected()) {
-                    button.setForeground(Color.WHITE);
-                } else {
-                    button.setForeground(Color.BLACK);
-                }
-            }
-        });
-    }
-
-    private void updateFilter(DocumentEvent e) {
-        final Document document = e.getDocument();
-        try {
-            updateFilteredNodes(document.getText(0, document.getLength()));
-        } catch (BadLocationException e1) {
-            e1.printStackTrace();
-        }
-    }
-
-    private void updateFilteredNodes(String filterText) {
-        final ViewNode root = scene.getRoot();
-        try {
-            final Pattern pattern = Pattern.compile(filterText, Pattern.CASE_INSENSITIVE);
-            filterNodes(pattern, root);
-        } catch (PatternSyntaxException e) {
-            filterNodes(null, root);
-        }
-        repaint();
-    }
-
-    private void filterNodes(Pattern pattern, ViewNode root) {
-        root.filter(pattern);
-
-        for (ViewNode node : root.children) {
-            filterNodes(pattern, node);
-        }
-    }
-
-    public void beginTask() {
-        progress.setVisible(true);
-    }
-
-    public void endTask() {
-        progress.setVisible(false);
-    }
-
-    public SwingWorker<?, ?> showNodeCapture() {
-        if (scene.getFocusedObject() == null) {
-            return null;
-        }
-        return new CaptureNodeTask();
-    }
-
-    public SwingWorker<?, ?> startServer() {
-        return new StartServerTask();
-    }
-
-    public SwingWorker<?, ?> stopServer() {
-        return new StopServerTask();
-    }
-
-    public SwingWorker<?, ?> loadWindows() {
-        return new LoadWindowsTask();
-    }
-
-    public SwingWorker<?, ?> loadGraph() {
-        return new LoadGraphTask();
-    }
-
-    public SwingWorker<?, ?> invalidateView() {
-        if (scene.getFocusedObject() == null) {
-            return null;
-        }
-        return new InvalidateTask();
-    }
-
-    public SwingWorker<?, ?> requestLayout() {
-        if (scene.getFocusedObject() == null) {
-            return null;
-        }
-        return new RequestLayoutTask();
-    }
-
-    public SwingWorker<?, ?> saveSceneAsImage() {
-        JFileChooser chooser = new JFileChooser();
-        chooser.setFileFilter(new PngFileFilter());
-        int choice = chooser.showSaveDialog(sceneView);
-        if (choice == JFileChooser.APPROVE_OPTION) {
-            return new SaveSceneTask(chooser.getSelectedFile());
-        } else {
-            return null;
-        }
-    }
-
-    private class InvalidateTask extends SwingWorker<Object, Void> {
-        private String captureParams;
-
-        private InvalidateTask() {
-            captureParams = scene.getFocusedObject().toString();
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Object doInBackground() throws Exception {
-            ViewManager.invalidate(currentDevice, currentWindow, captureParams);
-            return null;
-        }
-
-        @Override
-        protected void done() {
-            endTask();
-        }
-    }
-
-    private class RequestLayoutTask extends SwingWorker<Object, Void> {
-        private String captureParams;
-
-        private RequestLayoutTask() {
-            captureParams = scene.getFocusedObject().toString();
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Object doInBackground() throws Exception {
-            ViewManager.requestLayout(currentDevice, currentWindow, captureParams);
-            return null;
-        }
-
-        @Override
-        protected void done() {
-            endTask();
-        }
-    }
-
-    private class CaptureNodeTask extends SwingWorker<Image, Void> {
-        private String captureParams;
-        private ViewNode node;
-
-        private CaptureNodeTask() {
-            node = (ViewNode) scene.getFocusedObject();
-            captureParams = node.toString();
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Image doInBackground() throws Exception {
-            node.image = CaptureLoader.loadCapture(currentDevice, currentWindow, captureParams);
-            return node.image;
-        }
-
-        @Override
-        protected void done() {
-            try {
-                Image image = get();
-                showCaptureWindow(node, captureParams, image);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            } catch (ExecutionException e) {
-                e.printStackTrace();
-            } finally {
-                endTask();
-            }
-        }
-    }
-
-    private class LoadWindowsTask extends SwingWorker<Window[], Void> {
-        private LoadWindowsTask() {
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Window[] doInBackground() throws Exception {
-            return WindowsLoader.loadWindows(currentDevice);
-        }
-
-        @Override
-        protected void done() {
-            try {
-                windowsTableModel.clear();
-                windowsTableModel.addWindows(get());
-            } catch (ExecutionException e) {
-                e.printStackTrace();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            } finally {
-                endTask();
-            }
-        }
-    }
-
-    private class StartServerTask extends SwingWorker<Object, Void> {
-        public StartServerTask() {
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Object doInBackground() {
-            DeviceBridge.startViewServer(currentDevice);
-            return null;
-        }
-
-        @Override
-        protected void done() {
-            new LoadWindowsTask().execute();
-            windowsTableModel.setVisible(true);
-            checkForServerOnCurrentDevice();
-            endTask();
-        }
-    }
-
-    private class StopServerTask extends SwingWorker<Object, Void> {
-        public StopServerTask() {
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Object doInBackground() {
-            DeviceBridge.stopViewServer(currentDevice);
-            return null;
-        }
-
-        @Override
-        protected void done() {
-            windowsTableModel.setVisible(false);
-            windowsTableModel.clear();
-            checkForServerOnCurrentDevice();
-            endTask();
-        }
-    }
-
-    private class LoadGraphTask extends SwingWorker<double[], Void> {
-        public LoadGraphTask() {
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected double[] doInBackground() {
-            scene = ViewHierarchyLoader.loadScene(currentDevice, currentWindow);
-            return ProfilesLoader.loadProfiles(currentDevice, currentWindow,
-                    scene.getRoot().toString());
-        }
-
-        @Override
-        protected void done() {
-            try {
-                createGraph(scene);
-                updateProfiles(get());
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            } catch (ExecutionException e) {
-                e.printStackTrace();
-            } finally {
-                endTask();
-            }
-        }
-    }
-
-    private class SaveSceneTask extends SwingWorker<Object, Void> {
-        private File file;
-
-        private SaveSceneTask(File file) {
-            this.file = file;
-            beginTask();
-        }
-
-        @Override
-        @WorkerThread
-        protected Object doInBackground() {
-            if (sceneView == null) {
-                return null;
-            }
-
-            try {
-                BufferedImage image = new BufferedImage(sceneView.getWidth(),
-                        sceneView.getHeight(), BufferedImage.TYPE_INT_RGB);
-                Graphics2D g2 = image.createGraphics();
-                sceneView.paint(g2);
-                g2.dispose();
-                ImageIO.write(image, "PNG", file);
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-            return null;
-        }
-
-        @Override
-        protected void done() {
-            endTask();
-        }
-    }
-
-    private class SceneFocusListener implements ObjectSceneListener {
-
-        public void objectAdded(ObjectSceneEvent arg0, Object arg1) {
-        }
-
-        public void objectRemoved(ObjectSceneEvent arg0, Object arg1) {
-        }
-
-        public void objectStateChanged(ObjectSceneEvent arg0, Object arg1,
-                ObjectState arg2, ObjectState arg3) {
-        }
-
-        public void selectionChanged(ObjectSceneEvent e, Set<Object> previousSelection,
-                Set<Object> newSelection) {
-        }
-
-        public void highlightingChanged(ObjectSceneEvent arg0, Set<Object> arg1, Set<Object> arg2) {
-        }
-
-        public void hoverChanged(ObjectSceneEvent arg0, Object arg1, Object arg2) {
-        }
-
-        public void focusChanged(ObjectSceneEvent e, Object oldFocus, Object newFocus) {
-            displayNodeButton.setEnabled(true);
-            invalidateButton.setEnabled(true);
-            requestLayoutButton.setEnabled(true);
-
-            Set<Object> selection = new HashSet<Object>();
-            selection.add(newFocus);
-            scene.setSelectedObjects(selection);
-
-            showProperties((ViewNode) newFocus);
-            layoutView.repaint();
-        }
-    }
-
-    private class NodeClickListener extends MouseAdapter {
-        @Override
-        public void mouseClicked(MouseEvent e) {
-            if (e.getClickCount() == 2) {
-                showNodeCapture().execute();
-            }
-        }
-    }
-
-    private class WheelZoomListener implements MouseWheelListener {
-        public void mouseWheelMoved(MouseWheelEvent e) {
-            if (zoomSlider != null) {
-                int val = zoomSlider.getValue();
-                val -= e.getWheelRotation() * 10;
-                zoomSlider.setValue(val);
-            }
-        }
-    }
-    private class DevicesTableModel extends DefaultTableModel implements
-            AndroidDebugBridge.IDeviceChangeListener {
-
-        private ArrayList<IDevice> devices;
-
-        private DevicesTableModel() {
-            devices = new ArrayList<IDevice>();
-        }
-
-        @Override
-        public int getColumnCount() {
-            return 1;
-        }
-
-        @Override
-        public boolean isCellEditable(int row, int column) {
-            return false;
-        }
-
-        @Override
-        public Object getValueAt(int row, int column) {
-            return devices.get(row);
-        }
-
-        @Override
-        public String getColumnName(int column) {
-            return "Devices";
-        }
-
-        @WorkerThread
-        public void deviceConnected(final IDevice device) {
-            DeviceBridge.setupDeviceForward(device);
-
-            SwingUtilities.invokeLater(new Runnable() {
-                public void run() {
-                    addDevice(device);
-                }
-            });
-        }
-
-        @WorkerThread
-        public void deviceDisconnected(final IDevice device) {
-            DeviceBridge.removeDeviceForward(device);
-
-            SwingUtilities.invokeLater(new Runnable() {
-                public void run() {
-                    removeDevice(device);
-                }
-            });
-        }
-
-        public void addDevice(IDevice device) {
-            if (!devices.contains(device)) {
-                devices.add(device);
-                fireTableDataChanged();
-            }
-        }
-
-        public void removeDevice(IDevice device) {
-            if (device.equals(currentDevice)) {
-                reset();
-            }
-
-            if (devices.contains(device)) {
-                devices.remove(device);
-                fireTableDataChanged();
-            }
-        }
-
-        @WorkerThread
-        public void deviceChanged(IDevice device, int changeMask) {
-            if ((changeMask & IDevice.CHANGE_STATE) != 0 &&
-                    device.isOnline()) {
-                // if the device state changed and it's now online, we set up its port forwarding.
-                DeviceBridge.setupDeviceForward(device);
-            } else if (device == currentDevice && (changeMask & IDevice.CHANGE_CLIENT_LIST) != 0) {
-                // if the changed device is the current one and the client list changed, we update
-                // the UI.
-                loadWindows().execute();
-                windowsTableModel.setVisible(true);
-            }
-        }
-
-        @Override
-        public int getRowCount() {
-            return devices == null ? 0 : devices.size();
-        }
-
-        public IDevice getDevice(int index) {
-            return index < devices.size() ? devices.get(index) : null;
-        }
-
-        public IDevice[] getDevices() {
-            return devices.toArray(new IDevice[devices.size()]);
-        }
-    }
-
-    private static class WindowsTableModel extends DefaultTableModel {
-        private ArrayList<Window> windows;
-        private boolean visible;
-
-        private WindowsTableModel() {
-            windows = new ArrayList<Window>();
-            windows.add(Window.FOCUSED_WINDOW);
-        }
-
-        @Override
-        public int getColumnCount() {
-            return 1;
-        }
-
-        @Override
-        public boolean isCellEditable(int row, int column) {
-            return false;
-        }
-
-        @Override
-        public String getColumnName(int column) {
-            return "Windows";
-        }
-
-        @Override
-        public Object getValueAt(int row, int column) {
-            return windows.get(row);
-        }
-
-        @Override
-        public int getRowCount() {
-            return !visible || windows == null ? 0 : windows.size();
-        }
-
-        public void setVisible(boolean visible) {
-            this.visible = visible;
-            fireTableDataChanged();
-        }
-
-        public void addWindow(Window window) {
-            windows.add(window);
-            fireTableDataChanged();
-        }
-
-        public void addWindows(Window[] windowsList) {
-            //noinspection ManualArrayToCollectionCopy
-            for (Window window : windowsList) {
-                windows.add(window);
-            }
-            fireTableDataChanged();
-        }
-
-        public void clear() {
-            windows.clear();
-            windows.add(Window.FOCUSED_WINDOW);
-        }
-
-        public Window getWindow(int index) {
-            return windows.get(index);
-        }
-    }
-
-    private class DeviceSelectedListener implements ListSelectionListener {
-        public void valueChanged(ListSelectionEvent event) {
-            if (event.getValueIsAdjusting()) {
-                return;
-            }
-
-            int row = devices.getSelectedRow();
-            if (row >= 0) {
-                currentDevice = devicesTableModel.getDevice(row);
-                currentDeviceChanged();
-                if (currentDevice != null) {
-                    if (!DeviceBridge.isViewServerRunning(currentDevice)) {
-                        DeviceBridge.startViewServer(currentDevice);
-                        checkForServerOnCurrentDevice();
-                    }
-                    loadWindows().execute();
-                    windowsTableModel.setVisible(true);
-                }
-            } else {
-                currentDevice = null;
-                currentDeviceChanged();
-                windowsTableModel.setVisible(false);
-                windowsTableModel.clear();
-            }
-        }
-    }
-
-    private class WindowSelectedListener implements ListSelectionListener {
-        public void valueChanged(ListSelectionEvent event) {
-            if (event.getValueIsAdjusting()) {
-                return;
-            }
-
-            int row = windows.getSelectedRow();
-            if (row >= 0) {
-                currentWindow = windowsTableModel.getWindow(row);
-            } else {
-                currentWindow = Window.FOCUSED_WINDOW;
-            }
-        }
-    }
-
-    private static class ViewsTreeCellRenderer extends DefaultTreeCellRenderer {
-        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
-                boolean expanded, boolean leaf, int row, boolean hasFocus) {
-
-            final String name = ((ViewNode) value).name;
-            value = name.substring(name.lastIndexOf('.') + 1, name.lastIndexOf('@'));
-            return super.getTreeCellRendererComponent(tree, value, selected, expanded,
-                    leaf, row, hasFocus);
-        }
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/BackgroundAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/BackgroundAction.java
deleted file mode 100644
index 051e3f3..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/BackgroundAction.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import org.jdesktop.swingworker.SwingWorker;
-
-import javax.swing.AbstractAction;
-
-public abstract class BackgroundAction extends AbstractAction {
-    protected void executeBackgroundTask(SwingWorker<?, ?> worker) {
-        if (worker != null) {
-            worker.execute();
-        }
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/CaptureNodeAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/CaptureNodeAction.java
deleted file mode 100644
index a8aee3c..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/CaptureNodeAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class CaptureNodeAction extends BackgroundAction {
-    public static final String ACTION_NAME = "captureNode";
-    private Workspace mWorkspace;
-
-    public CaptureNodeAction(Workspace workspace) {
-        putValue(NAME, "Display View");
-        putValue(SHORT_DESCRIPTION, "Display View");
-        putValue(LONG_DESCRIPTION, "Display View");
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_D,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.showNodeCapture());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ExitAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ExitAction.java
deleted file mode 100644
index e5aaed5..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ExitAction.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-import com.android.hierarchyviewer.device.DeviceBridge;
-
-import javax.swing.AbstractAction;
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class ExitAction extends AbstractAction {
-    public static final String ACTION_NAME = "exit";
-    private Workspace mWorkspace;
-
-    public ExitAction(Workspace workspace) {
-        putValue(NAME, "Quit");
-        putValue(SHORT_DESCRIPTION, "Quit");
-        putValue(LONG_DESCRIPTION, "Quit");
-        putValue(MNEMONIC_KEY, KeyEvent.VK_Q);
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        mWorkspace.cleanupDevices();
-        mWorkspace.dispose();
-        DeviceBridge.terminate();
-        System.exit(0);
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/InvalidateAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/InvalidateAction.java
deleted file mode 100644
index 7767cda..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/InvalidateAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class InvalidateAction extends BackgroundAction {
-    public static final String ACTION_NAME = "invalidate";
-    private Workspace mWorkspace;
-
-    public InvalidateAction(Workspace workspace) {
-        putValue(NAME, "Invalidate");
-        putValue(SHORT_DESCRIPTION, "Invalidate");
-        putValue(LONG_DESCRIPTION, "Invalidate");
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_I,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.invalidateView());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/LoadGraphAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/LoadGraphAction.java
deleted file mode 100644
index 42c8b8e..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/LoadGraphAction.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class LoadGraphAction extends BackgroundAction {
-    public static final String ACTION_NAME = "loadGraph";
-    private Workspace mWorkspace;
-
-    public LoadGraphAction(Workspace workspace) {
-        putValue(NAME, "Load View Hierarchy");
-        putValue(SHORT_DESCRIPTION, "Load");
-        putValue(LONG_DESCRIPTION, "Load View Hierarchy");
-        putValue(MNEMONIC_KEY, KeyEvent.VK_L);
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_L,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.loadGraph());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RefreshWindowsAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RefreshWindowsAction.java
deleted file mode 100644
index bcb7ea7..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RefreshWindowsAction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-
-public class RefreshWindowsAction extends BackgroundAction {
-    public static final String ACTION_NAME = "refreshWindows";
-    private Workspace mWorkspace;
-
-    public RefreshWindowsAction(Workspace workspace) {
-        putValue(NAME, "Refresh Windows");
-        putValue(SHORT_DESCRIPTION, "Refresh");
-        putValue(LONG_DESCRIPTION, "Refresh Windows");
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.loadWindows());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RequestLayoutAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RequestLayoutAction.java
deleted file mode 100644
index 6fc2832..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RequestLayoutAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class RequestLayoutAction extends BackgroundAction {
-    public static final String ACTION_NAME = "requestLayout";
-    private Workspace mWorkspace;
-
-    public RequestLayoutAction(Workspace workspace) {
-        putValue(NAME, "Request Layout");
-        putValue(SHORT_DESCRIPTION, "Request Layout");
-        putValue(LONG_DESCRIPTION, "Request Layout");
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_R,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.requestLayout());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/SaveSceneAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/SaveSceneAction.java
deleted file mode 100644
index 7c7a8a9..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/SaveSceneAction.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class SaveSceneAction extends BackgroundAction {
-    public static final String ACTION_NAME = "saveScene";
-    private Workspace mWorkspace;
-
-    public SaveSceneAction(Workspace workspace) {
-        mWorkspace = workspace;
-        putValue(NAME, "Save as PNG...");
-        putValue(SHORT_DESCRIPTION, "Save");
-        putValue(LONG_DESCRIPTION, "Save as PNG...");
-        putValue(MNEMONIC_KEY, KeyEvent.VK_S);
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.saveSceneAsImage());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ShowDevicesAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ShowDevicesAction.java
deleted file mode 100644
index a91ab7a..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ShowDevicesAction.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.AbstractAction;
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-import java.awt.Toolkit;
-
-public class ShowDevicesAction extends AbstractAction {
-    public static final String ACTION_NAME = "showDevices";
-    private Workspace mWorkspace;
-
-    public ShowDevicesAction(Workspace workspace) {
-        putValue(NAME, "Devices");
-        putValue(SHORT_DESCRIPTION, "Devices");
-        putValue(LONG_DESCRIPTION, "Show Devices");
-        putValue(MNEMONIC_KEY, KeyEvent.VK_D);
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_D,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        mWorkspace.showDevicesSelector();
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StartServerAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StartServerAction.java
deleted file mode 100644
index ccb6ae0..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StartServerAction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-
-public class StartServerAction extends BackgroundAction {
-    public static final String ACTION_NAME = "startServer";
-    private Workspace mWorkspace;
-
-    public StartServerAction(Workspace workspace) {
-        putValue(NAME, "Start Server");
-        putValue(SHORT_DESCRIPTION, "Start");
-        putValue(LONG_DESCRIPTION, "Start Server");
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.startServer());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StopServerAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StopServerAction.java
deleted file mode 100644
index ac76e14..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StopServerAction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.action;
-
-import com.android.hierarchyviewer.ui.Workspace;
-
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.ActionEvent;
-
-public class StopServerAction extends BackgroundAction {
-    public static final String ACTION_NAME = "stopServer";
-    private Workspace mWorkspace;
-
-    public StopServerAction(Workspace workspace) {
-        putValue(NAME, "Stop Server");
-        putValue(SHORT_DESCRIPTION, "Stop");
-        putValue(LONG_DESCRIPTION, "Stop Server");
-        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0));
-        this.mWorkspace = workspace;
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        executeBackgroundTask(mWorkspace.stopServer());
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ProfilesTableModel.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ProfilesTableModel.java
deleted file mode 100644
index fcbe6b5..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ProfilesTableModel.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.hierarchyviewer.ui.model;
-
-import javax.swing.table.DefaultTableModel;
-import java.text.NumberFormat;
-
-public class ProfilesTableModel extends DefaultTableModel {
-    private static final String[] NAMES = { "measure", "layout", "draw" };
-
-    private final double[] profiles;
-    private final NumberFormat formatter;
-
-    public ProfilesTableModel(double[] profiles) {
-        this.profiles = profiles;
-        formatter = NumberFormat.getNumberInstance();
-    }
-
-    @Override
-    public int getRowCount() {
-        return profiles == null ? 0 : profiles.length;
-    }
-
-    @Override
-    public Object getValueAt(int row, int column) {
-        if (profiles == null) return "";
-
-        if (column == 0) {
-            return NAMES[row];
-        }
-
-
-        return formatter.format(profiles[row]) + "";
-    }
-
-    @Override
-    public int getColumnCount() {
-        return 2;
-    }
-
-    @Override
-    public String getColumnName(int column) {
-        return column == 0 ? "Operation" : "Duration (ms)";
-    }
-
-    @Override
-    public boolean isCellEditable(int arg0, int arg1) {
-        return false;
-    }
-
-    @Override
-    public void setValueAt(Object arg0, int arg1, int arg2) {
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/PropertiesTableModel.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/PropertiesTableModel.java
deleted file mode 100644
index cc4f7e3..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/PropertiesTableModel.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.model;
-
-import com.android.hierarchyviewer.scene.ViewNode;
-
-import javax.swing.table.DefaultTableModel;
-import java.util.List;
-import java.util.ArrayList;
-
-public class PropertiesTableModel extends DefaultTableModel {
-    private List<ViewNode.Property> properties;
-    private List<ViewNode.Property> privateProperties = new ArrayList<ViewNode.Property>();
-
-    public PropertiesTableModel(ViewNode node) {
-        properties = node.properties;
-        loadPrivateProperties(node);
-    }
-
-    private void loadPrivateProperties(ViewNode node) {
-        int x = node.left;
-        int y = node.top;
-        ViewNode p = node.parent;
-        while (p != null) {
-            x += p.left - p.scrollX;
-            y += p.top - p.scrollY;
-            p = p.parent;
-        }
-
-        ViewNode.Property property = new ViewNode.Property();
-        property.name = "absolute_x";
-        property.value = String.valueOf(x);
-        privateProperties.add(property);
-
-        property = new ViewNode.Property();
-        property.name = "absolute_y";
-        property.value = String.valueOf(y);
-        privateProperties.add(property);
-    }
-
-    @Override
-    public int getRowCount() {
-        return (privateProperties == null ? 0 : privateProperties.size()) +
-                (properties == null ? 0 : properties.size());
-    }
-
-    @Override
-    public Object getValueAt(int row, int column) {
-        ViewNode.Property property;
-
-        if (row < privateProperties.size()) {
-            property = privateProperties.get(row);
-        } else {
-            property = properties.get(row - privateProperties.size());
-        }
-
-        return column == 0 ? property.name : property.value;
-    }
-
-    @Override
-    public int getColumnCount() {
-        return 2;
-    }
-
-    @Override
-    public String getColumnName(int column) {
-        return column == 0 ? "Property" : "Value";
-    }
-
-    @Override
-    public boolean isCellEditable(int arg0, int arg1) {
-        return false;
-    }
-
-    @Override
-    public void setValueAt(Object arg0, int arg1, int arg2) {
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ViewsTreeModel.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ViewsTreeModel.java
deleted file mode 100644
index f3a07f8..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ViewsTreeModel.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.model;
-
-import com.android.hierarchyviewer.scene.ViewNode;
-
-import javax.swing.tree.TreeModel;
-import javax.swing.tree.TreePath;
-import javax.swing.event.TreeModelListener;
-
-public class ViewsTreeModel implements TreeModel {
-    private final ViewNode root;
-
-    public ViewsTreeModel(ViewNode root) {
-        this.root = root;
-    }
-
-    public Object getRoot() {
-        return root;
-    }
-
-    public Object getChild(Object o, int i) {
-        return ((ViewNode) o).children.get(i);
-    }
-
-    public int getChildCount(Object o) {
-        return ((ViewNode) o).children.size();
-    }
-
-    public boolean isLeaf(Object child) {
-        ViewNode node = (ViewNode) child;
-        return node.children == null || node.children.size() == 0;
-    }
-
-    public void valueForPathChanged(TreePath treePath, Object child) {
-    }
-
-    public int getIndexOfChild(Object parent, Object child) {
-        //noinspection SuspiciousMethodCalls
-        return ((ViewNode) parent).children.indexOf(child);
-    }
-
-    public void addTreeModelListener(TreeModelListener treeModelListener) {
-    }
-
-    public void removeTreeModelListener(TreeModelListener treeModelListener) {
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/IconLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/IconLoader.java
deleted file mode 100644
index ef73956..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/IconLoader.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.android.hierarchyviewer.ui.util;
-
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-import javax.imageio.ImageIO;
-import java.io.IOException;
-import java.awt.image.BufferedImage;
-import java.awt.Graphics;
-import java.awt.GraphicsEnvironment;
-import java.awt.GraphicsConfiguration;
-
-public class IconLoader {
-    public static Icon load(Class<?> klass, String path) {
-        try {
-            return new ImageIcon(ImageIO.read(klass.getResourceAsStream(path)));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    private static GraphicsConfiguration getGraphicsConfiguration() {
-        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
-        return environment.getDefaultScreenDevice().getDefaultConfiguration();
-    }
-
-    private static boolean isHeadless() {
-        return GraphicsEnvironment.isHeadless();
-    }
-
-    public static BufferedImage toCompatibleImage(BufferedImage image) {
-        if (isHeadless()) {
-            return image;
-        }
-
-        if (image.getColorModel().equals(
-                getGraphicsConfiguration().getColorModel())) {
-            return image;
-        }
-
-        BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(
-                    image.getWidth(), image.getHeight(), image.getTransparency());
-        Graphics g = compatibleImage.getGraphics();
-        g.drawImage(image, 0, 0, null);
-        g.dispose();
-
-        return compatibleImage;
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/PngFileFilter.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/PngFileFilter.java
deleted file mode 100644
index 5d6472d..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/PngFileFilter.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.android.hierarchyviewer.ui.util;
-
-import javax.swing.filechooser.FileFilter;
-import java.io.File;
-
-public class PngFileFilter extends FileFilter {
-    @Override
-    public boolean accept(File f) {
-        return f.isDirectory() || f.getName().toLowerCase().endsWith(".png");
-    }
-
-    @Override
-    public String getDescription() {
-        return "PNG Image (*.png)";
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/OS.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/OS.java
deleted file mode 100644
index fd619d6..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/OS.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.android.hierarchyviewer.util;
-
-public class OS {
-    private static boolean macOs;
-    private static boolean leopard;
-    private static boolean linux;
-    private static boolean windows;
-
-    static {
-        String osName = System.getProperty("os.name");
-        macOs = "Mac OS X".startsWith(osName);
-        linux = "Linux".startsWith(osName);
-        windows = "Windows".startsWith(osName);
-
-        String version = System.getProperty("os.version");
-        final String[] parts = version.split("\\.");
-        leopard = Integer.parseInt(parts[0]) >= 10 && Integer.parseInt(parts[1]) >= 5;
-    }
-
-    public static boolean isMacOsX() {
-        return macOs;
-    }
-
-    public static boolean isLeopardOrLater() {
-        return leopard;
-    }
-
-    public static boolean isLinux() {
-        return linux;
-    }
-
-    public static boolean isWindows() {
-        return windows;
-    }
-}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/WorkerThread.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/WorkerThread.java
deleted file mode 100644
index c714c1c..0000000
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/WorkerThread.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.android.hierarchyviewer.util;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Simple utility class used only to mark methods that are not executed on the UI thread
- * (or Event Dispatch Thread in Swing/AWT.) This annotation's sole purpose is to help
- * reading the source code. It has no additional effect.
- */
-@Target({ ElementType.METHOD })
-@Retention(RetentionPolicy.SOURCE)
-public @interface WorkerThread {
-}
diff --git a/tools/hierarchyviewer/src/resources/images/icon-graph-view-selected.png b/tools/hierarchyviewer/src/resources/images/icon-graph-view-selected.png
deleted file mode 100644
index 91f7119..0000000
--- a/tools/hierarchyviewer/src/resources/images/icon-graph-view-selected.png
+++ /dev/null
Binary files differ
diff --git a/tools/hierarchyviewer/src/resources/images/icon-graph-view.png b/tools/hierarchyviewer/src/resources/images/icon-graph-view.png
deleted file mode 100644
index 9a7f68b..0000000
--- a/tools/hierarchyviewer/src/resources/images/icon-graph-view.png
+++ /dev/null
Binary files differ
diff --git a/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view-selected.png b/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view-selected.png
deleted file mode 100644
index 1e44000..0000000
--- a/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view-selected.png
+++ /dev/null
Binary files differ
diff --git a/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view.png b/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view.png
deleted file mode 100644
index ec51cec..0000000
--- a/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view.png
+++ /dev/null
Binary files differ
diff --git a/tools/jarutils/.classpath b/tools/jarutils/.classpath
deleted file mode 100644
index fc17a43..0000000
--- a/tools/jarutils/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/jarutils/.gitignore b/tools/jarutils/.gitignore
deleted file mode 100644
index fe99505..0000000
--- a/tools/jarutils/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin
-
diff --git a/tools/jarutils/.project b/tools/jarutils/.project
deleted file mode 100644
index 3649e40..0000000
--- a/tools/jarutils/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>JarUtils</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/jarutils/Android.mk b/tools/jarutils/Android.mk
deleted file mode 100644
index 707614a..0000000
--- a/tools/jarutils/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-JARUTILS_LOCAL_DIR := $(call my-dir)
-include $(JARUTILS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/jarutils/src/Android.mk b/tools/jarutils/src/Android.mk
deleted file mode 100644
index 2248b7f..0000000
--- a/tools/jarutils/src/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := \
-	androidprefs
-
-LOCAL_MODULE := jarutils
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/jarutils/src/com/android/jarutils/DebugKeyProvider.java b/tools/jarutils/src/com/android/jarutils/DebugKeyProvider.java
deleted file mode 100644
index 6dc32ba..0000000
--- a/tools/jarutils/src/com/android/jarutils/DebugKeyProvider.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.android.jarutils;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.UnrecoverableEntryException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-
-/**
- * A provider of a dummy key to sign Android application for debugging purpose.
- * <p/>This provider uses a custom keystore to create and store a key with a known password.
- */
-public class DebugKeyProvider {
-    
-    public interface IKeyGenOutput {
-        public void out(String message);
-        public void err(String message);
-    }
-    
-    private static final String PASSWORD_STRING = "android";
-    private static final char[] PASSWORD_CHAR = PASSWORD_STRING.toCharArray();
-    private static final String DEBUG_ALIAS = "AndroidDebugKey";
-    
-    // Certificate CN value. This is a hard-coded value for the debug key.
-    // Android Market checks against this value in order to refuse applications signed with
-    // debug keys.
-    private static final String CERTIFICATE_DESC = "CN=Android Debug,O=Android,C=US";
-    
-    private KeyStore.PrivateKeyEntry mEntry;
-    
-    public static class KeytoolException extends Exception {
-        /** default serial uid */
-        private static final long serialVersionUID = 1L;
-        private String mJavaHome = null;
-        private String mCommandLine = null;
-        
-        KeytoolException(String message) {
-            super(message);
-        }
-
-        KeytoolException(String message, String javaHome, String commandLine) {
-            super(message);
-            
-            mJavaHome = javaHome;
-            mCommandLine = commandLine;
-        }
-        
-        public String getJavaHome() {
-            return mJavaHome;
-        }
-        
-        public String getCommandLine() {
-            return mCommandLine;
-        }
-    }
-    
-    /**
-     * Creates a provider using a keystore at the given location.
-     * <p/>The keystore, and a new random android debug key are created if they do not yet exist.
-     * <p/>Password for the store/key is <code>android</code>, and the key alias is
-     * <code>AndroidDebugKey</code>.
-     * @param osKeyStorePath the OS path to the keystore, or <code>null</code> if the default one
-     * is to be used.
-     * @param storeType an optional keystore type, or <code>null</code> if the default is to
-     * be used.
-     * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr
-     * of the keytool process call.
-     * @throws KeytoolException If the creation of the debug key failed.
-     * @throws AndroidLocationException 
-     */
-    public DebugKeyProvider(String osKeyStorePath, String storeType, IKeyGenOutput output)
-            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
-            UnrecoverableEntryException, IOException, KeytoolException, AndroidLocationException {
-        
-        if (osKeyStorePath == null) {
-            osKeyStorePath = getDefaultKeyStoreOsPath();
-        }
-        
-        if (loadKeyEntry(osKeyStorePath, storeType) == false) {
-            // create the store with the key
-            createNewStore(osKeyStorePath, storeType, output);
-        }
-    }
-
-    /**
-     * Returns the OS path to the default debug keystore.
-     * 
-     * @return The OS path to the default debug keystore.
-     * @throws KeytoolException
-     * @throws AndroidLocationException
-     */
-    public static String getDefaultKeyStoreOsPath()
-            throws KeytoolException, AndroidLocationException {
-        String folder = AndroidLocation.getFolder();
-        if (folder == null) {
-            throw new KeytoolException("Failed to get HOME directory!\n");
-        }
-        String osKeyStorePath = folder + "debug.keystore";
-
-        return osKeyStorePath;
-    }
-
-    /**
-     * Returns the debug {@link PrivateKey} to use to sign applications for debug purpose.
-     * @return the private key or <code>null</code> if its creation failed.
-     */
-    public PrivateKey getDebugKey() throws KeyStoreException, NoSuchAlgorithmException,
-            UnrecoverableKeyException, UnrecoverableEntryException {
-        if (mEntry != null) {
-            return mEntry.getPrivateKey();
-        }
-        
-        return null;
-    }
-
-    /**
-     * Returns the debug {@link Certificate} to use to sign applications for debug purpose.
-     * @return the certificate or <code>null</code> if its creation failed.
-     */
-    public Certificate getCertificate() throws KeyStoreException, NoSuchAlgorithmException,
-            UnrecoverableKeyException, UnrecoverableEntryException {
-        if (mEntry != null) {
-            return mEntry.getCertificate();
-        }
-
-        return null;
-    }
-    
-    /**
-     * Loads the debug key from the keystore.
-     * @param osKeyStorePath the OS path to the keystore.
-     * @param storeType an optional keystore type, or <code>null</code> if the default is to
-     * be used.
-     * @return <code>true</code> if success, <code>false</code> if the keystore does not exist.
-     */
-    private boolean loadKeyEntry(String osKeyStorePath, String storeType) throws KeyStoreException,
-            NoSuchAlgorithmException, CertificateException, IOException,
-            UnrecoverableEntryException {
-        try {
-            KeyStore keyStore = KeyStore.getInstance(
-                    storeType != null ? storeType : KeyStore.getDefaultType());
-            FileInputStream fis = new FileInputStream(osKeyStorePath);
-            keyStore.load(fis, PASSWORD_CHAR);
-            fis.close();
-            mEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
-                    DEBUG_ALIAS, new KeyStore.PasswordProtection(PASSWORD_CHAR));
-        } catch (FileNotFoundException e) {
-            return false;
-        }
-        
-        return true;
-    }
-
-    /**
-     * Creates a new store
-     * @param osKeyStorePath the location of the store
-     * @param storeType an optional keystore type, or <code>null</code> if the default is to
-     * be used.
-     * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr
-     * of the keytool process call.
-     * @throws KeyStoreException
-     * @throws NoSuchAlgorithmException
-     * @throws CertificateException
-     * @throws UnrecoverableEntryException
-     * @throws IOException
-     * @throws KeytoolException
-     */
-    private void createNewStore(String osKeyStorePath, String storeType, IKeyGenOutput output)
-            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
-            UnrecoverableEntryException, IOException, KeytoolException {
-        
-        if (KeystoreHelper.createNewStore(osKeyStorePath, storeType, PASSWORD_STRING, DEBUG_ALIAS,
-                PASSWORD_STRING, CERTIFICATE_DESC, 1 /* validity*/, output)) {
-            loadKeyEntry(osKeyStorePath, storeType);
-        }
-    }
-}
diff --git a/tools/jarutils/src/com/android/jarutils/JavaResourceFilter.java b/tools/jarutils/src/com/android/jarutils/JavaResourceFilter.java
deleted file mode 100644
index 8678510..0000000
--- a/tools/jarutils/src/com/android/jarutils/JavaResourceFilter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.android.jarutils;
-
-import com.android.jarutils.SignedJarBuilder.IZipEntryFilter;
-
-/**
- * A basic implementation of {@link IZipEntryFilter} to filter out anything that is not a
- * java resource.
- */
-public class JavaResourceFilter implements IZipEntryFilter {
-
-    public boolean checkEntry(String name) {
-        // split the path into segments.
-        String[] segments = name.split("/");
-
-        // empty path? skip to next entry.
-        if (segments.length == 0) {
-            return false;
-        }
-
-        // Check each folders to make sure they should be included.
-        // Folders like CVS, .svn, etc.. should already have been excluded from the
-        // jar file, but we need to exclude some other folder (like /META-INF) so
-        // we check anyway.
-        for (int i = 0 ; i < segments.length - 1; i++) {
-            if (checkFolderForPackaging(segments[i]) == false) {
-                return false;
-            }
-        }
-
-        // get the file name from the path
-        String fileName = segments[segments.length-1];
-
-        return checkFileForPackaging(fileName);
-    }
-
-    /**
-     * Checks whether a folder and its content is valid for packaging into the .apk as
-     * standard Java resource.
-     * @param folderName the name of the folder.
-     */
-    public static boolean checkFolderForPackaging(String folderName) {
-        return folderName.equals("CVS") == false &&
-            folderName.equals(".svn") == false &&
-            folderName.equals("SCCS") == false &&
-            folderName.equals("META-INF") == false &&
-            folderName.startsWith("_") == false;
-    }
-
-    /**
-     * Checks a file to make sure it should be packaged as standard resources.
-     * @param fileName the name of the file (including extension)
-     * @return true if the file should be packaged as standard java resources.
-     */
-    public static boolean checkFileForPackaging(String fileName) {
-        String[] fileSegments = fileName.split("\\.");
-        String fileExt = "";
-        if (fileSegments.length > 1) {
-            fileExt = fileSegments[fileSegments.length-1];
-        }
-
-        return checkFileForPackaging(fileName, fileExt);
-    }
-
-    /**
-     * Checks a file to make sure it should be packaged as standard resources.
-     * @param fileName the name of the file (including extension)
-     * @param extension the extension of the file (excluding '.')
-     * @return true if the file should be packaged as standard java resources.
-     */
-    public  static boolean checkFileForPackaging(String fileName, String extension) {
-        // Note: this method is used by com.android.ide.eclipse.adt.internal.build.ApkBuilder
-        if (fileName.charAt(0) == '.') { // ignore hidden files.
-            return false;
-        }
-
-        return "aidl".equalsIgnoreCase(extension) == false &&       // Aidl files
-            "java".equalsIgnoreCase(extension) == false &&          // Java files
-            "class".equalsIgnoreCase(extension) == false &&         // Java class files
-            "scc".equalsIgnoreCase(extension) == false &&           // VisualSourceSafe
-            "swp".equalsIgnoreCase(extension) == false &&           // vi swap file
-            "package.html".equalsIgnoreCase(fileName) == false &&   // Javadoc
-            "overview.html".equalsIgnoreCase(fileName) == false &&  // Javadoc
-            ".cvsignore".equalsIgnoreCase(fileName) == false &&     // CVS
-            ".DS_Store".equals(fileName) == false &&                // Mac resources
-            fileName.charAt(fileName.length()-1) != '~';            // Backup files
-    }
-}
diff --git a/tools/jarutils/src/com/android/jarutils/KeystoreHelper.java b/tools/jarutils/src/com/android/jarutils/KeystoreHelper.java
deleted file mode 100644
index c694684..0000000
--- a/tools/jarutils/src/com/android/jarutils/KeystoreHelper.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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.android.jarutils;
-
-import com.android.jarutils.DebugKeyProvider.IKeyGenOutput;
-import com.android.jarutils.DebugKeyProvider.KeytoolException;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableEntryException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-
-/**
- * A Helper to create new keystore/key.
- */
-public final class KeystoreHelper {
-
-    /**
-     * Creates a new store
-     * @param osKeyStorePath the location of the store
-     * @param storeType an optional keystore type, or <code>null</code> if the default is to
-     * be used.
-     * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr
-     * of the keytool process call.
-     * @throws KeyStoreException
-     * @throws NoSuchAlgorithmException
-     * @throws CertificateException
-     * @throws UnrecoverableEntryException
-     * @throws IOException
-     * @throws KeytoolException
-     */
-    public static boolean createNewStore(
-            String osKeyStorePath,
-            String storeType,
-            String storePassword,
-            String alias,
-            String keyPassword,
-            String description,
-            int validityYears,
-            IKeyGenOutput output)
-            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
-            UnrecoverableEntryException, IOException, KeytoolException {
-        
-        // get the executable name of keytool depending on the platform.
-        String os = System.getProperty("os.name");
-
-        String keytoolCommand;
-        if (os.startsWith("Windows")) {
-            keytoolCommand = "keytool.exe";
-        } else {
-            keytoolCommand = "keytool";
-        }
-
-        String javaHome = System.getProperty("java.home");
-
-        if (javaHome != null && javaHome.length() > 0) {
-            keytoolCommand = javaHome + File.separator + "bin" + File.separator + keytoolCommand; 
-        }
-        
-        // create the command line to call key tool to build the key with no user input.
-        ArrayList<String> commandList = new ArrayList<String>();
-        commandList.add(keytoolCommand);
-        commandList.add("-genkey");
-        commandList.add("-alias");
-        commandList.add(alias);
-        commandList.add("-keyalg");
-        commandList.add("RSA");
-        commandList.add("-dname");
-        commandList.add(description);
-        commandList.add("-validity");
-        commandList.add(Integer.toString(validityYears * 365));
-        commandList.add("-keypass");
-        commandList.add(keyPassword);
-        commandList.add("-keystore");
-        commandList.add(osKeyStorePath);
-        commandList.add("-storepass");
-        commandList.add(storePassword);
-        if (storeType != null) {
-            commandList.add("-storetype");
-            commandList.add(storeType);
-        }
-
-        String[] commandArray = commandList.toArray(new String[commandList.size()]);
-
-        // launch the command line process
-        int result = 0;
-        try {
-            result = grabProcessOutput(Runtime.getRuntime().exec(commandArray), output);
-        } catch (Exception e) {
-            // create the command line as one string
-            StringBuilder builder = new StringBuilder();
-            boolean firstArg = true;
-            for (String arg : commandArray) {
-                boolean hasSpace = arg.indexOf(' ') != -1;
-                
-                if (firstArg == true) {
-                    firstArg = false;
-                } else {
-                    builder.append(' ');
-                }
-                
-                if (hasSpace) {
-                    builder.append('"');
-                }
-                
-                builder.append(arg);
-
-                if (hasSpace) {
-                    builder.append('"');
-                }
-            }
-            
-            throw new KeytoolException("Failed to create key: " + e.getMessage(),
-                    javaHome, builder.toString());
-        }
-        
-        if (result != 0) {
-            return false;
-        }
-        
-        return true;
-    }
-    
-    /**
-     * Get the stderr/stdout outputs of a process and return when the process is done.
-     * Both <b>must</b> be read or the process will block on windows.
-     * @param process The process to get the ouput from
-     * @return the process return code.
-     * @throws InterruptedException
-     */
-    private static int grabProcessOutput(final Process process, final IKeyGenOutput output) {
-        // read the lines as they come. if null is returned, it's
-        // because the process finished
-        Thread t1 = new Thread("") {
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            if (output != null) {
-                                output.err(line);
-                            } else {
-                                System.err.println(line);
-                            }
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        Thread t2 = new Thread("") {
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            if (output != null) {
-                                output.out(line);
-                            } else {
-                                System.out.println(line);
-                            }
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        t1.start();
-        t2.start();
-
-        // it looks like on windows process#waitFor() can return
-        // before the thread have filled the arrays, so we wait for both threads and the
-        // process itself.
-        try {
-            t1.join();
-        } catch (InterruptedException e) {
-        }
-        try {
-            t2.join();
-        } catch (InterruptedException e) {
-        }
-
-        // get the return code from the process
-        try {
-            return process.waitFor();
-        } catch (InterruptedException e) {
-            // since we're waiting for the output thread above, we should never actually wait
-            // on the process to end, since it'll be done by the time we call waitFor()
-            return 0;
-        }
-    }
-}
diff --git a/tools/jarutils/src/com/android/jarutils/SignedJarBuilder.java b/tools/jarutils/src/com/android/jarutils/SignedJarBuilder.java
deleted file mode 100644
index 335ab7d..0000000
--- a/tools/jarutils/src/com/android/jarutils/SignedJarBuilder.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * 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.android.jarutils;
-
-import sun.misc.BASE64Encoder;
-import sun.security.pkcs.ContentInfo;
-import sun.security.pkcs.PKCS7;
-import sun.security.pkcs.SignerInfo;
-import sun.security.x509.AlgorithmId;
-import sun.security.x509.X500Name;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.security.DigestOutputStream;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.X509Certificate;
-import java.util.Map;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-/**
- * A Jar file builder with signature support.
- */
-public class SignedJarBuilder {
-    private static final String DIGEST_ALGORITHM = "SHA1";
-    private static final String DIGEST_ATTR = "SHA1-Digest";
-    private static final String DIGEST_MANIFEST_ATTR = "SHA1-Digest-Manifest";
-
-    /** Write to another stream and also feed it to the Signature object. */
-    private static class SignatureOutputStream extends FilterOutputStream {
-        private Signature mSignature;
-
-        public SignatureOutputStream(OutputStream out, Signature sig) {
-            super(out);
-            mSignature = sig;
-        }
-
-        @Override
-        public void write(int b) throws IOException {
-            try {
-                mSignature.update((byte) b);
-            } catch (SignatureException e) {
-                throw new IOException("SignatureException: " + e);
-            }
-            super.write(b);
-        }
-
-        @Override
-        public void write(byte[] b, int off, int len) throws IOException {
-            try {
-                mSignature.update(b, off, len);
-            } catch (SignatureException e) {
-                throw new IOException("SignatureException: " + e);
-            }
-            super.write(b, off, len);
-        }
-    }
-
-    private JarOutputStream mOutputJar;
-    private PrivateKey mKey;
-    private X509Certificate mCertificate;
-    private Manifest mManifest;
-    private BASE64Encoder mBase64Encoder;
-    private MessageDigest mMessageDigest;
-
-    private byte[] mBuffer = new byte[4096];
-
-    /**
-     * Classes which implement this interface provides a method to check whether a file should
-     * be added to a Jar file.
-     */
-    public interface IZipEntryFilter {
-        /**
-         * Checks a file for inclusion in a Jar archive.
-         * @param name the archive file path of the entry
-         * @return <code>true</code> if the file should be included.
-         */
-        public boolean checkEntry(String name);
-    }
-    
-    /**
-     * Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
-     * <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
-     * the archive will not be signed.
-     * @param out the {@link OutputStream} where to write the Jar archive.
-     * @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
-     * @param certificate the {@link X509Certificate} used to sign the archive, or
-     * <code>null</code>.
-     * @throws IOException
-     * @throws NoSuchAlgorithmException
-     */
-    public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate)
-            throws IOException, NoSuchAlgorithmException {
-        mOutputJar = new JarOutputStream(out);
-        mOutputJar.setLevel(9);
-        mKey = key;
-        mCertificate = certificate;
-        
-        if (mKey != null && mCertificate != null) {
-            mManifest = new Manifest();
-            Attributes main = mManifest.getMainAttributes();
-            main.putValue("Manifest-Version", "1.0");
-            main.putValue("Created-By", "1.0 (Android)");
-    
-            mBase64Encoder = new BASE64Encoder();
-            mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
-        }
-    }
-    
-    /**
-     * Writes a new {@link File} into the archive.
-     * @param inputFile the {@link File} to write.
-     * @param jarPath the filepath inside the archive.
-     * @throws IOException
-     */
-    public void writeFile(File inputFile, String jarPath) throws IOException {
-        // Get an input stream on the file.
-        FileInputStream fis = new FileInputStream(inputFile);
-        try {
-            
-            // create the zip entry
-            JarEntry entry = new JarEntry(jarPath);
-            entry.setTime(inputFile.lastModified());
-
-            writeEntry(fis, entry);
-        } finally {
-            // close the file stream used to read the file
-            fis.close();
-        }
-    }
-
-    /**
-     * Copies the content of a Jar/Zip archive into the receiver archive.
-     * <p/>An optional {@link IZipEntryFilter} allows to selectively choose which files
-     * to copy over.
-     * @param input the {@link InputStream} for the Jar/Zip to copy.
-     * @param filter the filter or <code>null</code>
-     * @throws IOException
-     */
-    public void writeZip(InputStream input, IZipEntryFilter filter) throws IOException {
-        ZipInputStream zis = new ZipInputStream(input);
-
-        try {
-            // loop on the entries of the intermediary package and put them in the final package.
-            ZipEntry entry;
-            while ((entry = zis.getNextEntry()) != null) {
-                String name = entry.getName();
-                
-                // do not take directories or anything inside a potential META-INF folder.
-                if (entry.isDirectory() || name.startsWith("META-INF/")) {
-                    continue;
-                }
-    
-                // if we have a filter, we check the entry against it
-                if (filter != null && filter.checkEntry(name) == false) {
-                    continue;
-                }
-    
-                JarEntry newEntry;
-    
-                // Preserve the STORED method of the input entry.
-                if (entry.getMethod() == JarEntry.STORED) {
-                    newEntry = new JarEntry(entry);
-                } else {
-                    // Create a new entry so that the compressed len is recomputed.
-                    newEntry = new JarEntry(name);
-                }
-                
-                writeEntry(zis, newEntry);
-    
-                zis.closeEntry();
-            }
-        } finally {
-            zis.close();
-        }
-    }
-
-    /**
-     * Closes the Jar archive by creating the manifest, and signing the archive. 
-     * @throws IOException
-     * @throws GeneralSecurityException
-     */
-    public void close() throws IOException, GeneralSecurityException {
-        if (mManifest != null) {
-            // write the manifest to the jar file
-            mOutputJar.putNextEntry(new JarEntry(JarFile.MANIFEST_NAME));
-            mManifest.write(mOutputJar);
-            
-            // CERT.SF
-            Signature signature = Signature.getInstance("SHA1with" + mKey.getAlgorithm());
-            signature.initSign(mKey);
-            mOutputJar.putNextEntry(new JarEntry("META-INF/CERT.SF"));
-            writeSignatureFile(new SignatureOutputStream(mOutputJar, signature));
-    
-            // CERT.*
-            mOutputJar.putNextEntry(new JarEntry("META-INF/CERT." + mKey.getAlgorithm()));
-            writeSignatureBlock(signature, mCertificate, mKey);
-        }
-        
-        mOutputJar.close();
-    }
-    
-    /**
-     * Adds an entry to the output jar, and write its content from the {@link InputStream}
-     * @param input The input stream from where to write the entry content.
-     * @param entry the entry to write in the jar.
-     * @throws IOException
-     */
-    private void writeEntry(InputStream input, JarEntry entry) throws IOException {
-        // add the entry to the jar archive
-        mOutputJar.putNextEntry(entry);
-
-        // read the content of the entry from the input stream, and write it into the archive.
-        int count; 
-        while ((count = input.read(mBuffer)) != -1) {
-            mOutputJar.write(mBuffer, 0, count);
-            
-            // update the digest
-            if (mMessageDigest != null) {
-                mMessageDigest.update(mBuffer, 0, count);
-            }
-        }
-
-        // close the entry for this file
-        mOutputJar.closeEntry();
-        
-        if (mManifest != null) {
-            // update the manifest for this entry.
-            Attributes attr = mManifest.getAttributes(entry.getName());
-            if (attr == null) {
-                attr = new Attributes();
-                mManifest.getEntries().put(entry.getName(), attr);
-            }
-            attr.putValue(DIGEST_ATTR, mBase64Encoder.encode(mMessageDigest.digest()));
-        }
-    }
-    
-    /** Writes a .SF file with a digest to the manifest. */
-    private void writeSignatureFile(OutputStream out)
-            throws IOException, GeneralSecurityException {
-        Manifest sf = new Manifest();
-        Attributes main = sf.getMainAttributes();
-        main.putValue("Signature-Version", "1.0");
-        main.putValue("Created-By", "1.0 (Android)");
-
-        BASE64Encoder base64 = new BASE64Encoder();
-        MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM);
-        PrintStream print = new PrintStream(
-                new DigestOutputStream(new ByteArrayOutputStream(), md),
-                true, "UTF-8");
-
-        // Digest of the entire manifest
-        mManifest.write(print);
-        print.flush();
-        main.putValue(DIGEST_MANIFEST_ATTR, base64.encode(md.digest()));
-
-        Map<String, Attributes> entries = mManifest.getEntries();
-        for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
-            // Digest of the manifest stanza for this entry.
-            print.print("Name: " + entry.getKey() + "\r\n");
-            for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
-                print.print(att.getKey() + ": " + att.getValue() + "\r\n");
-            }
-            print.print("\r\n");
-            print.flush();
-
-            Attributes sfAttr = new Attributes();
-            sfAttr.putValue(DIGEST_ATTR, base64.encode(md.digest()));
-            sf.getEntries().put(entry.getKey(), sfAttr);
-        }
-
-        sf.write(out);
-    }
-
-    /** Write the certificate file with a digital signature. */
-    private void writeSignatureBlock(Signature signature, X509Certificate publicKey,
-            PrivateKey privateKey)
-            throws IOException, GeneralSecurityException {
-        SignerInfo signerInfo = new SignerInfo(
-                new X500Name(publicKey.getIssuerX500Principal().getName()),
-                publicKey.getSerialNumber(),
-                AlgorithmId.get(DIGEST_ALGORITHM),
-                AlgorithmId.get(privateKey.getAlgorithm()),
-                signature.sign());
-
-        PKCS7 pkcs7 = new PKCS7(
-                new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) },
-                new ContentInfo(ContentInfo.DATA_OID, null),
-                new X509Certificate[] { publicKey },
-                new SignerInfo[] { signerInfo });
-
-        pkcs7.encodeSignedData(mOutputJar);
-    }
-}
diff --git a/tools/layoutlib_utils/.classpath b/tools/layoutlib_utils/.classpath
deleted file mode 100644
index 0321c43..0000000
--- a/tools/layoutlib_utils/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib_utils/.gitignore b/tools/layoutlib_utils/.gitignore
deleted file mode 100644
index fe99505..0000000
--- a/tools/layoutlib_utils/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin
-
diff --git a/tools/layoutlib_utils/.project b/tools/layoutlib_utils/.project
deleted file mode 100644
index b427809..0000000
--- a/tools/layoutlib_utils/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_utils</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib_utils/Android.mk b/tools/layoutlib_utils/Android.mk
deleted file mode 100644
index 50eb0ff..0000000
--- a/tools/layoutlib_utils/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_JAVA_LIBRARIES := \
-	layoutlib_api
-
-LOCAL_MODULE := layoutlib_utils
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/layoutlib_utils/src/com/android/layoutlib/utils/DensityBasedResourceValue.java b/tools/layoutlib_utils/src/com/android/layoutlib/utils/DensityBasedResourceValue.java
deleted file mode 100644
index 59de463..0000000
--- a/tools/layoutlib_utils/src/com/android/layoutlib/utils/DensityBasedResourceValue.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.android.layoutlib.utils;
-
-import com.android.layoutlib.api.IDensityBasedResourceValue;
-
-public class DensityBasedResourceValue extends ResourceValue implements IDensityBasedResourceValue {
-
-    private Density mDensity;
-
-    public DensityBasedResourceValue(String type, String name, String value, Density density,
-            boolean isFramework) {
-        super(type, name, value, isFramework);
-        mDensity = density;
-    }
-
-    public Density getDensity() {
-        return mDensity;
-    }
-}
diff --git a/tools/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java b/tools/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java
deleted file mode 100644
index 98b4de6..0000000
--- a/tools/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.android.layoutlib.utils;
-
-import com.android.layoutlib.api.IResourceValue;
-
-public class ResourceValue implements IResourceValue {
-    private final String mType;
-    private final String mName;
-    private String mValue = null;
-    private final boolean mIsFramwork;
-    
-    public ResourceValue(String type, String name, boolean isFramwork) {
-        mType = type;
-        mName = name;
-        mIsFramwork = isFramwork;
-    }
-
-    public ResourceValue(String type, String name, String value, boolean isFramework) {
-        mType = type;
-        mName = name;
-        mValue = value;
-        mIsFramwork = isFramework;
-    }
-
-    public String getType() {
-        return mType;
-    }
-
-    public final String getName() {
-        return mName;
-    }
-    
-    public final String getValue() {
-        return mValue;
-    }
-    
-    public final void setValue(String value) {
-        mValue = value;
-    }
-    
-    public void replaceWith(ResourceValue value) {
-        mValue = value.mValue;
-    }
-
-    public boolean isFramework() {
-        return mIsFramwork;
-    }
-}
diff --git a/tools/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java b/tools/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java
deleted file mode 100644
index a32ac1b..0000000
--- a/tools/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.android.layoutlib.utils;
-
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IStyleResourceValue;
-
-import java.util.HashMap;
-
-public final class StyleResourceValue extends ResourceValue implements IStyleResourceValue {
-
-    private String mParentStyle = null;
-    private HashMap<String, IResourceValue> mItems = new HashMap<String, IResourceValue>();
-
-    public StyleResourceValue(String type, String name, boolean isFramework) {
-        super(type, name, isFramework);
-    }
-
-    public StyleResourceValue(String type, String name, String parentStyle, boolean isFramework) {
-        super(type, name, isFramework);
-        mParentStyle = parentStyle;
-    }
-
-    public String getParentStyle() {
-        return mParentStyle;
-    }
-    
-    public IResourceValue findItem(String name) {
-        return mItems.get(name);
-    }
-    
-    public void addItem(IResourceValue value) {
-        mItems.put(value.getName(), value);
-    }
-    
-    @Override
-    public void replaceWith(ResourceValue value) {
-        super.replaceWith(value);
-        
-        if (value instanceof StyleResourceValue) {
-            mItems.clear();
-            mItems.putAll(((StyleResourceValue)value).mItems);
-        }
-    }
-
-}
diff --git a/tools/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java b/tools/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java
deleted file mode 100644
index 4682d90..0000000
--- a/tools/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.android.layoutlib.utils;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * SAX handler to parser value resource files.
- */
-public final class ValueResourceParser extends DefaultHandler {
-
-    // TODO: reuse definitions from somewhere else.
-    private final static String NODE_RESOURCES = "resources";
-    private final static String NODE_ITEM = "item";
-    private final static String ATTR_NAME = "name";
-    private final static String ATTR_TYPE = "type";
-    private final static String ATTR_PARENT = "parent";
-    
-    // Resource type definition
-    private final static String RES_STYLE = "style";
-    private final static String RES_ATTR = "attr";
-    
-    private final static String DEFAULT_NS_PREFIX = "android:";
-    private final static int DEFAULT_NS_PREFIX_LEN = DEFAULT_NS_PREFIX.length();
-    
-    public interface IValueResourceRepository {
-        void addResourceValue(String resType, ResourceValue value);
-    }
-    
-    private boolean inResources = false;
-    private int mDepth = 0;
-    private StyleResourceValue mCurrentStyle = null;
-    private ResourceValue mCurrentValue = null;
-    private IValueResourceRepository mRepository;
-    private final boolean mIsFramework;
-    
-    public ValueResourceParser(IValueResourceRepository repository, boolean isFramework) {
-        mRepository = repository;
-        mIsFramework = isFramework;
-    }
-
-    @Override
-    public void endElement(String uri, String localName, String qName) throws SAXException {
-        if (mCurrentValue != null) {
-            mCurrentValue.setValue(trimXmlWhitespaces(mCurrentValue.getValue()));
-        }
-        
-        if (inResources && qName.equals(NODE_RESOURCES)) {
-            inResources = false;
-        } else if (mDepth == 2) {
-            mCurrentValue = null;
-            mCurrentStyle = null;
-        } else if (mDepth == 3) {
-            mCurrentValue = null;
-        }
-        
-        mDepth--;
-        super.endElement(uri, localName, qName);
-    }
-
-    @Override
-    public void startElement(String uri, String localName, String qName, Attributes attributes)
-            throws SAXException {
-        try {
-            mDepth++;
-            if (inResources == false && mDepth == 1) {
-                if (qName.equals(NODE_RESOURCES)) {
-                    inResources = true;
-                }
-            } else if (mDepth == 2 && inResources == true) {
-                String type;
-                
-                // if the node is <item>, we get the type from the attribute "type"
-                if (NODE_ITEM.equals(qName)) {
-                    type = attributes.getValue(ATTR_TYPE);
-                } else {
-                    // the type is the name of the node.
-                    type = qName;
-                }
-
-                if (type != null) {
-                    if (RES_ATTR.equals(type) == false) {
-                        // get the resource name
-                        String name = attributes.getValue(ATTR_NAME);
-                        if (name != null) {
-                            if (RES_STYLE.equals(type)) {
-                                String parent = attributes.getValue(ATTR_PARENT);
-                                mCurrentStyle = new StyleResourceValue(type, name, parent, mIsFramework);
-                                mRepository.addResourceValue(type, mCurrentStyle);
-                            } else {
-                                mCurrentValue = new ResourceValue(type, name, mIsFramework);
-                                mRepository.addResourceValue(type, mCurrentValue);
-                            }
-                        }
-                    }
-                }
-            } else if (mDepth == 3 && mCurrentStyle != null) {
-                // get the resource name
-                String name = attributes.getValue(ATTR_NAME);
-                if (name != null) {
-                    // the name can, in some cases, contain a prefix! we remove it.
-                    if (name.startsWith(DEFAULT_NS_PREFIX)) {
-                        name = name.substring(DEFAULT_NS_PREFIX_LEN);
-                    }
-    
-                    mCurrentValue = new ResourceValue(null, name, mIsFramework);
-                    mCurrentStyle.addItem(mCurrentValue);
-                }
-            }
-        } finally {
-            super.startElement(uri, localName, qName, attributes);
-        }
-    }
-    
-    @Override
-    public void characters(char[] ch, int start, int length) throws SAXException {
-        if (mCurrentValue != null) {
-            String value = mCurrentValue.getValue();
-            if (value == null) {
-                mCurrentValue.setValue(new String(ch, start, length));
-            } else {
-                mCurrentValue.setValue(value + new String(ch, start, length));
-            }
-        }
-    }
-    
-    public static String trimXmlWhitespaces(String value) {
-        if (value == null) {
-            return null;
-        }
-
-        // look for carriage return and replace all whitespace around it by just 1 space.
-        int index;
-        
-        while ((index = value.indexOf('\n')) != -1) {
-            // look for whitespace on each side
-            int left = index - 1;
-            while (left >= 0) {
-                if (Character.isWhitespace(value.charAt(left))) {
-                    left--;
-                } else {
-                    break;
-                }
-            }
-            
-            int right = index + 1;
-            int count = value.length();
-            while (right < count) {
-                if (Character.isWhitespace(value.charAt(right))) {
-                    right++;
-                } else {
-                    break;
-                }
-            }
-            
-            // remove all between left and right (non inclusive) and replace by a single space.
-            String leftString = null;
-            if (left >= 0) {
-                leftString = value.substring(0, left + 1);
-            }
-            String rightString = null;
-            if (right < count) {
-                rightString = value.substring(right);
-            }
-            
-            if (leftString != null) {
-                value = leftString;
-                if (rightString != null) {
-                    value += " " + rightString;
-                }
-            } else {
-                value = rightString != null ? rightString : "";
-            }
-        }
-        
-        // now we un-escape the string
-        int length = value.length();
-        char[] buffer = value.toCharArray();
-        
-        for (int i = 0 ; i < length ; i++) {
-            if (buffer[i] == '\\' && i + 1 < length) {
-                if (buffer[i+1] == 'u') {
-                    if (i + 5 < length) {
-                        // this is unicode char \u1234
-                        int unicodeChar = Integer.parseInt(new String(buffer, i+2, 4), 16);
-                        
-                        // put the unicode char at the location of the \
-                        buffer[i] = (char)unicodeChar;
-    
-                        // offset the rest of the buffer since we go from 6 to 1 char
-                        if (i + 6 < buffer.length) {
-                            System.arraycopy(buffer, i+6, buffer, i+1, length - i - 6);
-                        }
-                        length -= 5;
-                    }
-                } else {
-                    if (buffer[i+1] == 'n') {
-                        // replace the 'n' char with \n
-                        buffer[i+1] = '\n';
-                    }
-                    
-                    // offset the buffer to erase the \
-                    System.arraycopy(buffer, i+1, buffer, i, length - i - 1);
-                    length--;
-                }
-            }
-        }
-        
-        return new String(buffer, 0, length);
-    }
-}
diff --git a/tools/layoutopt/Android.mk b/tools/layoutopt/Android.mk
deleted file mode 100644
index 43b2dcf..0000000
--- a/tools/layoutopt/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-LAYOUTOPT_LOCAL_DIR := $(call my-dir)
-include $(LAYOUTOPT_LOCAL_DIR)/libs/Android.mk
-include $(LAYOUTOPT_LOCAL_DIR)/app/Android.mk
diff --git a/tools/layoutopt/MODULE_LICENSE_APACHE2 b/tools/layoutopt/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/layoutopt/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/layoutopt/app/Android.mk b/tools/layoutopt/app/Android.mk
deleted file mode 100644
index 3fae340..0000000
--- a/tools/layoutopt/app/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-LAYOUTOPT_LOCAL_DIR := $(call my-dir)
-include $(LAYOUTOPT_LOCAL_DIR)/etc/Android.mk
-include $(LAYOUTOPT_LOCAL_DIR)/src/Android.mk
diff --git a/tools/layoutopt/app/README b/tools/layoutopt/app/README
deleted file mode 100644
index c118022..0000000
--- a/tools/layoutopt/app/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Layout optimizer.
-
-Simple command line front end for the uix library.
\ No newline at end of file
diff --git a/tools/layoutopt/app/etc/Android.mk b/tools/layoutopt/app/etc/Android.mk
deleted file mode 100644
index ae08f9d..0000000
--- a/tools/layoutopt/app/etc/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := layoutopt
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/layoutopt/app/etc/layoutopt b/tools/layoutopt/app/etc/layoutopt
deleted file mode 100755
index 22ebb67..0000000
--- a/tools/layoutopt/app/etc/layoutopt
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-# Copyright 2009, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=layoutopt.jar
-frameworkdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Djava.ext.dirs="$frameworkdir" -jar "$jarpath" "$@"
diff --git a/tools/layoutopt/app/etc/layoutopt.bat b/tools/layoutopt/app/etc/layoutopt.bat
deleted file mode 100755
index e1eb7b3..0000000
--- a/tools/layoutopt/app/etc/layoutopt.bat
+++ /dev/null
@@ -1,48 +0,0 @@
-@echo off
-rem Copyright (C) 2009 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-set jarfile=layoutopt.jar
-set frameworkdir=
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=lib\
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=..\framework\
-
-:JarFileOk
-
-if debug NEQ "%1" goto NoDebug
-    set java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
-    shift 1
-:NoDebug
-
-set jarpath=%frameworkdir%%jarfile%
-
-set javaextdirs=%swt_path%;%frameworkdir%
-
-call java %java_debug% -Djava.ext.dirs=%javaextdirs% %jarpath% %*
-
diff --git a/tools/layoutopt/app/etc/manifest.txt b/tools/layoutopt/app/etc/manifest.txt
deleted file mode 100644
index 5d0afdf..0000000
--- a/tools/layoutopt/app/etc/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Main-Class: com.android.layoutopt.cli.Main
-Class-Path: groovy-all-1.6.5.jar
diff --git a/tools/layoutopt/app/src/Android.mk b/tools/layoutopt/app/src/Android.mk
deleted file mode 100644
index 131addd..0000000
--- a/tools/layoutopt/app/src/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	uix
-LOCAL_MODULE := layoutopt
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/layoutopt/app/src/com/android/layoutopt/cli/Main.java b/tools/layoutopt/app/src/com/android/layoutopt/cli/Main.java
deleted file mode 100644
index 0275aa0..0000000
--- a/tools/layoutopt/app/src/com/android/layoutopt/cli/Main.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.cli;
-
-import com.android.layoutopt.uix.LayoutAnalyzer;
-import com.android.layoutopt.uix.LayoutAnalysis;
-
-import java.io.File;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Command line utility for the uix library.
- *
- * This is a simple CLI front-end for the uix library, used to
- * analyze and optimize Android layout files.
- */
-public class Main {
-    /**
-     * Main entry point of the application.
-     *
-     * @param args One mandatory parameter, a path (absolute or relative)
-     *             to an Android XML layout file
-     */
-    public static void main(String[] args) {
-        Parameters p = checkParameters(args);
-        if (!p.valid) {
-            displayHelpMessage();
-            exit();
-        }
-
-        analyzeFiles(p.files);
-    }
-
-    private static void analyzeFiles(File[] files) {
-        LayoutAnalyzer analyzer = new LayoutAnalyzer();
-        for (File file : files) {
-            if (file.isFile() && file.getName().endsWith(".xml")) {
-                analyze(analyzer, file);
-            } else if (file.isDirectory()) {
-                analyzeFiles(file.listFiles());
-            }
-        }
-    }
-
-    private static void analyze(LayoutAnalyzer analyzer, File file) {
-        LayoutAnalysis analysis = analyzer.analyze(file);
-        System.out.println(analysis.getName());
-        for (LayoutAnalysis.Issue issue : analysis.getIssues()) {
-            System.out.print(String.format("\t%d:%d ", issue.getStartLine(), issue.getEndLine()));
-            System.out.println(issue.getDescription());
-        }
-    }
-
-    /**
-     * Exits the tool.
-     */
-    private static void exit() {
-        System.exit(0);
-    }
-
-    /**
-     * Displays this tool's help message on the standard output.
-     */
-    private static void displayHelpMessage() {
-        System.out.println("usage: layoutopt <directories/files to analyze>");
-    }
-
-    /**
-     * Builds a valid Parameters object. Parses the paramters if necessary
-     * and checks for errors.
-     *
-     * @param args The parameters passed from the CLI.
-     */
-    private static Parameters checkParameters(String[] args) {
-        Parameters p = new Parameters();
-
-        if (args.length < 1) {
-            p.valid = false;
-        } else {
-            List<File> files = new ArrayList<File>();
-            for (String path : args) {
-                File file = new File(path);
-                if (file.exists() && (file.isDirectory() || file.getName().endsWith(".xml"))) {
-                    files.add(file);
-                }
-            }
-            p.files = files.toArray(new File[files.size()]);
-            p.valid = true;
-        }
-
-        return p;
-    }
-
-    /**
-     * Parameters parsed from the CLI.
-     */
-    private static class Parameters {
-        /**
-         * True if this list of parameters is valid, false otherwise.
-         */
-        boolean valid;
-
-        /**
-         * Paths (absolute or relative) to the files to be analyzed.
-         */
-        File[] files;
-    }
-}
diff --git a/tools/layoutopt/libs/Android.mk b/tools/layoutopt/libs/Android.mk
deleted file mode 100644
index 058299a..0000000
--- a/tools/layoutopt/libs/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-UIX_LOCAL_DIR := $(call my-dir)
-include $(UIX_LOCAL_DIR)/uix/Android.mk
-
diff --git a/tools/layoutopt/libs/uix/Android.mk b/tools/layoutopt/libs/uix/Android.mk
deleted file mode 100644
index 8344e57..0000000
--- a/tools/layoutopt/libs/uix/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-UIX_LOCAL_DIR := $(call my-dir)
-include $(UIX_LOCAL_DIR)/src/Android.mk
diff --git a/tools/layoutopt/libs/uix/src/Android.mk b/tools/layoutopt/libs/uix/src/Android.mk
deleted file mode 100644
index 65abcbc..0000000
--- a/tools/layoutopt/libs/uix/src/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_MODULE := uix
-LOCAL_JAVA_LIBRARIES := \
-	groovy-all-1.6.5
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/LayoutAnalysis.java b/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/LayoutAnalysis.java
deleted file mode 100644
index bc6f0b6..0000000
--- a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/LayoutAnalysis.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.uix;
-
-import org.w3c.dom.Node;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import com.android.layoutopt.uix.groovy.LayoutAnalysisCategory;
-
-/**
- * Contains the results of a layout analysis. Instances of this class are
- * generated by {@link com.android.layoutopt.uix.LayoutAnalyzer}.
- *
- * @see com.android.layoutopt.uix.LayoutAnalyzer
- */
-public class LayoutAnalysis {
-    /**
-     * Default layout analysis used to describe a problem with the
-     * analysis process.
-     */
-    static final LayoutAnalysis ERROR = new LayoutAnalysis("");
-    static {
-        ERROR.mAnalyzed = false;
-        ERROR.addIssue("The layout could not be analyzed. Check if you specified a valid "
-                + "XML layout, if the specified file exists, etc.");
-    }
-
-    private final List<Issue> mIssues = new ArrayList<Issue>();
-    private String mName;
-    private boolean mAnalyzed;
-    private Node mNode;
-
-    /**
-     * Creates a new analysis. An analysis is always considered invalid by default.
-     *
-     * @see #validate()
-     * @see #isValid() 
-     */
-    LayoutAnalysis(String name) {
-        mName = name;
-    }
-
-    /**
-     * Returns the name of this analysis.
-     */
-    public String getName() {
-        return mName;
-    }
-
-    void setName(String name) {
-        mName = name;
-    }
-    
-    /**
-     * Adds an issue to the layout analysis.
-     *
-     * @param issue The issue to add.
-     */
-    public void addIssue(Issue issue) {
-        mIssues.add(issue);
-    }
-
-    /**
-     * Adds an issue to the layout analysis.
-     *
-     * @param description Description of the issue.
-     */
-    public void addIssue(String description) {
-        mIssues.add(new Issue(mNode, description));
-    }
-
-    /**
-     * Adds an issue to the layout analysis.
-     *
-     * @param node The node containing the issue.
-     * @param description Description of the issue.
-     */
-    public void addIssue(Node node, String description) {
-        mIssues.add(new Issue(node, description));
-    }
-
-    /**
-     * Returns the list of issues found during the analysis.
-     *
-     * @return A non-null array of {@link com.android.layoutopt.uix.LayoutAnalysis.Issue}.
-     */
-    public Issue[] getIssues() {
-        return mIssues.toArray(new Issue[mIssues.size()]);
-    }
-
-    /**
-     * Indicates whether the layout was analyzed. If this method returns false,
-     * a probleme occured during the analysis (missing file, invalid document, etc.)
-     *
-     * @return True if the layout was analyzed, false otherwise.
-     */
-    public boolean isValid() {
-        return mAnalyzed;
-    }
-
-    /**
-     * Validates the analysis. This must be call before this analysis can
-     * be considered valid. Calling this method resets the current node to null.
-     * 
-     * @see #setCurrentNode(org.w3c.dom.Node) 
-     */
-    void validate() {
-        mAnalyzed = true;
-        mNode = null;
-    }
-
-    /**
-     * Sets the current node to be automatically added to created issues.
-     * 
-     * @param node An XML node.
-     */
-    void setCurrentNode(Node node) {
-        mNode = node;
-    }
-
-    /**
-     * Represents an issue discovered during the analysis process.
-     * An issue provides a human-readable description as well as optional solutions.
-     */
-    public static class Issue {
-        private final String mDescription;
-        private final Node mNode;
-
-        /**
-         * Creates a new issue with the specified description.
-         * 
-         * @param description The description of the issue.
-         */
-        public Issue(String description) {
-            mNode = null;
-            if (description == null) {
-                throw new IllegalArgumentException("The description must be non-null");
-            }
-            mDescription = description;
-        }
-
-        /**
-         * Creates a new issue with the specified description.
-         * 
-         * @param node The node in which the issue was found.
-         * @param description The description of the issue.
-         */
-        public Issue(Node node, String description) {
-            mNode = node;
-            if (description == null) {
-                throw new IllegalArgumentException("The description must be non-null");
-            }
-            mDescription = description;
-        }
-
-        /**
-         * Describes this issue to the user.
-         *
-         * @return A String describing the issue, always non-null.
-         */
-        public String getDescription() {
-            return mDescription;
-        }
-
-
-        /**
-         * Returns the start line of this node.
-         *
-         * @return The start line or -1 if the line is unknown.
-         */
-        public int getStartLine() {
-            return LayoutAnalysisCategory.getStartLine(mNode);
-        }
-
-        /**
-         * Returns the end line of this node.
-         *
-         * @return The end line or -1 if the line is unknown.
-         */
-        public int getEndLine() {
-            return LayoutAnalysisCategory.getEndLine(mNode);
-        }
-    }
-}
diff --git a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/LayoutAnalyzer.java b/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/LayoutAnalyzer.java
deleted file mode 100644
index da27414..0000000
--- a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/LayoutAnalyzer.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.uix;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipEntry;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.ArrayList;
-
-import com.android.layoutopt.uix.xml.XmlDocumentBuilder;
-import com.android.layoutopt.uix.rules.Rule;
-import com.android.layoutopt.uix.rules.GroovyRule;
-import com.android.layoutopt.uix.util.IOUtilities;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyShell;
-import groovy.lang.Script;
-
-/**
- * Analysis engine used to discover inefficiencies in Android XML
- * layout documents.
- *
- * Anaylizing an Android XML layout produces a list of explicit messages
- * as well as possible solutions. 
- */
-public class LayoutAnalyzer {
-    private static final String RULES_PREFIX = "rules/";
-
-    private final XmlDocumentBuilder mBuilder = new XmlDocumentBuilder();
-    private final List<Rule> mRules = new ArrayList<Rule>();
-
-    /**
-     * Creates a new layout analyzer. This constructor takes no argument
-     * and will use the default options.
-     */
-    public LayoutAnalyzer() {
-        loadRules();
-    }
-
-    private void loadRules() {
-        ClassLoader parent = getClass().getClassLoader();
-        GroovyClassLoader loader = new GroovyClassLoader(parent);
-        GroovyShell shell = new GroovyShell(loader);
-
-        URL jar = getClass().getProtectionDomain().getCodeSource().getLocation();
-        ZipFile zip = null;
-        try {
-            zip = new ZipFile(new File(jar.toURI()));
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            while (entries.hasMoreElements()) {
-                ZipEntry entry = entries.nextElement();
-                if (!entry.isDirectory() && entry.getName().startsWith(RULES_PREFIX)) {
-                    loadRule(shell, entry.getName(), zip.getInputStream(entry));
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (URISyntaxException e) {
-            e.printStackTrace();
-        } finally {
-            try {
-                if (zip != null) zip.close();
-            } catch (IOException e) {
-                // Ignore
-            }
-        }
-    }
-
-    private void loadRule(GroovyShell shell, String name, InputStream stream) {
-        try {
-            Script script = shell.parse(stream);
-            mRules.add(new GroovyRule(name, script));
-        } catch (Exception e) {
-            System.err.println("Could not load rule " + name + ":");
-            e.printStackTrace();
-        } finally {
-            IOUtilities.close(stream);
-        }
-    }
-
-    public void addRule(Rule rule) {
-        if (rule == null) {
-            throw new IllegalArgumentException("A rule must be non-null");
-        }
-        mRules.add(rule);
-    }
-
-    /**
-     * Analyzes the specified file.
-     *
-     * @param file The file to analyze.
-     *
-     * @return A {@link com.android.layoutopt.uix.LayoutAnalysis} which
-     *         cannot be null.
-     */
-    public LayoutAnalysis analyze(File file) {
-        if (file != null && file.exists()) {
-            InputStream in = null;
-            try {
-                in = new FileInputStream(file);
-                return analyze(file.getPath(), in);
-            } catch (FileNotFoundException e) {
-                // Ignore, cannot happen
-            } finally {
-                IOUtilities.close(in);
-            }
-        }
-
-        return LayoutAnalysis.ERROR;
-    }
-
-    /**
-     * Analyzes the specified XML stream.
-     *
-     * @param stream The stream to analyze.
-     * @return A {@link com.android.layoutopt.uix.LayoutAnalysis} which
-     *         cannot be null.
-     */
-    public LayoutAnalysis analyze(InputStream stream) {
-        return analyze("<unknown>", stream);
-    }
-
-    private LayoutAnalysis analyze(String name, InputStream stream) {
-         try {
-             Document document = mBuilder.parse(stream);
-             return analyze(name, document);
-         } catch (SAXException e) {
-             // Ignore
-         } catch (IOException e) {
-             // Ignore
-         }
-         return LayoutAnalysis.ERROR;
-    }
-
-    /**
-     * Analyzes the specified XML document.
-     *
-     * @param content The XML document to analyze.
-     *
-     * @return A {@link com.android.layoutopt.uix.LayoutAnalysis} which
-     *         cannot be null.
-     */
-    public LayoutAnalysis analyze(String content) {
-         return analyze("<unknown>", content);
-    }
-
-    /**
-     * Analyzes the specified XML document.
-     *
-     * @param name The name of the document.
-     * @param content The XML document to analyze.
-     *
-     * @return A {@link com.android.layoutopt.uix.LayoutAnalysis} which
-     *         cannot be null.
-     */
-    public LayoutAnalysis analyze(String name, String content) {
-         try {
-             Document document = mBuilder.parse(content);
-             return analyze(name, document);
-         } catch (SAXException e) {
-             // Ignore
-         } catch (IOException e) {
-             // Ignore
-         }
-         return LayoutAnalysis.ERROR;
-    }
-
-    /**
-     * Analyzes the specified XML document.
-     *
-     * @param document The XML document to analyze.
-     *
-     * @return A {@link com.android.layoutopt.uix.LayoutAnalysis} which
-     *         cannot be null.
-     */
-    public LayoutAnalysis analyze(Document document) {
-        return analyze("<unknown>", document);
-    }
-
-    /**
-     * Analyzes the specified XML document.
-     *
-     * @param name The name of the document.
-     * @param document The XML document to analyze.
-     *
-     * @return A {@link com.android.layoutopt.uix.LayoutAnalysis} which
-     *         cannot be null.
-     */
-    public LayoutAnalysis analyze(String name, Document document) {
-        LayoutAnalysis analysis = new LayoutAnalysis(name);
-
-        try {
-            Element root = document.getDocumentElement();
-            analyze(analysis, root);
-        } finally {
-            analysis.validate();
-        }
-
-        return analysis;        
-    }
-
-    private void analyze(LayoutAnalysis analysis, Node node) {
-        NodeList list = node.getChildNodes();
-        int count = list.getLength();
-
-        applyRules(analysis, node);
-
-        for (int i = 0; i < count; i++) {
-            Node child = list.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                analyze(analysis, child);
-            }
-        }
-    }
-
-    private void applyRules(LayoutAnalysis analysis, Node node) {
-        analysis.setCurrentNode(node);
-        for (Rule rule : mRules) {
-            rule.run(analysis, node);
-        }
-    }
-}
diff --git a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/groovy/LayoutAnalysisCategory.java b/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/groovy/LayoutAnalysisCategory.java
deleted file mode 100644
index a70086d..0000000
--- a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/groovy/LayoutAnalysisCategory.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.uix.groovy;
-
-import com.android.layoutopt.uix.LayoutAnalysis;
-import com.android.layoutopt.uix.xml.XmlDocumentBuilder;
-
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import groovy.lang.GString;
-import groovy.xml.dom.DOMCategory;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Element;
-
-/**
- * Support class for Groovy rules. This class adds new Groovy capabilities
- * to {@link com.android.layoutopt.uix.LayoutAnalysis} and {@link org.w3c.dom.Node}.
- */
-public class LayoutAnalysisCategory {
-    private static final String ANDROID_PADDING = "android:padding";
-    private static final String ANDROID_PADDING_LEFT = "android:paddingLeft";
-    private static final String ANDROID_PADDING_TOP = "android:paddingTop";
-    private static final String ANDROID_PADDING_RIGHT = "android:paddingRight";
-    private static final String ANDROID_PADDING_BOTTOM = "android:paddingBottom";
-    private static final String ANDROID_LAYOUT_WIDTH = "android:layout_width";
-    private static final String ANDROID_LAYOUT_HEIGHT = "android:layout_height";
-    private static final String VALUE_FILL_PARENT = "fill_parent";
-    private static final String VALUE_WRAP_CONTENT = "wrap_content";
-    
-    private static final String[] sContainers = new String[] {
-            "FrameLayout", "LinearLayout", "RelativeLayout", "SlidingDrawer",
-            "AbsoluteLayout", "TableLayout", "Gallery", "GridView", "ListView",
-            "RadioGroup", "ScrollView", "HorizontalScrollView", "Spinner",
-            "ViewSwitcher", "ViewFlipper", "ViewAnimator", "ImageSwitcher",
-            "TextSwitcher", "android.gesture.GestureOverlayView", "TabHost"
-    };
-    static {
-        Arrays.sort(sContainers);
-    }
-
-    /**
-     * xmlNode.isContainer()
-     * 
-     * @return True if the specified node corresponds to a container widget.
-     */
-    public static boolean isContainer(Element element) {
-        return Arrays.binarySearch(sContainers, element.getNodeName()) >= 0;
-    }
-
-    /**
-     * xmlNode.all()
-     * 
-     * Same as xmlNode.'**' but excludes xmlNode from the results.
-     * 
-     * @return All descendants, this node excluded.
-     */
-    public static List<Node> all(Element element) {
-        NodeList list = DOMCategory.depthFirst(element);
-        int count = list.getLength();
-        List<Node> nodes = new ArrayList<Node>(count - 1);
-        for (int i = 1; i < count; i++) {
-            nodes.add(list.item(i));
-        }
-        return nodes;
-    }
-
-    /**
-     * Returns the start line of this node.
-     *
-     * @return The start line or -1 if the line is unknown.
-     */
-    public static int getStartLine(Node node) {
-        final Object data = node == null ? null :
-                node.getUserData(XmlDocumentBuilder.NODE_START_LINE);
-        return data == null ? -1 : (Integer) data;
-    }
-
-    /**
-     * Returns the end line of this node.
-     *
-     * @return The end line or -1 if the line is unknown.
-     */
-    public static int getEndLine(Node node) {
-        final Object data = node == null ? null :
-                node.getUserData(XmlDocumentBuilder.NODE_END_LINE);
-        return data == null ? -1 : (Integer) data;
-    }
-
-    /**
-     * xmlNode.hasPadding()
-     * 
-     * @return True if the node has one ore more padding attributes.
-     */
-    public static boolean hasPadding(Element element) {
-        return element.getAttribute(ANDROID_PADDING).length() > 0 ||
-                element.getAttribute(ANDROID_PADDING_LEFT).length() > 0 ||
-                element.getAttribute(ANDROID_PADDING_TOP).length() > 0 ||
-                element.getAttribute(ANDROID_PADDING_BOTTOM).length() > 0 ||
-                element.getAttribute(ANDROID_PADDING_RIGHT).length() > 0;
-    }
-
-    /**
-     * Returns whether this node's width is fill_parent.
-     */
-    public static boolean isWidthFillParent(Element element) {
-        return element.getAttribute(ANDROID_LAYOUT_WIDTH).equals(VALUE_FILL_PARENT);
-    }
-
-    /**
-     * Returns whether this node's width is wrap_content.
-     */
-    public static boolean isWidthWrapContent(Element element) {
-        return element.getAttribute(ANDROID_LAYOUT_WIDTH).equals(VALUE_WRAP_CONTENT);
-    }
-
-    /**
-     * Returns whether this node's height is fill_parent.
-     */
-    public static boolean isHeightFillParent(Element element) {
-        return element.getAttribute(ANDROID_LAYOUT_HEIGHT).equals(VALUE_FILL_PARENT);
-    }
-
-    /**
-     * Returns whether this node's height is wrap_content.
-     */
-    public static boolean isHeightWrapContent(Element element) {
-        return element.getAttribute(ANDROID_LAYOUT_HEIGHT).equals(VALUE_WRAP_CONTENT);
-    }
-
-    /**
-     * xmlNode.isRoot()
-     * 
-     * @return True if xmlNode is the root of the document, false otherwise
-     */
-    public static boolean isRoot(Node node) {
-        return node.getOwnerDocument().getDocumentElement() == node;
-    }
-
-    /**
-     * xmlNode.is("tagName")
-     * 
-     * @return True if xmlNode.getNodeName().equals(name), false otherwise.
-     */
-    public static boolean is(Node node, String name) {
-        return node.getNodeName().equals(name);
-    }
-
-    /**
-     * xmlNode.depth()
-     * 
-     * @return The maximum depth of the node.
-     */
-    public static int depth(Node node) {
-        int maxDepth = 0;
-        NodeList list = node.getChildNodes();
-        int count = list.getLength();
-
-        for (int i = 0; i < count; i++) {
-            maxDepth = Math.max(maxDepth, depth(list.item(i)));
-        }
-
-        return maxDepth + 1;
-    }
-
-    /**
-     * analysis << "The issue"
-     * 
-     * @return The analysis itself to chain calls.
-     */
-    public static LayoutAnalysis leftShift(LayoutAnalysis analysis, GString description) {
-        analysis.addIssue(description.toString());
-        return analysis;
-    }
-
-    /**
-     * analysis << "The issue"
-     * 
-     * @return The analysis itself to chain calls.
-     */
-    public static LayoutAnalysis leftShift(LayoutAnalysis analysis, String description) {
-        analysis.addIssue(description);
-        return analysis;
-    }
-
-    /**
-     * analysis << [node: node, description: "The issue"]
-     * 
-     * @return The analysis itself to chain calls.
-     */
-    public static LayoutAnalysis leftShift(LayoutAnalysis analysis, Map issue) {
-        analysis.addIssue((Node) issue.get("node"), issue.get("description").toString());
-        return analysis;
-    }
-}
diff --git a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/rules/GroovyRule.java b/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/rules/GroovyRule.java
deleted file mode 100644
index 785b8f4..0000000
--- a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/rules/GroovyRule.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.uix.rules;
-
-import groovy.lang.Script;
-import groovy.lang.Binding;
-import groovy.lang.Closure;
-import groovy.xml.dom.DOMCategory;
-import com.android.layoutopt.uix.LayoutAnalysis;
-import com.android.layoutopt.uix.groovy.LayoutAnalysisCategory;
-import org.w3c.dom.Node;
-import org.codehaus.groovy.runtime.GroovyCategorySupport;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Implementation of a rule using a Groovy script.
- */
-public class GroovyRule implements Rule {
-    private final String mName;
-    private final Script mScript;
-    private final Binding mBinding;
-    private final Closure mClosure;
-    private final List<Class> mCategories;
-
-    public GroovyRule(String name, Script script) {
-        mName = name;
-        mScript = script;
-        mBinding = new Binding();
-        mScript.setBinding(mBinding);
-        mClosure = new Closure(this) {
-            @Override
-            public Object call() {
-                return mScript.run();
-            }
-        };
-        mCategories = new ArrayList<Class>();
-        Collections.addAll(mCategories, DOMCategory.class, LayoutAnalysisCategory.class);
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public void run(LayoutAnalysis analysis, Node node) {
-        mBinding.setVariable("analysis", analysis);
-        mBinding.setVariable("node", node);
-
-        GroovyCategorySupport.use(mCategories, mClosure);
-    }
-}
diff --git a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/rules/Rule.java b/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/rules/Rule.java
deleted file mode 100644
index 0168992..0000000
--- a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/rules/Rule.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.uix.rules;
-
-import com.android.layoutopt.uix.LayoutAnalysis;
-import org.w3c.dom.Node;
-
-/**
- * Interface that define an analysis rule.
- */
-public interface Rule {
-    /**
-     * Returns the name of the rule.
-     *
-     * @return A non-null String.
-     */
-    String getName();
-
-    /**
-     * Runs the rule for the specified node. The rule must add any detected
-     * issue to the analysis.
-     *
-     * @param analysis The resulting analysis.
-     * @param node The original XML node.
-     */
-    void run(LayoutAnalysis analysis, Node node);
-}
diff --git a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/util/IOUtilities.java b/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/util/IOUtilities.java
deleted file mode 100644
index 69ac30f..0000000
--- a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/util/IOUtilities.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.uix.util;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-/**
- * Various utilities related to I/O operations.
- */
-public class IOUtilities {
-    private IOUtilities() {
-    }
-
-    /**
-     * Safely close a Closeable object, like an InputStream.
-     *
-     * @param stream The object to close.
-     *
-     * @return True if the object is null or was closed properly,
-     *         false otherwise.
-     */
-    public static boolean close(Closeable stream) {
-        if (stream != null) {
-            try {
-                stream.close();
-            } catch (IOException e) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
diff --git a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/xml/XmlDocumentBuilder.java b/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/xml/XmlDocumentBuilder.java
deleted file mode 100644
index f5779ff..0000000
--- a/tools/layoutopt/libs/uix/src/com/android/layoutopt/uix/xml/XmlDocumentBuilder.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutopt.uix.xml;
-
-import com.sun.org.apache.xerces.internal.parsers.DOMParser;
-import com.sun.org.apache.xerces.internal.xni.XMLLocator;
-import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
-import com.sun.org.apache.xerces.internal.xni.Augmentations;
-import com.sun.org.apache.xerces.internal.xni.XNIException;
-import com.sun.org.apache.xerces.internal.xni.QName;
-import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.w3c.dom.Node;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.SAXException;
-import org.xml.sax.InputSource;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.LinkedList;
-
-/**
- * Parses XML documents. This class tries to add meta-data in the resulting DOM
- * trees to indicate the start and end line numbers of each node.
- */
-public class XmlDocumentBuilder {
-    /**
-     * Name of the node user data containing the start line number of the node.
-     * 
-     * @see Node#getUserData(String)
-     */
-    public static final String NODE_START_LINE = "startLine";
-
-    /**
-     * Name of the node user data containing the end line number of the node.
-     *
-     * @see Node#getUserData(String)
-     */
-    public static final String NODE_END_LINE = "endLine";
-
-    private final DocumentBuilder mBuilder;
-    private boolean mHasLineNumbersSupport;
-
-    /**
-     * Creates a new XML document builder.
-     */
-    public XmlDocumentBuilder() {
-        try {
-            Class.forName("com.sun.org.apache.xerces.internal.parsers.DOMParser");
-            mHasLineNumbersSupport = true;
-        } catch (ClassNotFoundException e) {
-            // Ignore
-        }
-
-        if (!mHasLineNumbersSupport) {
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            try {
-                mBuilder = factory.newDocumentBuilder();
-            } catch (ParserConfigurationException e) {
-                throw new IllegalStateException("Could not initialize the XML parser");
-            }
-        } else {
-            mBuilder = null;
-        }
-    }
-
-    /**
-     * Indicates whether the XML documents created by this class are annotated
-     * with line numbers.
-     *
-     * @return True if the parsed documents contain line numbers meta-data,
-     *         false otherwise.
-     *
-     * @see #NODE_START_LINE
-     * @see #NODE_END_LINE
-     */
-    public boolean isHasLineNumbersSupport() {
-        return mHasLineNumbersSupport;
-    }
-
-    public Document parse(InputStream inputStream) throws SAXException, IOException {
-        if (!mHasLineNumbersSupport) {
-            return mBuilder.parse(inputStream);
-        } else {
-            DOMParser parser = new LineNumberDOMParser();
-            parser.parse(new InputSource(inputStream));
-            return parser.getDocument();
-        }
-    }
-
-    public Document parse(String content) throws SAXException, IOException {
-        if (!mHasLineNumbersSupport) {
-            return mBuilder.parse(content);
-        } else {
-            DOMParser parser = new LineNumberDOMParser();
-            parser.parse(content);
-            return parser.getDocument();
-        }
-    }
-
-    public Document parse(File file) throws SAXException, IOException {
-        return parse(new FileInputStream(file));
-    }
-
-    private static class LineNumberDOMParser extends DOMParser {
-        private static final String FEATURE_NODE_EXPANSION =
-                "http://apache.org/xml/features/dom/defer-node-expansion";
-        private static final String CURRENT_NODE =
-                "http://apache.org/xml/properties/dom/current-element-node";
-
-        private XMLLocator mLocator;
-        private LinkedList<Node> mStack = new LinkedList<Node>();
-
-        private LineNumberDOMParser() {
-            try {
-                setFeature(FEATURE_NODE_EXPANSION, false);
-            } catch (SAXNotRecognizedException e) {
-                e.printStackTrace();
-            } catch (SAXNotSupportedException e) {
-                e.printStackTrace();
-            }
-        }
-
-        @Override
-        public void startDocument(XMLLocator xmlLocator, String s,
-                NamespaceContext namespaceContext, Augmentations augmentations)
-                throws XNIException {
-            super.startDocument(xmlLocator, s, namespaceContext, augmentations);
-
-            mLocator = xmlLocator;
-            mStack.add(setNodeLineNumber(NODE_START_LINE));
-        }
-
-        private Node setNodeLineNumber(String tag) {
-            Node node = null;
-            try {
-                node = (Node) getProperty(CURRENT_NODE);
-            } catch (SAXNotRecognizedException e) {
-                e.printStackTrace();
-            } catch (SAXNotSupportedException e) {
-                e.printStackTrace();
-            }
-
-            if (node != null) {
-                node.setUserData(tag, mLocator.getLineNumber(), null);
-            }
-
-            return node;
-        }
-
-        @Override
-        public void startElement(QName qName, XMLAttributes xmlAttributes,
-                Augmentations augmentations) throws XNIException {
-            super.startElement(qName, xmlAttributes, augmentations);
-            mStack.add(setNodeLineNumber(NODE_START_LINE));            
-        }
-
-        @Override
-        public void endElement(QName qName, Augmentations augmentations) throws XNIException {
-            super.endElement(qName, augmentations);
-            Node node = mStack.removeLast();
-            if (node != null) {
-                node.setUserData(NODE_END_LINE, mLocator.getLineNumber(), null);
-            }
-        }
-    }
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/IncorrectHeightInScrollView.rule b/tools/layoutopt/libs/uix/src/resources/rules/IncorrectHeightInScrollView.rule
deleted file mode 100644
index d29ebd5..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/IncorrectHeightInScrollView.rule
+++ /dev/null
@@ -1,11 +0,0 @@
-// Rule: IncorrectHeightInScrollView
-//
-// Description: Checks whether a scrollview's child has the wrong dimension.
-//
-// Conditions:
-// - The node has a ScrollView parent
-// - The node has a height set to fill_parent
-
-if (node.'..'.is("ScrollView") && node.isHeightFillParent()) {
-    analysis << "This ${node.name()} tag should use android:layout_height=\"wrap_content\""
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/IncorrectWidthInHorizontalScrollView.rule b/tools/layoutopt/libs/uix/src/resources/rules/IncorrectWidthInHorizontalScrollView.rule
deleted file mode 100644
index 17da843..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/IncorrectWidthInHorizontalScrollView.rule
+++ /dev/null
@@ -1,11 +0,0 @@
-// Rule: IncorrectWidthInScrollView
-//
-// Description: Checks whether a scrollview's child has the wrong dimension.
-//
-// Conditions:
-// - The node has a HorizontalScrollView parent
-// - The node has a width set to fill_parent
-
-if (node.'..'.is("HorizontalScrollView") && node.isWidthFillParent()) {
-    analysis << "This ${node.name()} tag should use android:layout_width=\"wrap_content\""
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/InefficientWeight.rule b/tools/layoutopt/libs/uix/src/resources/rules/InefficientWeight.rule
deleted file mode 100644
index 928d7a1..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/InefficientWeight.rule
+++ /dev/null
@@ -1,19 +0,0 @@
-// Rule: InefficientWeight
-//
-// Description: Checks whether a layout_weight is declared inefficiently.
-//
-// Conditions:
-// - The node has a LinearLayout parent
-// - The node is the only sibling with a weight
-// - The node has a height/width != 0
-
-def parent = node.'..'
-if (parent.is("LinearLayout") && node.'@android:layout_weight' &&
-        parent.'*'.findAll{ it.'@android:layout_weight' }.size() == 1) {
-    def dimension = parent.'@android:orientation' == "vertical" ?
-        "android:layout_height" : "android:layout_width"
-    if (node."@${dimension}"[0] != '0') {
-        analysis << "Use an ${dimension} of 0dip instead of ${node."@${dimension}"} " +
-                "for better performance"
-    }
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/MergeRootFrameLayout.rule b/tools/layoutopt/libs/uix/src/resources/rules/MergeRootFrameLayout.rule
deleted file mode 100644
index d3fc3d9..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/MergeRootFrameLayout.rule
+++ /dev/null
@@ -1,18 +0,0 @@
-// Rule: MergeRootFrameLayout
-//
-// Description: Checks whether the root node of the XML document can be
-//              replaced with a <merge /> tag.
-//
-// Conditions:
-// - The node is the root of the document
-// - The node is a FrameLayout
-// - The node is fill_parent in both orientation *or* it has no layout_gravity
-// - The node does not have a background nor a foreground
-// - The node does not have padding
-
-if (node.isRoot() && node.is("FrameLayout") && !node.'@android:background' &&
-        !node.'@android:foreground' && ((node.isWidthFillParent() &&
-                node.isHeightFillParent()) || !node.'@android:layout_gravity') &&
-        !node.hasPadding()) {
-    analysis << "The root-level <FrameLayout/> can be replaced with <merge/>"
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/NestedScrollingWidgets.rule b/tools/layoutopt/libs/uix/src/resources/rules/NestedScrollingWidgets.rule
deleted file mode 100644
index f48c24e..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/NestedScrollingWidgets.rule
+++ /dev/null
@@ -1,19 +0,0 @@
-// Rule: NestedScrollingWidgets
-//
-// Description: Checks whether a scrolling widget has nested scrolling widgets.
-//
-// Conditions:
-// - The node is a scrolling widget
-// - The node has a descendant who is also a scrolling widget
-
-def widgets = ["ScrollView", "ListView", "GridView"]
-if (node.name() in widgets && node.all().any{ it.name() in widgets }) {
-    analysis << "The vertically scrolling ${node.name()} should not contain another " +
-            "vertically scrolling widget"
-}
-
-widgets = ["HorizontalScrollView", "Gallery"]
-if (node.name() in widgets && node.all().any{ it.name() in widgets }) {
-    analysis << "The horizontally scrolling ${node.name()} should not contain another " +
-            "horizontally scrolling widget"
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/TooManyChildren.rule b/tools/layoutopt/libs/uix/src/resources/rules/TooManyChildren.rule
deleted file mode 100644
index 516d91f..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/TooManyChildren.rule
+++ /dev/null
@@ -1,15 +0,0 @@
-// Rule: TooManyChildren
-//
-// Description: Checks whether the layout has too many children.
-//
-// Conditions:
-// - The layout is a ScrollView and has more than 1 child
-// - The layout is a list or grid ans has at least 1 child
-
-if (node.name() in ["ScrollView", "HorizontalScrollView"] && node.'*'.size() > 1) {
-    analysis << "A scroll view can have only one child"
-}
-
-if (node.name() in ["ListView", "GridView"] && node.'*'.size() > 0) {
-    analysis << "A list/grid should have no children declared in node"
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/TooManyLevels.rule b/tools/layoutopt/libs/uix/src/resources/rules/TooManyLevels.rule
deleted file mode 100644
index f04e082..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/TooManyLevels.rule
+++ /dev/null
@@ -1,11 +0,0 @@
-// Rule: TooManyLevels
-//
-// Description: Checks whether the layout has too many nested groups.
-//
-// Conditions:
-// - The depth of the layout is > 10
-
-if (node.isRoot() && (depth = node.depth()) > 10) {
-    analysis << [node: null, description: "This layout has too many nested layouts: " +
-            "${depth} levels, it should have <= 10!"]
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/TooManyViews.rule b/tools/layoutopt/libs/uix/src/resources/rules/TooManyViews.rule
deleted file mode 100644
index 544a888..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/TooManyViews.rule
+++ /dev/null
@@ -1,11 +0,0 @@
-// Rule: TooManyViews
-//
-// Description: Checks whether the layout has too many views.
-//
-// Conditions:
-// - The document contains more than 80 views
-
-if (node.isRoot && (size = node.'**'.size()) > 80) {
-    analysis << [node: null,
-            description: "This layout has too many views: ${size} views, it should have <= 80!"]
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/UseCompoundDrawables.rule b/tools/layoutopt/libs/uix/src/resources/rules/UseCompoundDrawables.rule
deleted file mode 100644
index 4e4a6ba..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/UseCompoundDrawables.rule
+++ /dev/null
@@ -1,15 +0,0 @@
-// Rule: UseCompoundDrawables
-//
-// Description: Checks whether the current node can be replaced by a TextView
-//              using compound drawables.
-//
-// Conditions:
-// - The node is a LinearLayout
-// - The node has two children, ImageView and TextView
-// - The ImageView does not have a weight
-
-if (node.is("LinearLayout") && node.'*'.size() == 2 && node.'TextView'.size() == 1 &&
-        node.'ImageView'.size() == 1 && !node.'ImageView'[0].'@android:layout_weight') {
-    analysis << "This tag and its children can be replaced by one <TextView/> and " +
-            "a compound drawable"
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/UselessLayout.rule b/tools/layoutopt/libs/uix/src/resources/rules/UselessLayout.rule
deleted file mode 100644
index 9326333..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/UselessLayout.rule
+++ /dev/null
@@ -1,19 +0,0 @@
-// Rule: UselessLayout
-//
-// Description: Checks whether current node can be removed.
-//
-// Conditions:
-// - The node has children
-// - The node does not have siblings
-// - The node's parent is not a scroll view (horizontal or vertical)
-// - The node does not have a background or its parent does not have a
-//   background or neither the node and its parent have a background
-// - The parent is not a <merge/>
-
-if (!node.isRoot() && !(node['..'].name() in ["ScrollView", "HorizontalScrollView"]) &&
-        node['..']['*'].size() == 1 && node['*'].size() > 0 && ((node.'@android:background' ||
-        node['..'].'@android:background') || (!node.'@android:background' &&
-        !node['..'].'@android:background'))) {
-    analysis << "This ${node.name()} layout or its ${node['..'].name()} parent is " +
-            "${node['..'].'@android:id' ? "possibly useless" : "useless"}"
-}
diff --git a/tools/layoutopt/libs/uix/src/resources/rules/UselessView.rule b/tools/layoutopt/libs/uix/src/resources/rules/UselessView.rule
deleted file mode 100644
index c3a77e5..0000000
--- a/tools/layoutopt/libs/uix/src/resources/rules/UselessView.rule
+++ /dev/null
@@ -1,14 +0,0 @@
-// Rule: UselessView
-//
-// Description: Checks whether a container view can be removed.
-//
-// Conditions:
-// - The node is a container view (LinearLayout, etc.)
-// - The node has no id
-// - The node has no background
-// - The node has no children
-
-if (node.isContainer() && node.'*'.size() == 0 && !node.'@android:id' &&
-        !node.'@android:background') {
-    analysis << "This ${node.name()} view is useless (no children, no background, no id)"
-}
diff --git a/tools/layoutopt/samples/compound.xml b/tools/layoutopt/samples/compound.xml
deleted file mode 100644
index 176089b..0000000
--- a/tools/layoutopt/samples/compound.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-    <ImageView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
-
-</LinearLayout>
diff --git a/tools/layoutopt/samples/has_children.xml b/tools/layoutopt/samples/has_children.xml
deleted file mode 100644
index f216db5..0000000
--- a/tools/layoutopt/samples/has_children.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<ListView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-	<ListView 
-	    android:layout_width="fill_parent"
-	    android:layout_height="fill_parent" />
-	
-</ListView>
\ No newline at end of file
diff --git a/tools/layoutopt/samples/inefficient_weight.xml b/tools/layoutopt/samples/inefficient_weight.xml
deleted file mode 100644
index 785350a..0000000
--- a/tools/layoutopt/samples/inefficient_weight.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-	<Button 
-	    android:layout_width="fill_parent"
-	    android:layout_height="wrap_content"
-	 	android:layout_weight="1.0" />
-	
-	<LinearLayout
-	    xmlns:android="http://schemas.android.com/apk/res/android"
-
-	    android:layout_width="fill_parent"
-	    android:layout_height="fill_parent"
-	
-		android:orientation="vertical">
-
-		<Button 
-		    android:layout_width="fill_parent"
-		    android:layout_height="wrap_content"
-		 	android:layout_weight="1.0" />
-
-	</LinearLayout>
-	
-	<LinearLayout
-	    xmlns:android="http://schemas.android.com/apk/res/android"
-
-	    android:layout_width="fill_parent"
-	    android:layout_height="fill_parent"
-	
-		android:orientation="vertical">
-
-		<Button 
-		    android:layout_width="fill_parent"
-		    android:layout_height="0dip"
-		 	android:layout_weight="1.0" />
-
-	</LinearLayout>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutopt/samples/scrolling.xml b/tools/layoutopt/samples/scrolling.xml
deleted file mode 100644
index 534289c..0000000
--- a/tools/layoutopt/samples/scrolling.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<ScrollView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-	<LinearLayout
-	    android:layout_width="fill_parent"
-	    android:layout_height="fill_parent">
-
-		<ListView 
-		    android:layout_width="fill_parent"
-		    android:layout_height="fill_parent" />
-
-	</LinearLayout>
-
-</ScrollView>
diff --git a/tools/layoutopt/samples/simple.xml b/tools/layoutopt/samples/simple.xml
deleted file mode 100644
index 1fd36e2..0000000
--- a/tools/layoutopt/samples/simple.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent" />
diff --git a/tools/layoutopt/samples/too_deep.xml b/tools/layoutopt/samples/too_deep.xml
deleted file mode 100644
index 7317362..0000000
--- a/tools/layoutopt/samples/too_deep.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-        
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent">
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="fill_parent">
-
-            <LinearLayout
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent">
-
-                <LinearLayout
-                    android:layout_width="fill_parent"
-                    android:layout_height="fill_parent">
-
-                    <LinearLayout
-                        android:layout_width="fill_parent"
-                        android:layout_height="fill_parent">
-
-                        <LinearLayout
-                            android:layout_width="fill_parent"
-                            android:layout_height="fill_parent">
-
-                            <LinearLayout
-                                android:layout_width="fill_parent"
-                                android:layout_height="fill_parent">
-
-                                <LinearLayout
-                                    android:layout_width="fill_parent"
-                                    android:layout_height="fill_parent">
-
-                                    <LinearLayout
-                                        android:layout_width="fill_parent"
-                                        android:layout_height="fill_parent">
-
-                                        <LinearLayout
-                                            android:layout_width="fill_parent"
-                                            android:layout_height="fill_parent">
-
-                                            <LinearLayout
-                                                android:layout_width="fill_parent"
-                                                android:layout_height="fill_parent">
-
-                                                <Button
-                                                    android:layout_width="wrap_content"
-                                                    android:layout_height="wrap_content"
-                                                    android:text="Ok" />
-
-                                            </LinearLayout>
-
-                                        </LinearLayout>
-
-                                    </LinearLayout>
-
-                                </LinearLayout>
-
-                            </LinearLayout>
-
-                        </LinearLayout>
-
-                    </LinearLayout>
-
-                </LinearLayout>
-
-            </LinearLayout>
-
-        </LinearLayout>
-
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/tools/layoutopt/samples/too_many.xml b/tools/layoutopt/samples/too_many.xml
deleted file mode 100644
index 41c18ff..0000000
--- a/tools/layoutopt/samples/too_many.xml
+++ /dev/null
@@ -1,413 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-    
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ok" />
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent">
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-            <LinearLayout
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent">
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-            </LinearLayout>
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent">
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-        <Button
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Ok" />
-
-            <LinearLayout
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent">
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-                <Button
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="Ok" />
-
-            </LinearLayout>
-
-    </LinearLayout>
-
-</FrameLayout>
diff --git a/tools/layoutopt/samples/useless.xml b/tools/layoutopt/samples/useless.xml
deleted file mode 100644
index 1c2d5d8..0000000
--- a/tools/layoutopt/samples/useless.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-	<LinearLayout
-		android:layout_width="fill_parent"
-	    android:layout_height="fill_parent">
-	
-		<TextView
-			android:layout_width="wrap_content"
-		    android:layout_height="wrap_content" />
-	
-	</LinearLayout>
-
-</FrameLayout>
diff --git a/tools/layoutopt/samples/wrong_dimension.xml b/tools/layoutopt/samples/wrong_dimension.xml
deleted file mode 100644
index c0b292b..0000000
--- a/tools/layoutopt/samples/wrong_dimension.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<HorizontalScrollView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-	<LinearLayout
-	    android:layout_width="fill_parent"
-	    android:layout_height="fill_parent" />
-
-</HorizontalScrollView>
diff --git a/tools/ninepatch/.classpath b/tools/ninepatch/.classpath
deleted file mode 100644
index fb50116..0000000
--- a/tools/ninepatch/.classpath
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/ninepatch/.gitignore b/tools/ninepatch/.gitignore
deleted file mode 100644
index ba077a4..0000000
--- a/tools/ninepatch/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/tools/ninepatch/.project b/tools/ninepatch/.project
deleted file mode 100644
index 192f000..0000000
--- a/tools/ninepatch/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>ninepatch</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/ninepatch/Android.mk b/tools/ninepatch/Android.mk
deleted file mode 100644
index 42e0205..0000000
--- a/tools/ninepatch/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_MODULE := ninepatch
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java b/tools/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java
deleted file mode 100644
index e8d71d6..0000000
--- a/tools/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.android.ninepatch;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.awt.image.Raster;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsEnvironment;
-import java.awt.Graphics;
-import java.awt.Transparency;
-import java.net.URL;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class GraphicsUtilities {
-    public static BufferedImage loadCompatibleImage(URL resource) throws IOException {
-        BufferedImage image = ImageIO.read(resource);
-        return toCompatibleImage(image);
-    }
-
-    public static BufferedImage loadCompatibleImage(InputStream stream) throws IOException {
-        BufferedImage image = ImageIO.read(stream);
-        return toCompatibleImage(image);
-    }
-
-    public static BufferedImage createCompatibleImage(int width, int height) {
-        return getGraphicsConfiguration().createCompatibleImage(width, height);
-    }
-
-    public static BufferedImage toCompatibleImage(BufferedImage image) {
-        if (isHeadless()) {
-            return image;
-        }
-
-        if (image.getColorModel().equals(getGraphicsConfiguration().getColorModel())) {
-            return image;
-        }
-
-        BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(
-                    image.getWidth(), image.getHeight(), image.getTransparency());
-        Graphics g = compatibleImage.getGraphics();
-        g.drawImage(image, 0, 0, null);
-        g.dispose();
-
-        return compatibleImage;
-    }
-
-    public static BufferedImage createCompatibleImage(BufferedImage image, int width, int height) {
-        return getGraphicsConfiguration().createCompatibleImage(width, height,
-                                                   image.getTransparency());
-    }
-
-    private static GraphicsConfiguration getGraphicsConfiguration() {
-        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
-        return environment.getDefaultScreenDevice().getDefaultConfiguration();
-    }
-
-    private static boolean isHeadless() {
-        return GraphicsEnvironment.isHeadless();
-    }
-
-    public static BufferedImage createTranslucentCompatibleImage(int width, int height) {
-        return getGraphicsConfiguration().createCompatibleImage(width, height,
-                Transparency.TRANSLUCENT);
-    }
-
-    public static int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
-        if (w == 0 || h == 0) {
-            return new int[0];
-        }
-
-        if (pixels == null) {
-            pixels = new int[w * h];
-        } else if (pixels.length < w * h) {
-            throw new IllegalArgumentException("Pixels array must have a length >= w * h");
-        }
-
-        int imageType = img.getType();
-        if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) {
-            Raster raster = img.getRaster();
-            return (int[]) raster.getDataElements(x, y, w, h, pixels);
-        }
-
-        // Unmanages the image
-        return img.getRGB(x, y, w, h, pixels, 0, w);
-    }
-}
diff --git a/tools/ninepatch/src/com/android/ninepatch/NinePatch.java b/tools/ninepatch/src/com/android/ninepatch/NinePatch.java
deleted file mode 100644
index 7484fd8..0000000
--- a/tools/ninepatch/src/com/android/ninepatch/NinePatch.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * 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.android.ninepatch;
-
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents a 9-Patch bitmap.
- */
-public class NinePatch {
-    public static final String EXTENSION_9PATCH = ".9.png";
-
-    private BufferedImage mImage;
-
-    private int mMinWidth;
-    private int mMinHeight;
-
-    private int[] row;
-    private int[] column;
-
-    private boolean mVerticalStartWithPatch;
-    private boolean mHorizontalStartWithPatch;
-
-    private List<Rectangle> mFixed;
-    private List<Rectangle> mPatches;
-    private List<Rectangle> mHorizontalPatches;
-    private List<Rectangle> mVerticalPatches;
-
-    private Pair<Integer> mHorizontalPadding;
-    private Pair<Integer> mVerticalPadding;
-
-    private float mHorizontalPatchesSum;
-    private float mVerticalPatchesSum;
-
-    private int mRemainderHorizontal;
-
-    private int mRemainderVertical;
-
-    /**
-     * Loads a 9 patch or regular bitmap.
-     * @param fileUrl the URL of the file to load.
-     * @param convert if <code>true</code>, non 9-patch bitmap will be converted into a 9 patch.
-     * If <code>false</code> and the bitmap is not a 9 patch, the method will return
-     * <code>null</code>.
-     * @return a {@link NinePatch} or <code>null</code>.
-     * @throws IOException
-     */
-    public static NinePatch load(URL fileUrl, boolean convert) throws IOException {
-        BufferedImage image = null;
-        try {
-            image  = GraphicsUtilities.loadCompatibleImage(fileUrl);
-        } catch (MalformedURLException e) {
-            // really this shouldn't be happening since we're not creating the URL manually.
-            return null;
-        }
-
-        boolean is9Patch = fileUrl.getPath().toLowerCase().endsWith(EXTENSION_9PATCH);
-
-        return load(image, is9Patch, convert);
-    }
-
-    /**
-     * Loads a 9 patch or regular bitmap.
-     * @param stream the {@link InputStream} of the file to load.
-     * @param is9Patch whether the file represents a 9-patch
-     * @param convert if <code>true</code>, non 9-patch bitmap will be converted into a 9 patch.
-     * If <code>false</code> and the bitmap is not a 9 patch, the method will return
-     * <code>null</code>.
-     * @return a {@link NinePatch} or <code>null</code>.
-     * @throws IOException
-     */
-    public static NinePatch load(InputStream stream, boolean is9Patch, boolean convert)
-            throws IOException {
-        BufferedImage image = null;
-        try {
-            image  = GraphicsUtilities.loadCompatibleImage(stream);
-        } catch (MalformedURLException e) {
-            // really this shouldn't be happening since we're not creating the URL manually.
-            return null;
-        }
-
-        return load(image, is9Patch, convert);
-    }
-
-    /**
-     * Loads a 9 patch or regular bitmap.
-     * @param image the source {@link BufferedImage}.
-     * @param is9Patch whether the file represents a 9-patch
-     * @param convert if <code>true</code>, non 9-patch bitmap will be converted into a 9 patch.
-     * If <code>false</code> and the bitmap is not a 9 patch, the method will return
-     * <code>null</code>.
-     * @return a {@link NinePatch} or <code>null</code>.
-     * @throws IOException
-     */
-    public static NinePatch load(BufferedImage image, boolean is9Patch, boolean convert) {
-        if (is9Patch == false) {
-            if (convert) {
-                image = convertTo9Patch(image);
-            } else {
-                return null;
-            }
-        } else {
-            ensure9Patch(image);
-        }
-
-        return new NinePatch(image);
-    }
-
-    public int getWidth() {
-        return mImage.getWidth() - 2;
-    }
-
-    public int getHeight() {
-        return mImage.getHeight() - 2;
-    }
-
-    /**
-     *
-     * @param padding array of left, top, right, bottom padding
-     * @return
-     */
-    public boolean getPadding(int[] padding) {
-        padding[0] = mHorizontalPadding.mFirst; // left
-        padding[2] = mHorizontalPadding.mSecond; // right
-        padding[1] = mVerticalPadding.mFirst; // top
-        padding[3] = mVerticalPadding.mSecond; // bottom
-        return true;
-    }
-
-
-    public void draw(Graphics2D graphics2D, int x, int y, int scaledWidth, int scaledHeight) {
-        if (scaledWidth <= 1 || scaledHeight <= 1) {
-            return;
-        }
-
-        Graphics2D g = (Graphics2D)graphics2D.create();
-        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-
-
-        try {
-            if (mPatches.size() == 0) {
-                g.drawImage(mImage, x, y, scaledWidth, scaledHeight, null);
-                return;
-            }
-
-            g.translate(x, y);
-            x = y = 0;
-
-            computePatches(scaledWidth, scaledHeight);
-
-            int fixedIndex = 0;
-            int horizontalIndex = 0;
-            int verticalIndex = 0;
-            int patchIndex = 0;
-
-            boolean hStretch;
-            boolean vStretch;
-
-            float vWeightSum = 1.0f;
-            float vRemainder = mRemainderVertical;
-
-            vStretch = mVerticalStartWithPatch;
-            while (y < scaledHeight - 1) {
-                hStretch = mHorizontalStartWithPatch;
-
-                int height = 0;
-                float vExtra = 0.0f;
-
-                float hWeightSum = 1.0f;
-                float hRemainder = mRemainderHorizontal;
-
-                while (x < scaledWidth - 1) {
-                    Rectangle r;
-                    if (!vStretch) {
-                        if (hStretch) {
-                            r = mHorizontalPatches.get(horizontalIndex++);
-                            float extra = r.width / mHorizontalPatchesSum;
-                            int width = (int) (extra * hRemainder / hWeightSum);
-                            hWeightSum -= extra;
-                            hRemainder -= width;
-                            g.drawImage(mImage, x, y, x + width, y + r.height, r.x, r.y,
-                                    r.x + r.width, r.y + r.height, null);
-                            x += width;
-                        } else {
-                            r = mFixed.get(fixedIndex++);
-                            g.drawImage(mImage, x, y, x + r.width, y + r.height, r.x, r.y,
-                                    r.x + r.width, r.y + r.height, null);
-                            x += r.width;
-                        }
-                        height = r.height;
-                    } else {
-                        if (hStretch) {
-                            r = mPatches.get(patchIndex++);
-                            vExtra = r.height / mVerticalPatchesSum;
-                            height = (int) (vExtra * vRemainder / vWeightSum);
-                            float extra = r.width / mHorizontalPatchesSum;
-                            int width = (int) (extra * hRemainder / hWeightSum);
-                            hWeightSum -= extra;
-                            hRemainder -= width;
-                            g.drawImage(mImage, x, y, x + width, y + height, r.x, r.y,
-                                    r.x + r.width, r.y + r.height, null);
-                            x += width;
-                        } else {
-                            r = mVerticalPatches.get(verticalIndex++);
-                            vExtra = r.height / mVerticalPatchesSum;
-                            height = (int) (vExtra * vRemainder / vWeightSum);
-                            g.drawImage(mImage, x, y, x + r.width, y + height, r.x, r.y,
-                                    r.x + r.width, r.y + r.height, null);
-                            x += r.width;
-                        }
-
-                    }
-                    hStretch = !hStretch;
-                }
-                x = 0;
-                y += height;
-                if (vStretch) {
-                    vWeightSum -= vExtra;
-                    vRemainder -= height;
-                }
-                vStretch = !vStretch;
-            }
-
-        } finally {
-            g.dispose();
-        }
-    }
-
-    void computePatches(int scaledWidth, int scaledHeight) {
-        boolean measuredWidth = false;
-        boolean endRow = true;
-
-        int remainderHorizontal = 0;
-        int remainderVertical = 0;
-
-        if (mFixed.size() > 0) {
-            int start = mFixed.get(0).y;
-            for (Rectangle rect : mFixed) {
-                if (rect.y > start) {
-                    endRow = true;
-                    measuredWidth = true;
-                }
-                if (!measuredWidth) {
-                    remainderHorizontal += rect.width;
-                }
-                if (endRow) {
-                    remainderVertical += rect.height;
-                    endRow = false;
-                    start = rect.y;
-                }
-            }
-        }
-
-        mRemainderHorizontal = scaledWidth - remainderHorizontal;
-
-        mRemainderVertical = scaledHeight - remainderVertical;
-
-        mHorizontalPatchesSum = 0;
-        if (mHorizontalPatches.size() > 0) {
-            int start = -1;
-            for (Rectangle rect : mHorizontalPatches) {
-                if (rect.x > start) {
-                    mHorizontalPatchesSum += rect.width;
-                    start = rect.x;
-                }
-            }
-        } else {
-            int start = -1;
-            for (Rectangle rect : mPatches) {
-                if (rect.x > start) {
-                    mHorizontalPatchesSum += rect.width;
-                    start = rect.x;
-                }
-            }
-        }
-
-        mVerticalPatchesSum = 0;
-        if (mVerticalPatches.size() > 0) {
-            int start = -1;
-            for (Rectangle rect : mVerticalPatches) {
-                if (rect.y > start) {
-                    mVerticalPatchesSum += rect.height;
-                    start = rect.y;
-                }
-            }
-        } else {
-            int start = -1;
-            for (Rectangle rect : mPatches) {
-                if (rect.y > start) {
-                    mVerticalPatchesSum += rect.height;
-                    start = rect.y;
-                }
-            }
-        }
-    }
-
-
-    private NinePatch(BufferedImage image) {
-        mImage = image;
-
-        findPatches();
-    }
-
-    private void findPatches() {
-        int width = mImage.getWidth();
-        int height = mImage.getHeight();
-
-        row = GraphicsUtilities.getPixels(mImage, 0, 0, width, 1, row);
-        column = GraphicsUtilities.getPixels(mImage, 0, 0, 1, height, column);
-
-        boolean[] result = new boolean[1];
-        Pair<List<Pair<Integer>>> left = getPatches(column, result);
-        mVerticalStartWithPatch = result[0];
-
-        result = new boolean[1];
-        Pair<List<Pair<Integer>>> top = getPatches(row, result);
-        mHorizontalStartWithPatch = result[0];
-
-        mFixed = getRectangles(left.mFirst, top.mFirst);
-        mPatches = getRectangles(left.mSecond, top.mSecond);
-
-        if (mFixed.size() > 0) {
-            mHorizontalPatches = getRectangles(left.mFirst, top.mSecond);
-            mVerticalPatches = getRectangles(left.mSecond, top.mFirst);
-        } else {
-            if (top.mFirst.size() > 0) {
-                mHorizontalPatches = new ArrayList<Rectangle>(0);
-                mVerticalPatches = getVerticalRectangles(top.mFirst);
-            } else if (left.mFirst.size() > 0) {
-                mHorizontalPatches = getHorizontalRectangles(left.mFirst);
-                mVerticalPatches = new ArrayList<Rectangle>(0);
-            } else {
-                mHorizontalPatches = mVerticalPatches = new ArrayList<Rectangle>(0);
-            }
-        }
-
-        row = GraphicsUtilities.getPixels(mImage, 0, height - 1, width, 1, row);
-        column = GraphicsUtilities.getPixels(mImage, width - 1, 0, 1, height, column);
-
-        top = getPatches(row, result);
-        mHorizontalPadding = getPadding(top.mFirst);
-
-        left = getPatches(column, result);
-        mVerticalPadding = getPadding(left.mFirst);
-    }
-
-    private List<Rectangle> getVerticalRectangles(List<Pair<Integer>> topPairs) {
-        List<Rectangle> rectangles = new ArrayList<Rectangle>();
-        for (Pair<Integer> top : topPairs) {
-            int x = top.mFirst;
-            int width = top.mSecond - top.mFirst;
-
-            rectangles.add(new Rectangle(x, 1, width, mImage.getHeight() - 2));
-        }
-        return rectangles;
-    }
-
-    private List<Rectangle> getHorizontalRectangles(List<Pair<Integer>> leftPairs) {
-        List<Rectangle> rectangles = new ArrayList<Rectangle>();
-        for (Pair<Integer> left : leftPairs) {
-            int y = left.mFirst;
-            int height = left.mSecond - left.mFirst;
-
-            rectangles.add(new Rectangle(1, y, mImage.getWidth() - 2, height));
-        }
-        return rectangles;
-    }
-
-    private Pair<Integer> getPadding(List<Pair<Integer>> pairs) {
-        if (pairs.size() == 0) {
-            return new Pair<Integer>(0, 0);
-        } else if (pairs.size() == 1) {
-            if (pairs.get(0).mFirst == 1) {
-                return new Pair<Integer>(pairs.get(0).mSecond - pairs.get(0).mFirst, 0);
-            } else {
-                return new Pair<Integer>(0, pairs.get(0).mSecond - pairs.get(0).mFirst);
-            }
-        } else {
-            int index = pairs.size() - 1;
-            return new Pair<Integer>(pairs.get(0).mSecond - pairs.get(0).mFirst,
-                    pairs.get(index).mSecond - pairs.get(index).mFirst);
-        }
-    }
-
-    private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs,
-            List<Pair<Integer>> topPairs) {
-        List<Rectangle> rectangles = new ArrayList<Rectangle>();
-        for (Pair<Integer> left : leftPairs) {
-            int y = left.mFirst;
-            int height = left.mSecond - left.mFirst;
-            for (Pair<Integer> top : topPairs) {
-                int x = top.mFirst;
-                int width = top.mSecond - top.mFirst;
-
-                rectangles.add(new Rectangle(x, y, width, height));
-            }
-        }
-        return rectangles;
-    }
-
-    private Pair<List<Pair<Integer>>> getPatches(int[] pixels, boolean[] startWithPatch) {
-        int lastIndex = 1;
-        int lastPixel = pixels[1];
-        boolean first = true;
-
-        List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>();
-        List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>();
-
-        for (int i = 1; i < pixels.length - 1; i++) {
-            int pixel = pixels[i];
-            if (pixel != lastPixel) {
-                if (lastPixel == 0xFF000000) {
-                    if (first) startWithPatch[0] = true;
-                    patches.add(new Pair<Integer>(lastIndex, i));
-                } else {
-                    fixed.add(new Pair<Integer>(lastIndex, i));
-                }
-                first = false;
-
-                lastIndex = i;
-                lastPixel = pixel;
-            }
-        }
-        if (lastPixel == 0xFF000000) {
-            if (first) startWithPatch[0] = true;
-            patches.add(new Pair<Integer>(lastIndex, pixels.length - 1));
-        } else {
-            fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1));
-        }
-
-        if (patches.size() == 0) {
-            patches.add(new Pair<Integer>(1, pixels.length - 1));
-            startWithPatch[0] = true;
-            fixed.clear();
-        }
-
-        return new Pair<List<Pair<Integer>>>(fixed, patches);
-    }
-
-    private static void ensure9Patch(BufferedImage image) {
-        int width = image.getWidth();
-        int height = image.getHeight();
-        for (int i = 0; i < width; i++) {
-            int pixel = image.getRGB(i, 0);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(i, 0, 0);
-            }
-            pixel = image.getRGB(i, height - 1);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(i, height - 1, 0);
-            }
-        }
-        for (int i = 0; i < height; i++) {
-            int pixel = image.getRGB(0, i);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(0, i, 0);
-            }
-            pixel = image.getRGB(width - 1, i);
-            if (pixel != 0 && pixel != 0xFF000000) {
-                image.setRGB(width - 1, i, 0);
-            }
-        }
-    }
-
-    private static BufferedImage convertTo9Patch(BufferedImage image) {
-        BufferedImage buffer = GraphicsUtilities.createTranslucentCompatibleImage(
-                image.getWidth() + 2, image.getHeight() + 2);
-
-        Graphics2D g2 = buffer.createGraphics();
-        g2.drawImage(image, 1, 1, null);
-        g2.dispose();
-
-        return buffer;
-    }
-
-    static class Pair<E> {
-        E mFirst;
-        E mSecond;
-
-        Pair(E first, E second) {
-            mFirst = first;
-            mSecond = second;
-        }
-
-        @Override
-        public String toString() {
-            return "Pair[" + mFirst + ", " + mSecond + "]";
-        }
-    }
-}
diff --git a/tools/screenshot/.classpath b/tools/screenshot/.classpath
deleted file mode 100644
index b0326c8..0000000
--- a/tools/screenshot/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/screenshot/.gitignore b/tools/screenshot/.gitignore
deleted file mode 100644
index ba077a4..0000000
--- a/tools/screenshot/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/tools/screenshot/.project b/tools/screenshot/.project
deleted file mode 100644
index f5d3f51..0000000
--- a/tools/screenshot/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>screenshot</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/screenshot/Android.mk b/tools/screenshot/Android.mk
deleted file mode 100644
index 7cf9090..0000000
--- a/tools/screenshot/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-SCREENSHOT2_LOCAL_DIR := $(call my-dir)
-include $(SCREENSHOT2_LOCAL_DIR)/etc/Android.mk
-include $(SCREENSHOT2_LOCAL_DIR)/src/Android.mk
diff --git a/tools/screenshot/etc/Android.mk b/tools/screenshot/etc/Android.mk
deleted file mode 100644
index 5107535..0000000
--- a/tools/screenshot/etc/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := screenshot2
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/screenshot/etc/manifest.txt b/tools/screenshot/etc/manifest.txt
deleted file mode 100644
index f52874a..0000000
--- a/tools/screenshot/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.screenshot.Screenshot
diff --git a/tools/screenshot/etc/screenshot2 b/tools/screenshot/etc/screenshot2
deleted file mode 100755
index 10b921a..0000000
--- a/tools/screenshot/etc/screenshot2
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/sh
-# Copyright 2005-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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=screenshot2.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
-    # add this in for debugging
-    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
-    shift 1
-else
-    java_debug=
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.screenshot.bindir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/screenshot/src/Android.mk b/tools/screenshot/src/Android.mk
deleted file mode 100644
index 8b5ea3a..0000000
--- a/tools/screenshot/src/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	ddmlib
-LOCAL_MODULE := screenshot2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/screenshot/src/com/android/screenshot/Screenshot.java b/tools/screenshot/src/com/android/screenshot/Screenshot.java
deleted file mode 100644
index a3fe520..0000000
--- a/tools/screenshot/src/com/android/screenshot/Screenshot.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * 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.android.screenshot;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.RawImage;
-import com.android.ddmlib.Log.ILogOutput;
-import com.android.ddmlib.Log.LogLevel;
-
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-
-import javax.imageio.ImageIO;
-
-/**
- * Connects to a device using ddmlib and dumps its event log as long as the device is connected.
- */
-public class Screenshot {
-
-    public static void main(String[] args) {
-        boolean device = false;
-        boolean emulator = false;
-        String serial = null;
-        String filepath = null;
-        boolean landscape = false;
-
-        if (args.length == 0) {
-            printUsageAndQuit();
-        }
-
-        // parse command line parameters.
-        int index = 0;
-        do {
-            String argument = args[index++];
-
-            if ("-d".equals(argument)) {
-                if (emulator || serial != null) {
-                    printAndExit("-d conflicts with -e and -s", false /* terminate */);
-                }
-                device = true;
-            } else if ("-e".equals(argument)) {
-                if (device || serial != null) {
-                    printAndExit("-e conflicts with -d and -s", false /* terminate */);
-                }
-                emulator = true;
-            } else if ("-s".equals(argument)) {
-                // quick check on the next argument.
-                if (index == args.length) {
-                    printAndExit("Missing serial number after -s", false /* terminate */);
-                }
-
-                if (device || emulator) {
-                    printAndExit("-s conflicts with -d and -e", false /* terminate */);
-                }
-
-                serial = args[index++];
-            } else if ("-l".equals(argument)) {
-                landscape = true;
-            } else {
-                // get the filepath and break.
-                filepath = argument;
-
-                // should not be any other device.
-                if (index < args.length) {
-                    printAndExit("Too many arguments!", false /* terminate */);
-                }
-            }
-        } while (index < args.length);
-
-        if (filepath == null) {
-            printUsageAndQuit();
-        }
-
-        Log.setLogOutput(new ILogOutput() {
-            public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
-                System.err.println(logLevel.getStringValue() + ":" + tag + ":" + message);
-            }
-
-            public void printLog(LogLevel logLevel, String tag, String message) {
-                System.err.println(logLevel.getStringValue() + ":" + tag + ":" + message);
-            }
-        });
-
-        // init the lib
-        // [try to] ensure ADB is running
-        String adbLocation = System.getProperty("com.android.screenshot.bindir"); //$NON-NLS-1$
-        if (adbLocation != null && adbLocation.length() != 0) {
-            adbLocation += File.separator + "adb"; //$NON-NLS-1$
-        } else {
-            adbLocation = "adb"; //$NON-NLS-1$
-        }
-
-        AndroidDebugBridge.init(false /* debugger support */);
-
-        try {
-            AndroidDebugBridge bridge = AndroidDebugBridge.createBridge(
-                    adbLocation, true /* forceNewBridge */);
-
-            // we can't just ask for the device list right away, as the internal thread getting
-            // them from ADB may not be done getting the first list.
-            // Since we don't really want getDevices() to be blocking, we wait here manually.
-            int count = 0;
-            while (bridge.hasInitialDeviceList() == false) {
-                try {
-                    Thread.sleep(100);
-                    count++;
-                } catch (InterruptedException e) {
-                    // pass
-                }
-
-                // let's not wait > 10 sec.
-                if (count > 100) {
-                    System.err.println("Timeout getting device list!");
-                    return;
-                }
-            }
-
-            // now get the devices
-            IDevice[] devices = bridge.getDevices();
-
-            if (devices.length == 0) {
-                printAndExit("No devices found!", true /* terminate */);
-            }
-
-            IDevice target = null;
-
-            if (emulator || device) {
-                for (IDevice d : devices) {
-                    // this test works because emulator and device can't both be true at the same
-                    // time.
-                    if (d.isEmulator() == emulator) {
-                        // if we already found a valid target, we print an error and return.
-                        if (target != null) {
-                            if (emulator) {
-                                printAndExit("Error: more than one emulator launched!",
-                                        true /* terminate */);
-                            } else {
-                                printAndExit("Error: more than one device connected!",true /* terminate */);
-                            }
-                        }
-                        target = d;
-                    }
-                }
-            } else if (serial != null) {
-                for (IDevice d : devices) {
-                    if (serial.equals(d.getSerialNumber())) {
-                        target = d;
-                        break;
-                    }
-                }
-            } else {
-                if (devices.length > 1) {
-                    printAndExit("Error: more than one emulator or device available!",
-                            true /* terminate */);
-                }
-                target = devices[0];
-            }
-
-            if (target != null) {
-                try {
-                    System.out.println("Taking screenshot from: " + target.getSerialNumber());
-                    getDeviceImage(target, filepath, landscape);
-                    System.out.println("Success.");
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            } else {
-                printAndExit("Could not find matching device/emulator.", true /* terminate */);
-            }
-        } finally {
-            AndroidDebugBridge.terminate();
-        }
-    }
-
-    /*
-     * Grab an image from an ADB-connected device.
-     */
-    private static void getDeviceImage(IDevice device, String filepath, boolean landscape)
-            throws IOException {
-        RawImage rawImage;
-
-        try {
-            rawImage = device.getScreenshot();
-        }
-        catch (IOException ioe) {
-            printAndExit("Unable to get frame buffer: " + ioe.getMessage(), true /* terminate */);
-            return;
-        }
-
-        // device/adb not available?
-        if (rawImage == null)
-            return;
-
-        if (landscape) {
-            rawImage = rawImage.getRotated();
-        }
-
-        // convert raw data to an Image
-        BufferedImage image = new BufferedImage(rawImage.width, rawImage.height,
-                BufferedImage.TYPE_INT_ARGB);
-
-        int index = 0;
-        int IndexInc = rawImage.bpp >> 3;
-        for (int y = 0 ; y < rawImage.height ; y++) {
-            for (int x = 0 ; x < rawImage.width ; x++) {
-                int value = rawImage.getARGB(index);
-                index += IndexInc;
-                image.setRGB(x, y, value);
-            }
-        }
-
-        if (!ImageIO.write(image, "png", new File(filepath))) {
-            throw new IOException("Failed to find png writer");
-        }
-    }
-
-    private static void printUsageAndQuit() {
-        // 80 cols marker:  01234567890123456789012345678901234567890123456789012345678901234567890123456789
-        System.out.println("Usage: screenshot2 [-d | -e | -s SERIAL] [-l] OUT_FILE");
-        System.out.println("");
-        System.out.println("    -d      Uses the first device found.");
-        System.out.println("    -e      Uses the first emulator found.");
-        System.out.println("    -s      Targets the device by serial number.");
-        System.out.println("");
-        System.out.println("    -l      Rotate images for landscape mode.");
-        System.out.println("");
-
-        System.exit(1);
-    }
-
-    private static void printAndExit(String message, boolean terminate) {
-        System.out.println(message);
-        if (terminate) {
-            AndroidDebugBridge.terminate();
-        }
-        System.exit(1);
-    }
-}
diff --git a/tools/scripts/AndroidManifest.alias.template b/tools/scripts/AndroidManifest.alias.template
deleted file mode 100644
index 6606d3d..0000000
--- a/tools/scripts/AndroidManifest.alias.template
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-ALIAS PROJECTS ARE CURRENT NOT SUPPORTED.
-THIS FILE IS CURRENTLY BROKEN AND SHOULD NOT BE USED.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="PACKAGE"
-      android:versionCode="1"
-      android:versionName="1.0">
-    <application android:hasCode="false">
-        <activity android:name="android.app.AliasActivity" android:label="@string/app_name">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-            <meta-data android:name="android.app.alias" android:resource="@xml/alias" />
-        </activity>
-    </application>
-</manifest> 
diff --git a/tools/scripts/AndroidManifest.template b/tools/scripts/AndroidManifest.template
deleted file mode 100644
index f14f147..0000000
--- a/tools/scripts/AndroidManifest.template
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="PACKAGE"
-      android:versionCode="1"
-      android:versionName="1.0">
-    <application android:label="@string/app_name" ICON>
-        <activity android:name="ACTIVITY_ENTRY_NAME"
-                  android:label="@string/app_name">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest> 
diff --git a/tools/scripts/AndroidManifest.tests.template b/tools/scripts/AndroidManifest.tests.template
deleted file mode 100644
index c74ff6d..0000000
--- a/tools/scripts/AndroidManifest.tests.template
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="PACKAGE.tests"
-          android:versionCode="1"
-          android:versionName="1.0">
-    <!-- We add an application tag here just so that we can indicate that
-         this package needs to link against the android.test library,
-         which is needed when building test cases. -->
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <!--
-    This declares that this application uses the instrumentation test runner targeting
-    the package of PACKAGE.  To run the tests use the command:
-    "adb shell am instrument -w PACKAGE.tests/android.test.InstrumentationTestRunner"
-    -->
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-                     android:targetPackage="PACKAGE"
-                     android:label="Tests for PACKAGE"/>
-</manifest>
diff --git a/tools/scripts/README_add-ons.txt b/tools/scripts/README_add-ons.txt
deleted file mode 100644
index b8eb1d6..0000000
--- a/tools/scripts/README_add-ons.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Add-on folder.
-Drop vendor supplied SDK add-on in this folder.
\ No newline at end of file
diff --git a/tools/scripts/add-accounts b/tools/scripts/add-accounts
deleted file mode 100755
index d2cddc0..0000000
--- a/tools/scripts/add-accounts
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-
-"""
-A faux Setup Wizard.  Stuffs one or two usernames + passwords into the
-database on the device.
-"""
-
-import sys
-if sys.hexversion < 0x02040000:
-  print "This script requires python 2.4 or higher."
-  sys.exit(1)
-
-import getpass
-import subprocess
-import time
-import sha
-
-DB = "/data/data/com.google.android.googleapps/databases/accounts.db"
-
-def RunCmd(args):
-  proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-  out = proc.stdout.read()
-  if proc.wait():
-    print
-    print "failed: %s" % " ".join(args)
-    return None
-  return out
-
-def GetProp(adb_flags, name):
-  args = ("adb",) + adb_flags + ("shell", "su", "root",
-                                 "/system/bin/getprop", name)
-  return RunCmd(args)
-
-def SetProp(adb_flags, name, value):
-  args = ("adb",) + adb_flags + ("shell", "su", "root",
-                                 "/system/bin/setprop", name, value)
-  return RunCmd(args)
-
-def DbExists(adb_flags):
-  args = ("adb",) + adb_flags + ("shell", "su", "root",
-                                 "/system/bin/ls", DB)
-  result = RunCmd(args)
-  if result is None: return None
-  return "No such file" not in result
-
-def main(argv):
-  if len(argv) == 1:
-    print ("usage: %s [adb flags] "
-           "[<dasher address[:password]>] "
-           "[<gmail address[:password]>]") % (argv[0],)
-    sys.exit(2)
-
-  argv = argv[1:]
-
-  gmail = None
-  dasher = None
-  while argv and "@" in argv[-1]:
-    addr = argv.pop()
-    if "@gmail.com" in addr or "@googlemail.com" in addr:
-      gmail = addr
-    else:
-      dasher = addr
-
-  adb_flags = tuple(argv)
-
-  while True:
-    db = DbExists(adb_flags)
-    if db is None:
-      print "failed to contact device; will retry in 3 seconds"
-      time.sleep(3)
-      continue
-
-    if db:
-      print
-      print "GoogleLoginService has already started on this device;"
-      print "it's too late to use this script to add accounts."
-      print
-      print "This script only works on a freshly-wiped device (or "
-      print "emulator) while booting for the first time."
-      print
-      break
-
-    hosted_account = GetProp(adb_flags, "ro.config.hosted_account").strip()
-    google_account = GetProp(adb_flags, "ro.config.google_account").strip()
-
-    if dasher and hosted_account:
-      print
-      print "A dasher account is already configured on this device;"
-      print "can't add", hosted_account
-      print
-      dasher = None
-
-    if gmail and google_account:
-      print
-      print "A google account is already configured on this device;"
-      print "can't add", google_account
-      print
-      gmail = None
-
-    if not gmail and not dasher: break
-
-    if dasher:
-      SetProp(adb_flags, "ro.config.hosted_account", dasher)
-      print "set hosted_account to", dasher
-    if gmail:
-      SetProp(adb_flags, "ro.config.google_account", gmail)
-      print "set google_account to", gmail
-
-    break
-
-
-
-
-
-
-if __name__ == "__main__":
-  main(sys.argv)
diff --git a/tools/scripts/add-accounts-sdk b/tools/scripts/add-accounts-sdk
deleted file mode 100755
index bb3447f..0000000
--- a/tools/scripts/add-accounts-sdk
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-
-"""
-A faux Setup Wizard.  Stuffs one or two usernames + passwords into the
-database on the device.
-"""
-
-import sys
-if sys.hexversion < 0x02040000:
-  print "This script requires python 2.4 or higher."
-  sys.exit(1)
-
-import getpass
-import subprocess
-import time
-import sha
-
-DB = "/data/data/com.google.android.googleapps/databases/accounts.db"
-
-def RunCmd(args):
-  proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-  out = proc.stdout.read()
-  if proc.wait():
-    print
-    print "failed: %s" % " ".join(args)
-    return None
-  return out
-
-def GetProp(adb_flags, name):
-  args = ("adb",) + adb_flags + ("shell", "/system/bin/getprop", name)
-  return RunCmd(args)
-
-def SetProp(adb_flags, name, value):
-  args = ("adb",) + adb_flags + ("shell", "/system/bin/setprop", name, value)
-  return RunCmd(args)
-
-def DbExists(adb_flags):
-  args = ("adb",) + adb_flags + ("shell", "/system/bin/ls", DB)
-  result = RunCmd(args)
-  if result is None: return None
-  return "No such file" not in result
-
-def main(argv):
-  if len(argv) == 1:
-    print ("usage: %s [adb flags] "
-           "[<hosted address[:password]>] "
-           "[<gmail address[:password]>]") % (argv[0],)
-    sys.exit(2)
-
-  argv = argv[1:]
-
-  gmail = None
-  hosted = None
-  while argv and "@" in argv[-1]:
-    addr = argv.pop()
-    if "@gmail.com" in addr or "@googlemail.com" in addr:
-      gmail = addr
-    else:
-      hosted = addr
-
-  adb_flags = tuple(argv)
-
-  while True:
-    db = DbExists(adb_flags)
-    if db is None:
-      print "failed to contact device; will retry in 3 seconds"
-      time.sleep(3)
-      continue
-
-    if db:
-      print
-      print "GoogleLoginService has already started on this device;"
-      print "it's too late to use this script to add accounts."
-      print
-      print "This script only works on a freshly-wiped device (or "
-      print "emulator) while booting for the first time."
-      print
-      break
-
-    hosted_account = GetProp(adb_flags, "ro.config.hosted_account").strip()
-    google_account = GetProp(adb_flags, "ro.config.google_account").strip()
-
-    if hosted and hosted_account:
-      print
-      print "A hosted account is already configured on this device;"
-      print "can't add", hosted_account
-      print
-      hosted = None
-
-    if gmail and google_account:
-      print
-      print "A google account is already configured on this device;"
-      print "can't add", google_account
-      print
-      gmail = None
-
-    if not gmail and not hosted: break
-
-    if hosted:
-      SetProp(adb_flags, "ro.config.hosted_account", hosted)
-      print "set hosted_account to", hosted
-    if gmail:
-      SetProp(adb_flags, "ro.config.google_account", gmail)
-      print "set google_account to", gmail
-
-    break
-
-
-
-
-
-
-if __name__ == "__main__":
-  main(sys.argv)
diff --git a/tools/scripts/alias.template b/tools/scripts/alias.template
deleted file mode 100644
index 14899ce..0000000
--- a/tools/scripts/alias.template
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-ALIAS PROJECTS ARE CURRENT NOT SUPPORTED.
-THIS FILE IS CURRENTLY BROKEN AND SHOULD NOT BE USED.
--->
-<alias xmlns:android="http://schemas.android.com/apk/res/android">
-    <intent android:action="android.intent.action.VIEW"
-        android:data="ALIASDATA"/>
-</alias>
\ No newline at end of file
diff --git a/tools/scripts/alias_rules.xml b/tools/scripts/alias_rules.xml
deleted file mode 100644
index 273da45..0000000
--- a/tools/scripts/alias_rules.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-ALIAS PROJECTS ARE CURRENT NOT SUPPORTED.
-THIS FILE IS CURRENTLY BROKEN AND SHOULD NOT BE USED.
--->
-<project name="alias_rules" default="package">
-
-    <!-- No user serviceable parts below. -->
-
-    <!-- Input directories -->
-    <property name="resource.dir" value="res" />
-
-    <!-- The final package file to generate -->
-    <property name="out.package" value="${ant.project.name}.apk" />
-
-    <!-- Tools -->
-    <condition property="aapt" value="${android.tools.dir}/aapt.exe" else="${android.tools.dir}/aapt">
-        <os family="windows" />
-    </condition>
-    <condition property="adb" value="${android.tools.dir}/adb.exe" else="${android.tools.dir}/adb">
-        <os family="windows" />
-    </condition>
-    <property name="android.jar" value="${sdk.dir}/android.jar" />
-
-    <!-- Rules -->
-
-    <!-- Packages the manifest and the resource files -->
-    <target name="package-res">
-        <echo>Packaging resources...</echo>
-        <exec executable="${aapt}" failonerror="true">
-            <arg value="package" />
-            <arg value="-f" />
-            <arg value="-M" />
-            <arg value="AndroidManifest.xml" />
-            <arg value="-S" />
-            <arg value="${resource.dir}" />
-            <arg value="-I" />
-            <arg value="${android.jar}" />
-            <arg value="-F" />
-            <arg value="${out.package}" />
-        </exec>
-    </target>
-
-    <!-- Create the package file for this project from the sources. -->
-    <target name="package" depends="package-res" />
-
-    <!-- Create the package and install package on the default emulator -->
-    <target name="install" depends="package">
-        <echo>Sending package to default emulator...</echo>
-        <exec executable="${adb}" failonerror="true">
-            <arg value="install" />
-            <arg value="${out.package}" />
-        </exec>
-    </target>
-
-</project>
diff --git a/tools/scripts/android.el b/tools/scripts/android.el
deleted file mode 100644
index 49f2f1e..0000000
--- a/tools/scripts/android.el
+++ /dev/null
@@ -1,131 +0,0 @@
-;;;; Copyright 2007 The Android Open Source Project
-
-;;; Set up GUD+JDB to attach to a Java process running on the phone or
-;;; under the emulator.
-
-(defvar android-jdb-port-history '("8700")
- "history of ports supplied to `android-jdb'")
-
-(defvar android-jdb-project-root-history '()
- "history of project roots supplied to `android-jdb'")
-(defvar android-jdb-history nil
- "history of commands supplied to `android-jdb'")
-
-(defvar android-jdb-activity-class-history ()
- "history of activity classes supplied to `start-android-activity'")
-
-(defcustom  android-jdb-command-name "jdb"
-  "Name of Java debugger."
-  :type 'string
-  :group 'android)
-
-(defgroup android nil
-  "Android Applications."
-  :group 'applications)
-
-(defcustom android-project-root nil
- "This is where your Android project root is stored."
-  :type 'directory
- :group 'android )
-
-(defcustom android-apk nil
- "This is where your Android Application Package is stored."
- :type 'string
- :group 'android)
-
-(defcustom android-activity-class nil
- "This is where your Android Activity class is stored."
- :type 'string
- :group 'android)
-
-(defun android-read-project-root ()
- (if (or (string-match "XEmacs" emacs-version)
-         (>= emacs-major-version 22))
-     (read-file-name "Android project root: "
-                     android-project-root
-                     nil
-                     t
-                     nil
-                     'file-directory-p)
-   (labels ((read-directory ()
-                            (read-file-name "Android project root: "
-                                            android-project-root
-                                            nil
-                                            t
-                                            nil)))
-     (do ((entered-root (read-directory) (read-directory)))
-         ((and entered-root
-               (file-directory-p entered-root))
-          (expand-file-name entered-root))))))
-
-(defun android-jdb (port root)
- "Set GUD+JDB up to run against Android on PORT in directory ROOT."
- (interactive
-  (list
-   (read-from-minibuffer "Activity's JDWP DDMS port: "
-                     (car android-jdb-port-history)
-                     nil
-                     t
-                     'android-jdb-port-history)
-                    (android-read-project-root)))
- (setq android-project-root root)
- (let ((jdb-command
-        (format "%s -attach localhost:%s -sourcepath%s"
-                android-jdb-command-name
-                port
-                (format "%s/src" root))))
-   (if (not (string= jdb-command (car android-jdb-history)))
-       (push jdb-command android-jdb-history))
-   (jdb jdb-command)))
-
-(defun android-emulate ()
- "Run the Android emulator. This expects the SDK tools directory to be in the current path."
- (interactive)
- (compile "emulator"))
-
-(defun android-install-app (apk)
-  "Install an Android application package APK in the Android emulator. This expects the SDK tools directory to be in the current path."
-  (interactive (list (expand-file-name
-                      (read-file-name "Android Application Package (.apk): "
-                                      nil
-                                      android-apk
-                                      t
-                                      nil
-                                      nil))))
-  (setq android-apk apk)
-  (compile (format "adb install -r %s" apk)))
-
-(defun android-uninstall-app (package-name)
-  "Uninstall an Android application package APK in the Android emulator. This expects the SDK tools directory to be in the current path.
-Specify the package name --- and not the name of the application e.g., com.android.foo."
-  (interactive
-   (list
-    (read-from-minibuffer "Package: ")))
-  (compile (format "adb install -r %s" package)))
-
-(defun android-start-activity (package class)
- "Start the activity PACKAGE/CLASS in the Android emulator. This expects the SDK tools directory to be in the current path."
- (interactive
-  (list
-   (read-from-minibuffer "Package: ")
-   (read-from-minibuffer "Activity Java class: "
-         (car android-jdb-activity-class-history)
-         nil
-         t
-         'android-jdb-activity-class-history)))
- (compile (format "adb shell am start -n %s/%s" package class)))
-
-(defun android-debug-activity (package class)
- "Start the activity PACKAGE/CLASS within the debugger in the Android emulator. This expects the SDK tools directory to be in the current path."
- (interactive
-  (list
-   (read-from-minibuffer "Package: ")
-   (read-from-minibuffer "Activity Java class: "
-         (car android-jdb-activity-class-history)
-         nil
-         t
-         'android-jdb-activity-class-history)))
- (compile (format "adb shell am start -D -n %s/%s" package class)))
-
-(provide 'android)
-
diff --git a/tools/scripts/android_rules.xml b/tools/scripts/android_rules.xml
deleted file mode 100644
index 675017c..0000000
--- a/tools/scripts/android_rules.xml
+++ /dev/null
@@ -1,447 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="android_rules" default="debug">
-
-    <!--
-        This rules file is meant to be imported by the custom Ant task:
-            com.android.ant.AndroidInitTask
-
-        The following properties are put in place by the importing task:
-            android.jar, android.aidl, aapt, aidl, and dx
-
-        Additionnaly, the task sets up the following classpath reference:
-            android.target.classpath
-        This is used by the compiler task as the boot classpath.
-    -->
-
-    <!-- Custom tasks -->
-    <taskdef name="aaptexec"
-        classname="com.android.ant.AaptExecLoopTask"
-        classpathref="android.antlibs" />
-
-    <taskdef name="apkbuilder"
-        classname="com.android.ant.ApkBuilderTask"
-        classpathref="android.antlibs" />
-
-    <taskdef name="xpath"
-        classname="com.android.ant.XPathTask"
-        classpathref="android.antlibs" />
-
-    <!-- Properties -->
-
-    <!-- Tells adb which device to target. You can change this from the command line
-         by invoking "ant -Dadb.device.arg=-d" for device "ant -Dadb.device.arg=-e" for
-         the emulator. -->
-    <property name="adb.device.arg" value="" />
-
-    <property name="android.tools.dir" location="${sdk.dir}/tools" />
-    <!-- Name of the application package extracted from manifest file -->
-    <xpath input="AndroidManifest.xml" expression="/manifest/@package"
-                output="manifest.package" />
-
-    <!-- Input directories -->
-    <property name="source.dir" value="src" />
-    <property name="source.absolute.dir" location="${source.dir}" />
-    <property name="gen.dir" value="gen" />
-    <property name="gen.absolute.dir" location="${gen.dir}" />
-    <property name="resource.dir" value="res" />
-    <property name="resource.absolute.dir" location="${resource.dir}" />
-    <property name="asset.dir" value="assets" />
-    <property name="asset.absolute.dir" location="${asset.dir}" />
-
-    <!-- Directory for the third party java libraries -->
-    <property name="external.libs.dir" value="libs" />
-    <property name="external.libs.absolute.dir" location="${external.libs.dir}" />
-
-    <!-- Directory for the native libraries -->
-    <property name="native.libs.dir" value="libs" />
-    <property name="native.libs.absolute.dir" location="${native.libs.dir}" />
-
-    <!-- Output directories -->
-    <property name="out.dir" value="bin" />
-    <property name="out.absolute.dir" location="${out.dir}" />
-    <property name="out.classes.dir" value="${out.absolute.dir}/classes" />
-    <property name="out.classes.absolute.dir" location="${out.classes.dir}" />
-
-    <!-- Intermediate files -->
-    <property name="dex.file.name" value="classes.dex" />
-    <property name="intermediate.dex.file" location="${out.absolute.dir}/${dex.file.name}" />
-
-    <!-- The final package file to generate -->
-    <property name="out.debug.unaligned.package"
-                  location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk" />
-    <property name="out.debug.package"
-                  location="${out.absolute.dir}/${ant.project.name}-debug.apk" />
-    <property name="out.unsigned.package"
-                  location="${out.absolute.dir}/${ant.project.name}-unsigned.apk" />
-    <property name="out.unaligned.package"
-                  location="${out.absolute.dir}/${ant.project.name}-unaligned.apk" />
-    <property name="out.release.package"
-                  location="${out.absolute.dir}/${ant.project.name}-release.apk" />
-
-    <!-- Verbosity -->
-    <property name="verbose" value="false" />
-    <!-- This is needed by emma as it uses multilevel verbosity instead of simple 'true' or 'false'
-         The property 'verbosity' is not user configurable and depends exclusively on 'verbose'
-         value.-->
-    <condition property="verbosity" value="verbose" else="quiet">
-        <istrue value="${verbose}" />
-    </condition>
-    <!-- This is needed to switch verbosity of zipalign and aapt. Depends exclusively on 'verbose'
-         -->
-    <condition property="v.option" value="-v" else="">
-        <istrue value="${verbose}" />
-    </condition>
-    <!-- This is needed to switch verbosity of dx. Depends exclusively on 'verbose' -->
-    <condition property="verbose.option" value="--verbose" else="">
-        <istrue value="${verbose}" />
-    </condition>
-
-    <!-- Tools -->
-    <condition property="exe" value=".exe" else=""><os family="windows" /></condition>
-    <property name="adb" location="${android.tools.dir}/adb${exe}" />
-    <property name="zipalign" location="${android.tools.dir}/zipalign${exe}" />
-
-    <!-- Emma configuration -->
-    <property name="emma.dir" value="${sdk.dir}/tools/lib" />
-        <path id="emma.lib">
-            <pathelement location="${emma.dir}/emma.jar" />
-            <pathelement location="${emma.dir}/emma_ant.jar" />
-        </path>
-    <taskdef resource="emma_ant.properties" classpathref="emma.lib" />
-    <!-- End of emma configuration -->
-
-    <!-- Macros -->
-
-    <!-- Configurable macro, which allows to pass as parameters output directory,
-         output dex filename and external libraries to dex (optional) -->
-    <macrodef name="dex-helper">
-       <element name="external-libs" optional="yes" />
-       <element name="extra-parameters" optional="yes" />
-       <sequential>
-         <echo>Converting compiled files and external libraries into ${intermediate.dex.file}...
-         </echo>
-         <apply executable="${dx}" failonerror="true" parallel="true">
-             <arg value="--dex" />
-             <arg value="--output=${intermediate.dex.file}" />
-             <extra-parameters />
-             <arg line="${verbose.option}" />
-             <arg path="${out.classes.absolute.dir}" />
-             <fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
-             <external-libs />
-         </apply>
-       </sequential>
-    </macrodef>
-
-    <!-- This is macro that enable passing variable list of external jar files to ApkBuilder
-         Example of use:
-         <package-helper>
-             <extra-jars>
-                <jarfolder path="my_jars" />
-                <jarfile path="foo/bar.jar" />
-                <jarfolder path="your_jars" />
-             </extra-jars>
-         </package-helper> -->
-    <macrodef name="package-helper">
-        <attribute name="sign.package" />
-        <element name="extra-jars" optional="yes" />
-        <sequential>
-            <apkbuilder
-                    outfolder="${out.absolute.dir}"
-                    basename="${ant.project.name}"
-                    signed="@{sign.package}"
-                    verbose="${verbose}">
-                <file path="${intermediate.dex.file}" />
-                <sourcefolder path="${source.absolute.dir}" />
-                <nativefolder path="${native.libs.absolute.dir}" />
-                <jarfolder path="${external.libs.absolute.dir}" />
-                <extra-jars/>
-            </apkbuilder>
-        </sequential>
-    </macrodef>
-
-    <!-- This is macro which zipaligns in.package and outputs it to out.package. Used by targets
-         debug, -debug-with-emma and release.-->
-    <macrodef name="zipalign-helper">
-        <attribute name="in.package" />
-        <attribute name="out.package" />
-        <sequential>
-            <echo>Running zip align on final apk...</echo>
-            <exec executable="${zipalign}" failonerror="true">
-                <arg line="${v.option}" />
-                <arg value="-f" />
-                <arg value="4" />
-                <arg path="@{in.package}" />
-                <arg path="@{out.package}" />
-            </exec>
-        </sequential>
-    </macrodef>
-
-    <!-- This is macro used only for sharing code among two targets, -install and
-         -install-with-emma which do exactly the same but differ in dependencies -->
-    <macrodef name="install-helper">
-        <sequential>
-            <echo>Installing ${out.debug.package} onto default emulator or device...</echo>
-            <exec executable="${adb}" failonerror="true">
-                <arg line="${adb.device.arg}" />
-                <arg value="install" />
-                <arg value="-r" />
-                <arg path="${out.debug.package}" />
-            </exec>
-        </sequential>
-    </macrodef>
-
-    <!-- Rules -->
-
-    <!-- Creates the output directories if they don't exist yet. -->
-    <target name="-dirs">
-        <echo>Creating output directories if needed...</echo>
-        <mkdir dir="${resource.absolute.dir}" />
-        <mkdir dir="${external.libs.absolute.dir}" />
-        <mkdir dir="${gen.absolute.dir}" />
-        <mkdir dir="${out.absolute.dir}" />
-        <mkdir dir="${out.classes.absolute.dir}" />
-    </target>
-
-    <!-- Generates the R.java file for this project's resources. -->
-    <target name="-resource-src" depends="-dirs">
-        <echo>Generating R.java / Manifest.java from the resources...</echo>
-        <exec executable="${aapt}" failonerror="true">
-            <arg value="package" />
-            <arg line="${v.option}" />
-            <arg value="-m" />
-            <arg value="-J" />
-            <arg path="${gen.absolute.dir}" />
-            <arg value="-M" />
-            <arg path="AndroidManifest.xml" />
-            <arg value="-S" />
-            <arg path="${resource.absolute.dir}" />
-            <arg value="-I" />
-            <arg path="${android.jar}" />
-        </exec>
-    </target>
-
-    <!-- Generates java classes from .aidl files. -->
-    <target name="-aidl" depends="-dirs">
-        <echo>Compiling aidl files into Java classes...</echo>
-        <apply executable="${aidl}" failonerror="true">
-            <arg value="-p${android.aidl}" />
-            <arg value="-I${source.absolute.dir}" />
-            <arg value="-o${gen.absolute.dir}" />
-            <fileset dir="${source.absolute.dir}">
-                <include name="**/*.aidl" />
-            </fileset>
-        </apply>
-    </target>
-
-    <!-- Compiles this project's .java files into .class files. -->
-    <target name="compile" depends="-resource-src, -aidl"
-                description="Compiles project's .java files into .class files">
-        <!-- If android rules are used for a test project, its classpath should include
-             tested project's location -->
-        <condition property="extensible.classpath"
-                           value="${tested.project.absolute.dir}/bin/classes" else=".">
-            <isset property="tested.project.absolute.dir" />
-        </condition>
-        <javac encoding="ascii" target="1.5" debug="true" extdirs=""
-                destdir="${out.classes.absolute.dir}"
-                bootclasspathref="android.target.classpath"
-                verbose="${verbose}" classpath="${extensible.classpath}">
-            <src path="${source.absolute.dir}" />
-            <src path="${gen.absolute.dir}" />
-            <classpath>
-                <fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
-            </classpath>
-        </javac>
-    </target>
-
-    <!-- Converts this project's .class files into .dex files -->
-    <target name="-dex" depends="compile">
-        <dex-helper />
-    </target>
-
-    <!-- Puts the project's resources into the output package file
-         This actually can create multiple resource package in case
-         Some custom apk with specific configuration have been
-         declared in default.properties.
-         -->
-    <target name="-package-resources">
-        <echo>Packaging resources</echo>
-        <aaptexec executable="${aapt}"
-                command="package"
-                manifest="AndroidManifest.xml"
-                resources="${resource.absolute.dir}"
-                assets="${asset.absolute.dir}"
-                androidjar="${android.jar}"
-                outfolder="${out.absolute.dir}"
-                basename="${ant.project.name}" />
-    </target>
-
-    <!-- Packages the application and sign it with a debug key. -->
-    <target name="-package-debug-sign" depends="-dex, -package-resources">
-        <package-helper sign.package="true" />
-    </target>
-
-    <!-- Packages the application without signing it. -->
-    <target name="-package-no-sign" depends="-dex, -package-resources">
-        <package-helper sign.package="false" />
-    </target>
-
-    <target name="-compile-tested-if-test" if="tested.project.dir" unless="do.not.compile.again">
-       <subant target="compile">
-            <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />
-       </subant>
-    </target>
-
-    <!-- Builds debug output package, provided all the necessary files are already dexed -->
-    <target name="debug" depends="-compile-tested-if-test, -package-debug-sign"
-                description="Builds the application and signs it with a debug key.">
-        <zipalign-helper in.package="${out.debug.unaligned.package}"
-                                   out.package="${out.debug.package}" />
-        <echo>Debug Package: ${out.debug.package}</echo>
-    </target>
-
-    <target name="-release-check">
-        <condition property="release.sign">
-            <and>
-                <isset property="key.store" />
-                <isset property="key.alias" />
-            </and>
-        </condition>
-    </target>
-
-    <target name="-release-nosign" depends="-release-check" unless="release.sign">
-        <echo>No key.store and key.alias properties found in build.properties.</echo>
-        <echo>Please sign ${out.unsigned.package} manually</echo>
-        <echo>and run zipalign from the Android SDK tools.</echo>
-    </target>
-
-    <target name="release" depends="-package-no-sign, -release-nosign" if="release.sign"
-                description="Builds the application. The generated apk file must be signed before
-                            it is published.">
-        <!-- Gets passwords -->
-        <input
-                message="Please enter keystore password (store:${key.store}):"
-                addproperty="key.store.password" />
-        <input
-                message="Please enter password for alias '${key.alias}':"
-                addproperty="key.alias.password" />
-
-        <!-- Signs the APK -->
-        <echo>Signing final apk...</echo>
-        <signjar
-                jar="${out.unsigned.package}"
-                signedjar="${out.unaligned.package}"
-                keystore="${key.store}"
-                storepass="${key.store.password}"
-                alias="${key.alias}"
-                keypass="${key.alias.password}"
-                verbose="${verbose}" />
-
-        <!-- Zip aligns the APK -->
-        <zipalign-helper in.package="${out.unaligned.package}"
-                                   out.package="${out.release.package}" />
-        <echo>Release Package: ${out.release.package}</echo>
-    </target>
-
-    <target name="install" depends="debug"
-                description="Installs/reinstalls the debug package onto a running
-                            emulator or device. If the application was previously installed,
-                            the signatures must match." >
-        <install-helper />
-    </target>
-
-    <target name="-uninstall-check">
-        <condition property="uninstall.run">
-           <isset property="manifest.package" />
-        </condition>
-    </target>
-
-    <target name="-uninstall-error" depends="-uninstall-check" unless="uninstall.run">
-        <echo>Unable to run 'ant uninstall', manifest.package property is not defined.
-        </echo>
-    </target>
-
-    <!-- Uninstalls the package from the default emulator/device -->
-    <target name="uninstall" depends="-uninstall-error" if="uninstall.run"
-                description="Uninstalls the application from a running emulator or device.">
-        <echo>Uninstalling ${manifest.package} from the default emulator or device...</echo>
-        <exec executable="${adb}" failonerror="true">
-            <arg line="${adb.device.arg}" />
-            <arg value="uninstall" />
-            <arg value="${manifest.package}" />
-        </exec>
-    </target>
-
-    <target name="clean" description="Removes output files created by other targets.">
-        <delete dir="${out.absolute.dir}" verbose="${verbose}" />
-        <delete dir="${gen.absolute.dir}" verbose="${verbose}" />
-    </target>
-
-    <!-- Targets for code-coverage measurement purposes, invoked from external file -->
-
-    <!-- Emma-instruments tested project classes (compiles the tested project if necessary)
-             and writes instrumented classes to ${instrumentation.absolute.dir}/classes -->
-    <target name="-emma-instrument" depends="compile">
-        <echo>Instrumenting classes from ${out.absolute.dir}/classes...</echo>
-        <!-- It only instruments class files, not any external libs -->
-        <emma enabled="true">
-            <instr verbosity="${verbosity}"
-                   mode="overwrite"
-                   instrpath="${out.absolute.dir}/classes"
-                   outdir="${out.absolute.dir}/classes">
-            </instr>
-            <!-- TODO: exclusion filters on R*.class and allowing custom exclusion from
-                 user defined file -->
-        </emma>
-    </target>
-
-    <target name="-dex-instrumented" depends="-emma-instrument">
-       <dex-helper>
-          <extra-parameters>
-            <arg value="--no-locals" />
-          </extra-parameters>
-          <external-libs>
-            <fileset file="${emma.dir}/emma_device.jar" />
-          </external-libs>
-       </dex-helper>
-    </target>
-
-    <!-- Invoked from external files for code coverage purposes -->
-    <target name="-package-with-emma" depends="-dex-instrumented, -package-resources">
-        <package-helper sign.package="true">
-            <extra-jars>
-                <!-- Injected from external file -->
-                <jarfile path="${emma.dir}/emma_device.jar" />
-            </extra-jars>
-        </package-helper>
-    </target>
-
-    <target name="-debug-with-emma" depends="-package-with-emma">
-        <zipalign-helper in.package="${out.debug.unaligned.package}"
-                                   out.package="${out.debug.package}" />
-    </target>
-
-    <target name="-install-with-emma" depends="-debug-with-emma">
-        <install-helper />
-    </target>
-
-    <!-- End of targets for code-coverage measurement purposes -->
-
-    <target name="help">
-        <!-- displays starts at col 13
-              |13                                                              80| -->
-        <echo>Android Ant Build. Available targets:</echo>
-        <echo>   help:      Displays this help.</echo>
-        <echo>   clean:     Removes output files created by other targets.</echo>
-        <echo>   compile:   Compiles project's .java files into .class files.</echo>
-        <echo>   debug:     Builds the application and signs it with a debug key.</echo>
-        <echo>   release:   Builds the application. The generated apk file must be</echo>
-        <echo>              signed before it is published.</echo>
-        <echo>   install:   Installs/reinstalls the debug package onto a running</echo>
-        <echo>              emulator or device.</echo>
-        <echo>              If the application was previously installed, the</echo>
-        <echo>              signatures must match.</echo>
-        <echo>   uninstall: Uninstalls the application from a running emulator or</echo>
-        <echo>              device.</echo>
-    </target>
-</project>
diff --git a/tools/scripts/android_test_rules.xml b/tools/scripts/android_test_rules.xml
deleted file mode 100644
index 78503ae..0000000
--- a/tools/scripts/android_test_rules.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="android_test_rules" default="run-tests">
-
-    <import file="android_rules.xml" />
-
-    <property name="tested.project.absolute.dir" location="${tested.project.dir}" />
-    <property name="instrumentation.dir" value="instrumented" />
-    <property name="instrumentation.absolute.dir" location="${instrumentation.dir}" />
-
-    <property name="test.runner" value="android.test.InstrumentationTestRunner" />
-    <!-- Application package of the tested project extracted from its manifest file -->
-    <xpath input="${tested.project.absolute.dir}/AndroidManifest.xml"
-                expression="/manifest/@package" output="tested.manifest.package" />
-
-    <!-- TODO: make it more configurable in the next CL's - now it is default for auto-generated
-         project -->
-    <property name="emma.dump.file"
-                  value="/data/data/${tested.manifest.package}/files/coverage.ec" />
-
-    <macrodef name="run-tests-helper">
-        <attribute name="emma.enabled" default="false" />
-        <element name="extra-instrument-args" optional="yes" />
-        <sequential>
-            <echo>Running tests ...</echo>
-            <exec executable="${adb}" failonerror="true">
-                <arg value="shell" />
-                <arg value="am" />
-                   <arg value="instrument" />
-                <arg value="-w" />
-                <arg value="-e" />
-                   <arg value="coverage" />
-                   <arg value="@{emma.enabled}" />
-                <extra-instrument-args />
-                <arg value="${manifest.package}/${test.runner}" />
-            </exec>
-        </sequential>
-    </macrodef>
-
-    <!-- Invoking this target sets the value of extensible.classpath, which is being added to javac
-         classpath in target 'compile' (android_rules.xml) -->
-    <target name="-set-coverage-classpath">
-        <property name="extensible.classpath"
-                      location="${instrumentation.absolute.dir}/classes" />
-    </target>
-
-    <!-- Ensures that tested project is installed on the device before we run the tests.
-         Used for ordinary tests, without coverage measurement -->
-    <target name="-install-tested-project">
-        <property name="do.not.compile.again" value="true" />
-        <subant target="install">
-            <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />
-        </subant>
-    </target>
-
-    <target name="run-tests" depends="-install-tested-project, install"
-                description="Runs tests from the package defined in test.package property">
-        <run-tests-helper />
-    </target>
-
-    <target name="-install-instrumented">
-        <property name="do.not.compile.again" value="true" />
-        <subant target="-install-with-emma">
-            <property name="out.absolute.dir" value="${instrumentation.absolute.dir}" />
-            <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />
-        </subant>
-    </target>
-
-    <target name="coverage" depends="-set-coverage-classpath, -install-instrumented, install"
-                description="Runs the tests against the instrumented code and generates
-                            code coverage report">
-        <run-tests-helper emma.enabled="true">
-            <extra-instrument-args>
-                <arg value="-e" />
-                   <arg value="coverageFile" />
-                   <arg value="${emma.dump.file}" />
-            </extra-instrument-args>
-        </run-tests-helper>
-        <echo>Downloading coverage file into project directory...</echo>
-        <exec executable="${adb}" failonerror="true">
-            <arg value="pull" />
-            <arg value="${emma.dump.file}" />
-            <arg value="coverage.ec" />
-        </exec>
-        <echo>Extracting coverage report...</echo>
-        <emma>
-            <report sourcepath="${tested.project.absolute.dir}/${source.dir}"
-                              verbosity="${verbosity}">
-                <!-- TODO: report.dir or something like should be introduced if necessary -->
-                <infileset dir=".">
-                    <include name="coverage.ec" />
-                    <include name="coverage.em" />
-                </infileset>
-                <!-- TODO: reports in other, indicated by user formats -->
-                <html outfile="coverage.html" />
-           </report>
-        </emma>
-        <echo>Cleaning up temporary files...</echo>
-        <delete dir="${instrumentation.absolute.dir}" />
-        <delete file="coverage.ec" />
-        <delete file="coverage.em" />
-        <echo>Saving the report file in ${basedir}/coverage/coverage.html</echo>
-    </target>
-
-</project>
diff --git a/tools/scripts/app_engine_server/LICENSE b/tools/scripts/app_engine_server/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/tools/scripts/app_engine_server/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   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.
diff --git a/tools/scripts/app_engine_server/app.yaml b/tools/scripts/app_engine_server/app.yaml
deleted file mode 100755
index 1fb50c7..0000000
--- a/tools/scripts/app_engine_server/app.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-application: androidappdocs-staging
-version: 1
-runtime: python
-api_version: 1
-
-handlers:
-- url: /gae_shell/static
-  static_dir: gae_shell/static
-  expiration: 1d
-
-- url: /gae_shell/.*
-  script: /gae_shell/shell.py
-  login: admin
-
-- url: .*
-  script: main.py
diff --git a/tools/scripts/app_engine_server/gae_shell/README b/tools/scripts/app_engine_server/gae_shell/README
deleted file mode 100644
index 5b0089f..0000000
--- a/tools/scripts/app_engine_server/gae_shell/README
+++ /dev/null
@@ -1,17 +0,0 @@
-An interactive, stateful AJAX shell that runs Python code on the server.
-
-Part of http://code.google.com/p/google-app-engine-samples/.
-
-May be run as a standalone app or in an existing app as an admin-only handler.
-Can be used for system administration tasks, as an interactive way to try out
-APIs, or as a debugging aid during development.
-
-The logging, os, sys, db, and users modules are imported automatically.
-
-Interpreter state is stored in the datastore so that variables, function
-definitions, and other values in the global and local namespaces can be used
-across commands.
-
-To use the shell in your app, copy shell.py, static/*, and templates/* into
-your app's source directory. Then, copy the URL handlers from app.yaml into
-your app.yaml.
diff --git a/tools/scripts/app_engine_server/gae_shell/__init__.py b/tools/scripts/app_engine_server/gae_shell/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tools/scripts/app_engine_server/gae_shell/__init__.py
+++ /dev/null
diff --git a/tools/scripts/app_engine_server/gae_shell/__init__.pyc b/tools/scripts/app_engine_server/gae_shell/__init__.pyc
deleted file mode 100644
index 84951e9..0000000
--- a/tools/scripts/app_engine_server/gae_shell/__init__.pyc
+++ /dev/null
Binary files differ
diff --git a/tools/scripts/app_engine_server/gae_shell/shell.py b/tools/scripts/app_engine_server/gae_shell/shell.py
deleted file mode 100755
index df2fb17..0000000
--- a/tools/scripts/app_engine_server/gae_shell/shell.py
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2007 Google Inc.
-#
-# 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.
-
-"""
-An interactive, stateful AJAX shell that runs Python code on the server.
-
-Part of http://code.google.com/p/google-app-engine-samples/.
-
-May be run as a standalone app or in an existing app as an admin-only handler.
-Can be used for system administration tasks, as an interactive way to try out
-APIs, or as a debugging aid during development.
-
-The logging, os, sys, db, and users modules are imported automatically.
-
-Interpreter state is stored in the datastore so that variables, function
-definitions, and other values in the global and local namespaces can be used
-across commands.
-
-To use the shell in your app, copy shell.py, static/*, and templates/* into
-your app's source directory. Then, copy the URL handlers from app.yaml into
-your app.yaml.
-
-TODO: unit tests!
-"""
-
-import logging
-import new
-import os
-import pickle
-import sys
-import traceback
-import types
-import wsgiref.handlers
-
-from google.appengine.api import users
-from google.appengine.ext import db
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp import template
-
-
-# Set to True if stack traces should be shown in the browser, etc.
-_DEBUG = True
-
-# The entity kind for shell sessions. Feel free to rename to suit your app.
-_SESSION_KIND = '_Shell_Session'
-
-# Types that can't be pickled.
-UNPICKLABLE_TYPES = (
-  types.ModuleType,
-  types.TypeType,
-  types.ClassType,
-  types.FunctionType,
-  )
-
-# Unpicklable statements to seed new sessions with.
-INITIAL_UNPICKLABLES = [
-  'import logging',
-  'import os',
-  'import sys',
-  'from google.appengine.ext import db',
-  'from google.appengine.api import users',
-  ]
-
-
-class Session(db.Model):
-  """A shell session. Stores the session's globals.
-
-  Each session globals is stored in one of two places:
-
-  If the global is picklable, it's stored in the parallel globals and
-  global_names list properties. (They're parallel lists to work around the
-  unfortunate fact that the datastore can't store dictionaries natively.)
-
-  If the global is not picklable (e.g. modules, classes, and functions), or if
-  it was created by the same statement that created an unpicklable global,
-  it's not stored directly. Instead, the statement is stored in the
-  unpicklables list property. On each request, before executing the current
-  statement, the unpicklable statements are evaluated to recreate the
-  unpicklable globals.
-
-  The unpicklable_names property stores all of the names of globals that were
-  added by unpicklable statements. When we pickle and store the globals after
-  executing a statement, we skip the ones in unpicklable_names.
-
-  Using Text instead of string is an optimization. We don't query on any of
-  these properties, so they don't need to be indexed.
-  """
-  global_names = db.ListProperty(db.Text)
-  globals = db.ListProperty(db.Blob)
-  unpicklable_names = db.ListProperty(db.Text)
-  unpicklables = db.ListProperty(db.Text)
-
-  def set_global(self, name, value):
-    """Adds a global, or updates it if it already exists.
-
-    Also removes the global from the list of unpicklable names.
-
-    Args:
-      name: the name of the global to remove
-      value: any picklable value
-    """
-    blob = db.Blob(pickle.dumps(value))
-
-    if name in self.global_names:
-      index = self.global_names.index(name)
-      self.globals[index] = blob
-    else:
-      self.global_names.append(db.Text(name))
-      self.globals.append(blob)
-
-    self.remove_unpicklable_name(name)
-
-  def remove_global(self, name):
-    """Removes a global, if it exists.
-
-    Args:
-      name: string, the name of the global to remove
-    """
-    if name in self.global_names:
-      index = self.global_names.index(name)
-      del self.global_names[index]
-      del self.globals[index]
-
-  def globals_dict(self):
-    """Returns a dictionary view of the globals.
-    """
-    return dict((name, pickle.loads(val))
-                for name, val in zip(self.global_names, self.globals))
-
-  def add_unpicklable(self, statement, names):
-    """Adds a statement and list of names to the unpicklables.
-
-    Also removes the names from the globals.
-
-    Args:
-      statement: string, the statement that created new unpicklable global(s).
-      names: list of strings; the names of the globals created by the statement.
-    """
-    self.unpicklables.append(db.Text(statement))
-
-    for name in names:
-      self.remove_global(name)
-      if name not in self.unpicklable_names:
-        self.unpicklable_names.append(db.Text(name))
-
-  def remove_unpicklable_name(self, name):
-    """Removes a name from the list of unpicklable names, if it exists.
-
-    Args:
-      name: string, the name of the unpicklable global to remove
-    """
-    if name in self.unpicklable_names:
-      self.unpicklable_names.remove(name)
-
-
-class FrontPageHandler(webapp.RequestHandler):
-  """Creates a new session and renders the shell.html template.
-  """
-
-  def get(self):
-    # set up the session. TODO: garbage collect old shell sessions
-    session_key = self.request.get('session')
-    if session_key:
-      session = Session.get(session_key)
-    else:
-      # create a new session
-      session = Session()
-      session.unpicklables = [db.Text(line) for line in INITIAL_UNPICKLABLES]
-      session_key = session.put()
-
-    template_file = os.path.join(os.path.dirname(__file__), 'templates',
-                                 'shell.html')
-    session_url = '/?session=%s' % session_key
-    vars = { 'server_software': os.environ['SERVER_SOFTWARE'],
-             'python_version': sys.version,
-             'session': str(session_key),
-             'user': users.get_current_user(),
-             'login_url': users.create_login_url(session_url),
-             'logout_url': users.create_logout_url(session_url),
-             }
-    rendered = webapp.template.render(template_file, vars, debug=_DEBUG)
-    self.response.out.write(rendered)
-
-
-class StatementHandler(webapp.RequestHandler):
-  """Evaluates a python statement in a given session and returns the result.
-  """
-
-  def get(self):
-    self.response.headers['Content-Type'] = 'text/plain'
-
-    # extract the statement to be run
-    statement = self.request.get('statement')
-    if not statement:
-      return
-
-    # the python compiler doesn't like network line endings
-    statement = statement.replace('\r\n', '\n')
-
-    # add a couple newlines at the end of the statement. this makes
-    # single-line expressions such as 'class Foo: pass' evaluate happily.
-    statement += '\n\n'
-
-    # log and compile the statement up front
-    try:
-      logging.info('Compiling and evaluating:\n%s' % statement)
-      compiled = compile(statement, '<string>', 'single')
-    except:
-      self.response.out.write(traceback.format_exc())
-      return
-
-    # create a dedicated module to be used as this statement's __main__
-    statement_module = new.module('__main__')
-
-    # use this request's __builtin__, since it changes on each request.
-    # this is needed for import statements, among other things.
-    import __builtin__
-    statement_module.__builtins__ = __builtin__
-
-    # load the session from the datastore
-    session = Session.get(self.request.get('session'))
-
-    # swap in our custom module for __main__. then unpickle the session
-    # globals, run the statement, and re-pickle the session globals, all
-    # inside it.
-    old_main = sys.modules.get('__main__')
-    try:
-      sys.modules['__main__'] = statement_module
-      statement_module.__name__ = '__main__'
-
-      # re-evaluate the unpicklables
-      for code in session.unpicklables:
-        exec code in statement_module.__dict__
-
-      # re-initialize the globals
-      for name, val in session.globals_dict().items():
-        try:
-          statement_module.__dict__[name] = val
-        except:
-          msg = 'Dropping %s since it could not be unpickled.\n' % name
-          self.response.out.write(msg)
-          logging.warning(msg + traceback.format_exc())
-          session.remove_global(name)
-
-      # run!
-      old_globals = dict(statement_module.__dict__)
-      try:
-        old_stdout = sys.stdout
-        old_stderr = sys.stderr
-        try:
-          sys.stdout = self.response.out
-          sys.stderr = self.response.out
-          exec compiled in statement_module.__dict__
-        finally:
-          sys.stdout = old_stdout
-          sys.stderr = old_stderr
-      except:
-        self.response.out.write(traceback.format_exc())
-        return
-
-      # extract the new globals that this statement added
-      new_globals = {}
-      for name, val in statement_module.__dict__.items():
-        if name not in old_globals or val != old_globals[name]:
-          new_globals[name] = val
-
-      if True in [isinstance(val, UNPICKLABLE_TYPES)
-                  for val in new_globals.values()]:
-        # this statement added an unpicklable global. store the statement and
-        # the names of all of the globals it added in the unpicklables.
-        session.add_unpicklable(statement, new_globals.keys())
-        logging.debug('Storing this statement as an unpicklable.')
-
-      else:
-        # this statement didn't add any unpicklables. pickle and store the
-        # new globals back into the datastore.
-        for name, val in new_globals.items():
-          if not name.startswith('__'):
-            session.set_global(name, val)
-
-    finally:
-      sys.modules['__main__'] = old_main
-
-    session.put()
-
-
-def main():
-  application = webapp.WSGIApplication(
-    [('/gae_shell/', FrontPageHandler),
-     ('/gae_shell/shell.do', StatementHandler)], debug=_DEBUG)
-  wsgiref.handlers.CGIHandler().run(application)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/scripts/app_engine_server/gae_shell/static/shell.js b/tools/scripts/app_engine_server/gae_shell/static/shell.js
deleted file mode 100644
index 4aa1583..0000000
--- a/tools/scripts/app_engine_server/gae_shell/static/shell.js
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2007 Google Inc.
-//
-// 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.
-
-/**
- * @fileoverview
- * Javascript code for the interactive AJAX shell.
- *
- * Part of http://code.google.com/p/google-app-engine-samples/.
- *
- * Includes a function (shell.runStatement) that sends the current python
- * statement in the shell prompt text box to the server, and a callback
- * (shell.done) that displays the results when the XmlHttpRequest returns.
- *
- * Also includes cross-browser code (shell.getXmlHttpRequest) to get an
- * XmlHttpRequest.
- */
-
-/**
- * Shell namespace.
- * @type {Object}
- */
-var shell = {}
-
-/**
- * The shell history. history is an array of strings, ordered oldest to
- * newest. historyCursor is the current history element that the user is on.
- *
- * The last history element is the statement that the user is currently
- * typing. When a statement is run, it's frozen in the history, a new history
- * element is added to the end of the array for the new statement, and
- * historyCursor is updated to point to the new element.
- *
- * @type {Array}
- */
-shell.history = [''];
-
-/**
- * See {shell.history}
- * @type {number}
- */
-shell.historyCursor = 0;
-
-/**
- * A constant for the XmlHttpRequest 'done' state.
- * @type Number
- */
-shell.DONE_STATE = 4;
-
-/**
- * A cross-browser function to get an XmlHttpRequest object.
- *
- * @return {XmlHttpRequest?} a new XmlHttpRequest
- */
-shell.getXmlHttpRequest = function() {
-  if (window.XMLHttpRequest) {
-    return new XMLHttpRequest();
-  } else if (window.ActiveXObject) {
-    try {
-      return new ActiveXObject('Msxml2.XMLHTTP');
-    } catch(e) {
-      return new ActiveXObject('Microsoft.XMLHTTP');
-    }
-  }
-
-  return null;
-};
-
-/**
- * This is the prompt textarea's onkeypress handler. Depending on the key that
- * was pressed, it will run the statement, navigate the history, or update the
- * current statement in the history.
- *
- * @param {Event} event the keypress event
- * @return {Boolean} false to tell the browser not to submit the form.
- */
-shell.onPromptKeyPress = function(event) {
-  var statement = document.getElementById('statement');
-
-  if (this.historyCursor == this.history.length - 1) {
-    // we're on the current statement. update it in the history before doing
-    // anything.
-    this.history[this.historyCursor] = statement.value;
-  }
-
-  // should we pull something from the history?
-  if (event.ctrlKey && event.keyCode == 38 /* up arrow */) {
-    if (this.historyCursor > 0) {
-      statement.value = this.history[--this.historyCursor];
-    }
-    return false;
-  } else if (event.ctrlKey && event.keyCode == 40 /* down arrow */) {
-    if (this.historyCursor < this.history.length - 1) {
-      statement.value = this.history[++this.historyCursor];
-    }
-    return false;
-  } else if (!event.altKey) {
-    // probably changing the statement. update it in the history.
-    this.historyCursor = this.history.length - 1;
-    this.history[this.historyCursor] = statement.value;
-  }
-
-  // should we submit?
-  var ctrlEnter = (document.getElementById('submit_key').value == 'ctrl-enter');
-  if (event.keyCode == 13 /* enter */ && !event.altKey && !event.shiftKey &&
-      event.ctrlKey == ctrlEnter) {
-    return this.runStatement();
-  }
-};
-
-/**
- * The XmlHttpRequest callback. If the request succeeds, it adds the command
- * and its resulting output to the shell history div.
- *
- * @param {XmlHttpRequest} req the XmlHttpRequest we used to send the current
- *     statement to the server
- */
-shell.done = function(req) {
-  if (req.readyState == this.DONE_STATE) {
-    var statement = document.getElementById('statement')
-    statement.className = 'prompt';
-
-    // add the command to the shell output
-    var output = document.getElementById('output');
-
-    output.value += '\n>>> ' + statement.value;
-    statement.value = '';
-
-    // add a new history element
-    this.history.push('');
-    this.historyCursor = this.history.length - 1;
-
-    // add the command's result
-    var result = req.responseText.replace(/^\s*|\s*$/g, '');  // trim whitespace
-    if (result != '')
-      output.value += '\n' + result;
-
-    // scroll to the bottom
-    output.scrollTop = output.scrollHeight;
-    if (output.createTextRange) {
-      var range = output.createTextRange();
-      range.collapse(false);
-      range.select();
-    }
-  }
-};
-
-/**
- * This is the form's onsubmit handler. It sends the python statement to the
- * server, and registers shell.done() as the callback to run when it returns.
- *
- * @return {Boolean} false to tell the browser not to submit the form.
- */
-shell.runStatement = function() {
-  var form = document.getElementById('form');
-
-  // build a XmlHttpRequest
-  var req = this.getXmlHttpRequest();
-  if (!req) {
-    document.getElementById('ajax-status').innerHTML =
-        "<span class='error'>Your browser doesn't support AJAX. :(</span>";
-    return false;
-  }
-
-  req.onreadystatechange = function() { shell.done(req); };
-
-  // build the query parameter string
-  var params = '';
-  for (i = 0; i < form.elements.length; i++) {
-    var elem = form.elements[i];
-    if (elem.type != 'submit' && elem.type != 'button' && elem.id != 'caret') {
-      var value = escape(elem.value).replace(/\+/g, '%2B'); // escape ignores +
-      params += '&' + elem.name + '=' + value;
-    }
-  }
-
-  // send the request and tell the user.
-  document.getElementById('statement').className = 'prompt processing';
-  req.open(form.method, form.action + '?' + params, true);
-  req.setRequestHeader('Content-type',
-                       'application/x-www-form-urlencoded;charset=UTF-8');
-  req.send(null);
-
-  return false;
-};
diff --git a/tools/scripts/app_engine_server/gae_shell/static/spinner.gif b/tools/scripts/app_engine_server/gae_shell/static/spinner.gif
deleted file mode 100644
index 3e58d6e..0000000
--- a/tools/scripts/app_engine_server/gae_shell/static/spinner.gif
+++ /dev/null
Binary files differ
diff --git a/tools/scripts/app_engine_server/gae_shell/templates/shell.html b/tools/scripts/app_engine_server/gae_shell/templates/shell.html
deleted file mode 100644
index 123b200..0000000
--- a/tools/scripts/app_engine_server/gae_shell/templates/shell.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-<title> Interactive Shell </title>
-<script type="text/javascript" src="/gae_shell/static/shell.js"></script>
-<style type="text/css">
-body {
-  font-family: monospace;
-  font-size: 10pt;
-}
-
-p {
-  margin: 0.5em;
-}
-
-.prompt, #output {
-  width: 45em;
-  border: 1px solid silver;
-  background-color: #f5f5f5;
-  font-size: 10pt;
-  margin: 0.5em;
-  padding: 0.5em;
-  padding-right: 0em;
-  overflow-x: hidden;
-}
-
-#toolbar {
-  margin-left: 0.5em;
-  padding-left: 0.5em;
-}
-
-#caret {
-  width: 2.5em;
-  margin-right: 0px;
-  padding-right: 0px;
-  border-right: 0px;
-}
-
-#statement {
-  width: 43em;
-  margin-left: -1em;
-  padding-left: 0px;
-  border-left: 0px;
-  background-position: top right;
-  background-repeat: no-repeat;
-}
-
-.processing {
-  background-image: url("/gae_shell/static/spinner.gif");
-}
-
-#ajax-status {
-  font-weight: bold;
-}
-
-.message {
-  color: #8AD;
-  font-weight: bold;
-  font-style: italic;
-}
-
-.error {
-  color: #F44;
-}
-
-.username {
-  font-weight: bold;
-}
-
-</style>
-</head>
-
-<body>
-
-<p> Interactive server-side Python shell for
-<a href="http://code.google.com/appengine/">Google App Engine</a>.
-(<a href="http://code.google.com/p/google-app-engine-samples/">source</a>)
-</p>
-
-<textarea id="output" rows="22" readonly="readonly">
-{{ server_software }}
-Python {{ python_version }}
-</textarea>
-
-<form id="form" action="shell.do" method="get">
-  <nobr>
-  <textarea class="prompt" id="caret" readonly="readonly" rows="4"
-            onfocus="document.getElementById('statement').focus()"
-            >&gt;&gt;&gt;</textarea>
-  <textarea class="prompt" name="statement" id="statement" rows="4"
-            onkeypress="return shell.onPromptKeyPress(event);"></textarea>
-  </nobr>
-  <input type="hidden" name="session" value="{{ session }}" />
-  <input type="submit" style="display: none" />
-</form>
-
-<p id="ajax-status"></p>
-
-<p id="toolbar">
-{% if user %}
-  <span class="username">{{ user.nickname }}</span>
-  (<a href="{{ logout_url }}">log out</a>)
-{% else %}
-  <a href="{{ login_url }}">log in</a>
-{% endif %}
- | Ctrl-Up/Down for history |
-<select id="submit_key">
-  <option value="enter">Enter</option>
-  <option value="ctrl-enter" selected="selected">Ctrl-Enter</option>
-</select>
-<label for="submit_key">submits</label>
-</p>
-
-<script type="text/javascript">
-document.getElementById('statement').focus();
-</script>
-
-</body>
-</html>
-
diff --git a/tools/scripts/app_engine_server/index.yaml b/tools/scripts/app_engine_server/index.yaml
deleted file mode 100644
index 8e6046d..0000000
--- a/tools/scripts/app_engine_server/index.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-indexes:
-
-# AUTOGENERATED
-
-# This index.yaml is automatically updated whenever the dev_appserver
-# detects that a new type of query is run.  If you want to manage the
-# index.yaml file manually, remove the above marker line (the line
-# saying "# AUTOGENERATED").  If you want to manage some indexes
-# manually, move them above the marker line.  The index.yaml file is
-# automatically uploaded to the admin console when you next deploy
-# your application using appcfg.py.
-
diff --git a/tools/scripts/app_engine_server/memcache_zipserve.py b/tools/scripts/app_engine_server/memcache_zipserve.py
deleted file mode 100644
index 43826b0..0000000
--- a/tools/scripts/app_engine_server/memcache_zipserve.py
+++ /dev/null
@@ -1,573 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2009 Google Inc.
-#
-# 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.
-#
-
-"""A class to serve pages from zip files and use memcache for performance.
-
-This contains a class and a function to create an anonymous instance of the
-class to serve HTTP GET requests. Memcache is used to increase response speed
-and lower processing cycles used in serving. Credit to Guido van Rossum and
-his implementation of zipserve which served as a reference as I wrote this.
-
-  MemcachedZipHandler: Class that serves request
-  create_handler: method to create instance of MemcachedZipHandler
-"""
-
-__author__ = 'jmatt@google.com (Justin Mattson)'
-
-import email.Utils
-import logging
-import mimetypes
-import time
-import zipfile
-
-from google.appengine.api import memcache
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp import util
-from time import localtime, strftime
-
-def create_handler(zip_files, max_age=None, public=None):
-  """Factory method to create a MemcachedZipHandler instance.
-
-  Args:
-    zip_files: A list of file names, or a list of lists of file name, first
-        member of file mappings. See MemcachedZipHandler documentation for
-        more information about using the list of lists format
-    max_age: The maximum client-side cache lifetime
-    public: Whether this should be declared public in the client-side cache
-  Returns:
-    A MemcachedZipHandler wrapped in a pretty, anonymous bow for use with App
-    Engine
-
-  Raises:
-    ValueError: if the zip_files argument is not a list
-  """
-  # verify argument integrity. If the argument is passed in list format,
-  # convert it to list of lists format
-  if zip_files and type(zip_files).__name__ == 'list':
-    num_items = len(zip_files)
-    while num_items > 0:
-      if type(zip_files[num_items - 1]).__name__ != 'list':
-        zip_files[num_items - 1] = [zip_files[num_items-1]]
-      num_items -= 1
-  else:
-    raise ValueError('File name arguments must be a list')
-
-  class HandlerWrapper(MemcachedZipHandler):
-    """Simple wrapper for an instance of MemcachedZipHandler.
-
-    I'm still not sure why this is needed
-    """
-    def get(self, name):
-      self.zipfilenames = zip_files
-      self.TrueGet(name)
-      if max_age is not None:
-        MAX_AGE = max_age
-      if public is not None:
-        PUBLIC = public
-
-  return HandlerWrapper
-
-
-class MemcachedZipHandler(webapp.RequestHandler):
-  """Handles get requests for a given URL.
-
-  Serves a GET request from a series of zip files. As files are served they are
-  put into memcache, which is much faster than retreiving them from the zip
-  source file again. It also uses considerably fewer CPU cycles.
-  """
-  zipfile_cache = {}                # class cache of source zip files
-  MAX_AGE = 600                     # max client-side cache lifetime
-  PUBLIC = True                     # public cache setting
-  CACHE_PREFIX = 'cache://'         # memcache key prefix for actual URLs
-  NEG_CACHE_PREFIX = 'noncache://'  # memcache key prefix for non-existant URL
-  intlString = 'intl/'
-  validLangs = ['en', 'de', 'es', 'fr','it','ja','zh-CN','zh-TW']
-  
-  def TrueGet(self, reqUri):
-    """The top-level entry point to serving requests.
-
-    Called 'True' get because it does the work when called from the wrapper
-    class' get method. Some logic is applied to the request to serve files
-    from an intl/<lang>/... directory or fall through to the default language.
-
-    Args:
-      name: URL requested
-
-    Returns:
-      None
-    """
-    langName = 'en'
-    resetLangCookie = False
-    urlLangName = None
-    retry = False
-    isValidIntl = False
-
-    # Try to retrieve the user's lang pref from the cookie. If there is no
-    # lang pref cookie in the request, add set-cookie to the response with the 
-    # default value of 'en'.
-    try:
-      langName = self.request.cookies['android_developer_pref_lang']
-    except KeyError:
-      resetLangCookie = True
-      #logging.info('==========================EXCEPTION: NO LANG COOKIE FOUND, USING [%s]', langName)
-    logging.info('==========================REQ INIT name [%s] langName [%s]', reqUri, langName)
-
-    # Preprocess the req url. If it references a directory or the domain itself,
-    # append '/index.html' to the url and 302 redirect. Otherwise, continue
-    # processing the request below.
-    name = self.PreprocessUrl(reqUri, langName)
-    if name:
-      # Do some prep for handling intl requests. Parse the url and validate
-      # the intl/lang substring, extract the url lang code (urlLangName) and the
-      # the uri that follows the intl/lang substring(contentUri)
-      sections = name.split("/", 2)
-      contentUri = 0
-      isIntl = len(sections) > 1 and (sections[0] == "intl")
-      if isIntl:
-        isValidIntl = sections[1] in self.validLangs
-        if isValidIntl:
-          urlLangName = sections[1]
-          contentUri = sections[2]
-          if (langName != urlLangName):
-            # if the lang code in the request is different from that in 
-            # the cookie, reset the cookie to the url lang value.
-            langName = urlLangName
-            resetLangCookie = True
-            #logging.info('INTL PREP resetting langName to urlLangName [%s]', langName)
-          #else: 
-          #  logging.info('INTL PREP no need to reset langName')
-
-      # Send for processing
-      if self.isCleanUrl(name, langName, isValidIntl):
-        # handle a 'clean' request.
-        # Try to form a response using the actual request url.
-        if not self.CreateResponse(name, langName, isValidIntl, resetLangCookie):
-          # If CreateResponse returns False, there was no such document
-          # in the intl/lang tree. Before going to 404, see if there is an
-          # English-language version of the doc in the default
-          # default tree and return it, else go to 404.
-          self.CreateResponse(contentUri, langName, False, resetLangCookie)
-
-      elif isIntl:
-        # handle the case where we need to pass through an invalid intl req 
-        # for processing (so as to get 404 as appropriate). This is needed
-        # because intl urls are passed through clean and retried in English,
-        # if necessary.
-        logging.info('  Handling an invalid intl request...')
-        self.CreateResponse(name, langName, isValidIntl, resetLangCookie)
-
-      else:
-        # handle the case where we have a non-clean url (usually a non-intl
-        # url) that we need to interpret in the context of any lang pref
-        # that is set. Prepend an intl/lang string to the request url and
-        # send it as a 302 redirect. After the redirect, the subsequent
-        # request will be handled as a clean url.
-        self.RedirToIntl(name, self.intlString, langName)
-
-  def isCleanUrl(self, name, langName, isValidIntl):
-    """Determine whether to pass an incoming url straight to processing. 
-
-       Args:
-         name: The incoming URL
-
-       Returns:
-         boolean: Whether the URL should be sent straight to processing
-    """
-    if (langName == 'en') or isValidIntl or not ('.html' in name) or (not isValidIntl and not langName):
-      return True
-
-  def PreprocessUrl(self, name, langName):
-    """Any preprocessing work on the URL when it comes in.
-
-    Put any work related to interpretting the incoming URL here. For example,
-    this is used to redirect requests for a directory to the index.html file
-    in that directory. Subclasses should override this method to do different
-    preprocessing.
-
-    Args:
-      name: The incoming URL
-
-    Returns:
-      False if the request was redirected to '/index.html', or
-      The processed URL, otherwise
-    """
-    # determine if this is a request for a directory
-    final_path_segment = name
-    final_slash_offset = name.rfind('/')
-    if final_slash_offset != len(name) - 1:
-      final_path_segment = name[final_slash_offset + 1:]
-      if final_path_segment.find('.') == -1:
-        name = ''.join([name, '/'])
-
-    # if this is a directory or the domain itself, redirect to /index.html
-    if not name or (name[len(name) - 1:] == '/'):
-      uri = ''.join(['/', name, 'index.html'])
-      logging.info('--->PREPROCESSING REDIRECT [%s] to [%s] with langName [%s]', name, uri, langName)
-      self.redirect(uri, False)
-      return False
-    else:
-      return name
-
-  def RedirToIntl(self, name, intlString, langName):
-    """Redirect an incoming request to the appropriate intl uri.
-
-       Builds the intl/lang string from a base (en) string
-       and redirects (302) the request to look for a version 
-       of the file in the language that matches the client-
-       supplied cookie value.
-
-    Args:
-      name: The incoming, preprocessed URL
-
-    Returns:
-      The lang-specific URL
-    """
-    builtIntlLangUri = ''.join([intlString, langName, '/', name, '?', self.request.query_string])
-    uri = ''.join(['/', builtIntlLangUri])
-    logging.info('-->>REDIRECTING %s to  %s', name, uri)
-    self.redirect(uri, False)
-    return uri
-
-  def CreateResponse(self, name, langName, isValidIntl, resetLangCookie):
-    """Process the url and form a response, if appropriate.
-
-       Attempts to retrieve the requested file (name) from cache, 
-       negative cache, or store (zip) and form the response. 
-       For intl requests that are not found (in the localized tree), 
-       returns False rather than forming a response, so that
-       the request can be retried with the base url (this is the 
-       fallthrough to default language). 
-
-       For requests that are found, forms the headers and
-       adds the content to the response entity. If the request was
-       for an intl (localized) url, also resets the language cookie 
-       to the language specified in the url if needed, to ensure that 
-       the client language and response data remain harmonious. 
-
-    Args:
-      name: The incoming, preprocessed URL
-      langName: The language id. Used as necessary to reset the
-                language cookie in the response.
-      isValidIntl: If present, indicates whether the request is
-                   for a language-specific url
-      resetLangCookie: Whether the response should reset the
-                       language cookie to 'langName'
-
-    Returns:
-      True: A response was successfully created for the request
-      False: No response was created.
-    """
-    # see if we have the page in the memcache
-    logging.info('PROCESSING %s langName [%s] isValidIntl [%s] resetLang [%s]', 
-      name, langName, isValidIntl, resetLangCookie)
-    resp_data = self.GetFromCache(name)
-    if resp_data is None:
-      logging.info('  Cache miss for %s', name)
-      resp_data = self.GetFromNegativeCache(name)
-      if resp_data is None:
-        resp_data = self.GetFromStore(name)
-
-        # IF we have the file, put it in the memcache
-        # ELSE put it in the negative cache
-        if resp_data is not None:
-          self.StoreOrUpdateInCache(name, resp_data)
-        elif isValidIntl:
-          # couldn't find the intl doc. Try to fall through to English.
-          #logging.info('  Retrying with base uri...')
-          return False
-        else:
-          logging.info('  Adding %s to negative cache, serving 404', name)
-          self.StoreInNegativeCache(name)
-          self.Write404Error()
-          return True
-      else:
-        # found it in negative cache
-        self.Write404Error()
-        return True
-
-    # found content from cache or store
-    logging.info('FOUND CLEAN')
-    if resetLangCookie:
-      logging.info('  Resetting android_developer_pref_lang cookie to [%s]',
-      langName)
-      expireDate = time.mktime(localtime()) + 60 * 60 * 24 * 365 * 10
-      self.response.headers.add_header('Set-Cookie', 
-      'android_developer_pref_lang=%s; path=/; expires=%s' % 
-      (langName, strftime("%a, %d %b %Y %H:%M:%S", localtime(expireDate))))
-    mustRevalidate = False
-    if ('.html' in name):
-      # revalidate html files -- workaround for cache inconsistencies for 
-      # negotiated responses
-      mustRevalidate = True
-      logging.info('  Adding [Vary: Cookie] to response...')
-      self.response.headers.add_header('Vary', 'Cookie')
-    content_type, encoding = mimetypes.guess_type(name)
-    if content_type:
-      self.response.headers['Content-Type'] = content_type
-      self.SetCachingHeaders(mustRevalidate)
-      self.response.out.write(resp_data)
-    elif (name == 'favicon.ico'):
-      self.response.headers['Content-Type'] = 'image/x-icon'
-      self.SetCachingHeaders(mustRevalidate)
-      self.response.out.write(resp_data)
-    elif name.endswith('.psd'):
-      self.response.headers['Content-Type'] = 'application/octet-stream'
-      self.SetCachingHeaders(mustRevalidate)
-      self.response.out.write(resp_data)
-    return True
-
-  def GetFromStore(self, file_path):
-    """Retrieve file from zip files.
-
-    Get the file from the source, it must not have been in the memcache. If
-    possible, we'll use the zip file index to quickly locate where the file
-    should be found. (See MapToFileArchive documentation for assumptions about
-    file ordering.) If we don't have an index or don't find the file where the
-    index says we should, look through all the zip files to find it.
-
-    Args:
-      file_path: the file that we're looking for
-
-    Returns:
-      The contents of the requested file
-    """
-    resp_data = None
-    file_itr = iter(self.zipfilenames)
-
-    # check the index, if we have one, to see what archive the file is in
-    archive_name = self.MapFileToArchive(file_path)
-    if not archive_name:
-      archive_name = file_itr.next()[0]
-
-    while resp_data is None and archive_name:
-      zip_archive = self.LoadZipFile(archive_name)
-      if zip_archive:
-
-        # we expect some lookups will fail, and that's okay, 404s will deal
-        # with that
-        try:
-          resp_data = zip_archive.read(file_path)
-        except (KeyError, RuntimeError), err:
-          # no op
-          x = False
-        if resp_data is not None:
-          logging.info('%s read from %s', file_path, archive_name)
-          
-      try:
-        archive_name = file_itr.next()[0]
-      except (StopIteration), err:
-        archive_name = False
-
-    return resp_data
-
-  def LoadZipFile(self, zipfilename):
-    """Convenience method to load zip file.
-
-    Just a convenience method to load the zip file from the data store. This is
-    useful if we ever want to change data stores and also as a means of
-    dependency injection for testing. This method will look at our file cache
-    first, and then load and cache the file if there's a cache miss
-
-    Args:
-      zipfilename: the name of the zip file to load
-
-    Returns:
-      The zip file requested, or None if there is an I/O error
-    """
-    zip_archive = None
-    zip_archive = self.zipfile_cache.get(zipfilename)
-    if zip_archive is None:
-      try:
-        zip_archive = zipfile.ZipFile(zipfilename)
-        self.zipfile_cache[zipfilename] = zip_archive
-      except (IOError, RuntimeError), err:
-        logging.error('Can\'t open zipfile %s, cause: %s' % (zipfilename,
-                                                             err))
-    return zip_archive
-
-  def MapFileToArchive(self, file_path):
-    """Given a file name, determine what archive it should be in.
-
-    This method makes two critical assumptions.
-    (1) The zip files passed as an argument to the handler, if concatenated
-        in that same order, would result in a total ordering
-        of all the files. See (2) for ordering type.
-    (2) Upper case letters before lower case letters. The traversal of a
-        directory tree is depth first. A parent directory's files are added
-        before the files of any child directories
-
-    Args:
-      file_path: the file to be mapped to an archive
-
-    Returns:
-      The name of the archive where we expect the file to be
-    """
-    num_archives = len(self.zipfilenames)
-    while num_archives > 0:
-      target = self.zipfilenames[num_archives - 1]
-      if len(target) > 1:
-        if self.CompareFilenames(target[1], file_path) >= 0:
-          return target[0]
-      num_archives -= 1
-
-    return None
-
-  def CompareFilenames(self, file1, file2):
-    """Determines whether file1 is lexigraphically 'before' file2.
-
-    WARNING: This method assumes that paths are output in a depth-first,
-    with parent directories' files stored before childs'
-
-    We say that file1 is lexigraphically before file2 if the last non-matching
-    path segment of file1 is alphabetically before file2.
-    
-    Args:
-      file1: the first file path
-      file2: the second file path
-
-    Returns:
-      A positive number if file1 is before file2
-      A negative number if file2 is before file1
-      0 if filenames are the same
-    """
-    f1_segments = file1.split('/')
-    f2_segments = file2.split('/')
-
-    segment_ptr = 0
-    while (segment_ptr < len(f1_segments) and
-           segment_ptr < len(f2_segments) and
-           f1_segments[segment_ptr] == f2_segments[segment_ptr]):
-      segment_ptr += 1
-
-    if len(f1_segments) == len(f2_segments):
-
-      # we fell off the end, the paths much be the same
-      if segment_ptr == len(f1_segments):
-        return 0
-
-      # we didn't fall of the end, compare the segments where they differ
-      if f1_segments[segment_ptr] < f2_segments[segment_ptr]:
-        return 1
-      elif f1_segments[segment_ptr] > f2_segments[segment_ptr]:
-        return -1
-      else:
-        return 0
-
-      # the number of segments differs, we either mismatched comparing
-      # directories, or comparing a file to a directory
-    else:
-
-      # IF we were looking at the last segment of one of the paths,
-      # the one with fewer segments is first because files come before
-      # directories
-      # ELSE we just need to compare directory names
-      if (segment_ptr + 1 == len(f1_segments) or
-          segment_ptr + 1 == len(f2_segments)):
-        return len(f2_segments) - len(f1_segments)
-      else:
-        if f1_segments[segment_ptr] < f2_segments[segment_ptr]:
-          return 1
-        elif f1_segments[segment_ptr] > f2_segments[segment_ptr]:
-          return -1
-        else:
-          return 0
-
-  def SetCachingHeaders(self, revalidate):
-    """Set caching headers for the request."""
-    max_age = self.MAX_AGE
-    #self.response.headers['Expires'] = email.Utils.formatdate(
-    #    time.time() + max_age, usegmt=True)
-	cache_control = []
-    if self.PUBLIC:
-      cache_control.append('public')
-    cache_control.append('max-age=%d' % max_age)
-    if revalidate:
-      cache_control.append('must-revalidate')
-    self.response.headers['Cache-Control'] = ', '.join(cache_control)
-
-  def GetFromCache(self, filename):
-    """Get file from memcache, if available.
-
-    Args:
-      filename: The URL of the file to return
-
-    Returns:
-      The content of the file
-    """
-    return memcache.get('%s%s' % (self.CACHE_PREFIX, filename))
-
-  def StoreOrUpdateInCache(self, filename, data):
-    """Store data in the cache.
-
-    Store a piece of data in the memcache. Memcache has a maximum item size of
-    1*10^6 bytes. If the data is too large, fail, but log the failure. Future
-    work will consider compressing the data before storing or chunking it
-
-    Args:
-      filename: the name of the file to store
-      data: the data of the file
-
-    Returns:
-      None
-    """
-    try:
-      if not memcache.add('%s%s' % (self.CACHE_PREFIX, filename), data):
-        memcache.replace('%s%s' % (self.CACHE_PREFIX, filename), data)
-    except (ValueError), err:
-      logging.warning('Data size too large to cache\n%s' % err)
-
-  def Write404Error(self):
-    """Ouptut a simple 404 response."""
-    self.error(404)
-    self.response.out.write(
-        ''.join(['<html><head><title>404: Not Found</title></head>',
-                 '<body><b><h2>Error 404</h2><br/>',
-                 'File not found</b></body></html>']))
-
-  def StoreInNegativeCache(self, filename):
-    """If a non-existant URL is accessed, cache this result as well.
-
-    Future work should consider setting a maximum negative cache size to
-    prevent it from from negatively impacting the real cache.
-
-    Args:
-      filename: URL to add ot negative cache
-
-    Returns:
-      None
-    """
-    memcache.add('%s%s' % (self.NEG_CACHE_PREFIX, filename), -1)
-
-  def GetFromNegativeCache(self, filename):
-    """Retrieve from negative cache.
-
-    Args:
-      filename: URL to retreive
-
-    Returns:
-      The file contents if present in the negative cache.
-    """
-    return memcache.get('%s%s' % (self.NEG_CACHE_PREFIX, filename))
-
-def main():
-  application = webapp.WSGIApplication([('/([^/]+)/(.*)',
-                                         MemcachedZipHandler)])
-  util.run_wsgi_app(application)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/scripts/build.alias.template b/tools/scripts/build.alias.template
deleted file mode 100644
index d051405..0000000
--- a/tools/scripts/build.alias.template
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-ALIAS PROJECTS ARE CURRENT NOT SUPPORTED.
-THIS FILE IS CURRENTLY BROKEN AND SHOULD NOT BE USED.
--->
-<project name="PROJECT_NAME" default="package">
-
-    <!-- The build.properties file can be created by you and is never touched
-         by activitycreator. If you want to manually set properties, this is
-         the best place to set them. -->
-    <property file="build.properties" />
-
-    <!-- The default.properties file is created and updated by activitycreator.
-         It will set any properties not already defined by build.properties. -->
-    <property file="default.properties" />
-
-    <!-- ************************************************************************************* -->
-    <!-- Import the default Android build rules.
-         This requires ant 1.6.0 or above. -->
-
-    <import file="${sdk.dir}/tools/lib/alias_rules.xml" />
-
-</project>
diff --git a/tools/scripts/build.template b/tools/scripts/build.template
deleted file mode 100644
index 3959c57..0000000
--- a/tools/scripts/build.template
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="PROJECT_NAME" default="help">
-
-    <!-- The local.properties file is created and updated by the 'android' tool.
-         It contains the path to the SDK. It should *NOT* be checked in in Version
-         Control Systems. -->
-    <property file="local.properties" />
-
-    <!-- The build.properties file can be created by you and is never touched
-         by the 'android' tool. This is the place to change some of the default property values
-         used by the Ant rules.
-         Here are some properties you may want to change/update:
-
-         application.package
-             the name of your application package as defined in the manifest. Used by the
-             'uninstall' rule.
-         source.dir
-             the name of the source directory. Default is 'src'.
-         out.dir
-             the name of the output directory. Default is 'bin'.
-
-         Properties related to the SDK location or the project target should be updated
-          using the 'android' tool with the 'update' action.
-
-         This file is an integral part of the build system for your application and
-         should be checked in in Version Control Systems.
-
-         -->
-    <property file="build.properties" />
-
-    <!-- The default.properties file is created and updated by the 'android' tool, as well
-         as ADT.
-         This file is an integral part of the build system for your application and
-         should be checked in in Version Control Systems. -->
-    <property file="default.properties" />
-
-    <!-- Custom Android task to deal with the project target, and import the proper rules.
-         This requires ant 1.6.0 or above. -->
-    <path id="android.antlibs">
-        <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
-    </path>
-
-    <taskdef name="setup"
-        classname="com.android.ant.SetupTask"
-        classpathref="android.antlibs" />
-
-    <!-- Execute the Android Setup task that will setup some properties specific to the target,
-         and import the build rules files.
-
-         The rules file is imported from
-            <SDK>/platforms/<target_platform>/templates/android_rules.xml
-
-         To customize some build steps for your project:
-         - copy the content of the main node <project> from android_rules.xml
-         - paste it in this build.xml below the <setup /> task.
-         - disable the import by changing the setup task below to <setup import="false" />
-
-         This will ensure that the properties are setup correctly but that your customized
-         build steps are used.
-    -->
-    <setup />
-
-</project>
diff --git a/tools/scripts/combine_sdks.sh b/tools/scripts/combine_sdks.sh
deleted file mode 100755
index ebaa1c6..0000000
--- a/tools/scripts/combine_sdks.sh
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/bin/bash
-
-function replace()
-{
-        echo replacing $1
-        rm $V -rf "$UNZIPPED_BASE_DIR"/$1
-        cp $V -rf "$UNZIPPED_IMAGE_DIR"/$1 "$UNZIPPED_BASE_DIR"/$1
-}
-
-V=""
-Q="-q"
-if [ "$1" == "-v" ]; then
-    V="-v"
-    Q=""
-    shift
-fi
-
-NOZIP=""
-if [ "$1" == "-nozip" ]; then
-    NOZIP="1"
-    shift
-fi
-
-BASE="$1"
-IMAGES="$2"
-OUTPUT="$3"
-
-if [[ -z "$BASE" || -z "$IMAGES" || -z "$OUTPUT" ]] ; then
-    echo "usage: combine_sdks.sh [-v] [-nozip] BASE IMAGES OUTPUT"
-    echo
-    echo "  BASE and IMAGES should be sdk zip files.  The system image files,"
-    echo "  emulator and other runtime files will be copied from IMAGES and"
-    echo "  everything else will be copied from BASE.  All of this will be"
-    echo "  bundled into OUTPUT and zipped up again (unless -nozip is specified)."
-    echo
-    exit 1
-fi
-
-TMP=$(mktemp -d)
-
-TMP_ZIP=tmp.zip
-
-# determine executable extension
-case `uname -s` in
-    *_NT-*)  # for Windows
-        EXE=.exe
-        ;;
-    *)
-        EXE=
-        ;;
-esac
-
-BASE_DIR="$TMP"/base
-IMAGES_DIR="$TMP"/images
-OUTPUT_TMP_ZIP="$BASE_DIR/$TMP_ZIP"
-
-unzip $Q "$BASE"   -d "$BASE_DIR"
-unzip $Q "$IMAGES" -d "$IMAGES_DIR"
-
-UNZIPPED_BASE_DIR=$(echo "$BASE_DIR"/*)
-UNZIPPED_IMAGE_DIR=$(echo "$IMAGES_DIR"/*)
-
-#
-# The commands to copy over the files that we want
-#
-
-# replace tools/emulator # at this time we do not want the exe from SDK1.x
-replace tools/lib/images
-replace tools/lib/res
-replace tools/lib/fonts
-replace tools/lib/layoutlib.jar
-replace docs
-replace android.jar
-
-for i in widgets categories broadcast_actions service_actions; do
-    replace tools/lib/$i.txt
-done
-
-if [ -d "$UNZIPPED_BASE_DIR"/usb_driver ]; then
-    replace usb_driver
-fi
-
-#
-# end
-#
-
-if [ -z "$NOZIP" ]; then
-    pushd "$BASE_DIR" &> /dev/null
-        # rename the directory to the leaf minus the .zip of OUTPUT
-        LEAF=$(echo "$OUTPUT" | sed -e "s:.*\.zip/::" | sed -e "s:.zip$::")
-        mv * "$LEAF"
-        # zip it
-        zip $V -qr "$TMP_ZIP" "$LEAF"
-    popd &> /dev/null
-
-    cp $V "$OUTPUT_TMP_ZIP" "$OUTPUT"
-    echo "Combined SDK available at $OUTPUT"
-else
-    OUT_DIR="${OUTPUT//.zip/}"
-    mv $V "$BASE_DIR"/* "$OUT_DIR"
-    echo "Unzipped combined SDK available at $OUT_DIR"
-fi
-
-rm $V -rf "$TMP"
-
diff --git a/tools/scripts/devices.xml b/tools/scripts/devices.xml
deleted file mode 100644
index d00d693..0000000
--- a/tools/scripts/devices.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0"?>
-<d:layout-devices
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xmlns:d="http://schemas.android.com/sdk/android/layout-devices/1">
-
-    <d:device name="ADP1">
-        <d:default>
-            <d:screen-size>normal</d:screen-size>
-            <d:screen-ratio>notlong</d:screen-ratio>
-            <d:screen-orientation>port</d:screen-orientation>
-            <d:pixel-density>mdpi</d:pixel-density>
-            <d:touch-type>finger</d:touch-type>
-            <d:text-input-method>qwerty</d:text-input-method>
-            <d:nav-method>trackball</d:nav-method>
-            <d:screen-dimension>
-                <d:size>320</d:size>
-                <d:size>480</d:size>
-            </d:screen-dimension>
-            <d:xdpi>180.6</d:xdpi>
-            <d:ydpi>182</d:ydpi>
-        </d:default>
-
-        <d:config name="Portrait">
-            <d:keyboard-state>keyssoft</d:keyboard-state>
-            <d:screen-orientation>port</d:screen-orientation>
-        </d:config>
-        <d:config name="Landscape, closed">
-            <d:keyboard-state>keyssoft</d:keyboard-state>
-            <d:screen-orientation>land</d:screen-orientation>
-        </d:config>
-        <d:config name="Landscape, open">
-            <d:keyboard-state>keysexposed</d:keyboard-state>
-            <d:screen-orientation>land</d:screen-orientation>
-        </d:config>
-    </d:device>
-
-    <d:device name="ADP2">
-        <d:default>
-            <d:screen-size>normal</d:screen-size>
-            <d:screen-ratio>notlong</d:screen-ratio>
-            <d:screen-orientation>port</d:screen-orientation>
-            <d:pixel-density>mdpi</d:pixel-density>
-            <d:touch-type>finger</d:touch-type>
-            <d:keyboard-state>keyssoft</d:keyboard-state>
-            <d:text-input-method>nokeys</d:text-input-method>
-            <d:nav-method>trackball</d:nav-method>
-            <d:screen-dimension>
-                <d:size>320</d:size>
-                <d:size>480</d:size>
-            </d:screen-dimension>
-            <d:xdpi>180.6</d:xdpi>
-            <d:ydpi>182</d:ydpi>
-        </d:default>
-
-        <d:config name="Portrait">
-            <d:screen-orientation>port</d:screen-orientation>
-        </d:config>
-        <d:config name="Landscape">
-            <d:screen-orientation>land</d:screen-orientation>
-        </d:config>
-    </d:device>
-</d:layout-devices>
diff --git a/tools/scripts/divide_and_compress.py b/tools/scripts/divide_and_compress.py
deleted file mode 100755
index 2bcb0ab..0000000
--- a/tools/scripts/divide_and_compress.py
+++ /dev/null
@@ -1,366 +0,0 @@
-#!/usr/bin/python2.4
-#
-# Copyright (C) 2008 Google Inc.
-#
-# 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.
-#
-
-"""Module to compress directories in to series of zip files.
-
-This module will take a directory and compress all its contents, including
-child directories into a series of zip files named N.zip where 'N' ranges from
-0 to infinity. The zip files will all be below a certain specified maximum
-threshold.
-
-The directory is compressed with a depth first traversal, each directory's
-file contents being compressed as it is visisted, before the compression of any
-child directory's contents. In this way the files within an archive are ordered
-and the archives themselves are ordered.
-
-The class also constructs a 'main.py' file intended for use with Google App
-Engine with a custom App Engine program not currently distributed with this
-code base. The custom App Engine runtime can leverage the index files written
-out by this class to more quickly locate which zip file to serve a given URL
-from.
-"""
-
-__author__ = 'jmatt@google.com (Justin Mattson)'
-
-import optparse
-import os
-import stat
-import sys
-import zipfile
-import divide_and_compress_constants
-
-
-def CreateOptionsParser():
-  """Creates the parser for command line arguments.
-
-  Returns:
-    A configured optparse.OptionParser object.
-  """
-  rtn = optparse.OptionParser()
-  rtn.add_option('-s', '--sourcefiles', dest='sourcefiles', default=None,
-                 help='The directory containing the files to compress')
-  rtn.add_option('-d', '--destination', dest='destination', default=None,
-                 help=('Where to put the archive files, this should not be'
-                       ' a child of where the source files exist.'))
-  rtn.add_option('-f', '--filesize', dest='filesize', default='1M',
-                 help=('Maximum size of archive files. A number followed by '
-                       'a magnitude indicator either "B", "K", "M", or "G". '
-                       'Examples:\n  1000000B == one million BYTES\n'
-                       '  1.2M == one point two MEGABYTES\n'
-                       '  1M == 1048576 BYTES'))
-  rtn.add_option('-n', '--nocompress', action='store_false', dest='compress',
-                 default=True,
-                 help=('Whether the archive files should be compressed, or '
-                       'just a concatenation of the source files'))
-  return rtn
-
-
-def VerifyArguments(options, parser):
-  """Runs simple checks on correctness of commandline arguments.
-
-  Args:
-    options: The command line options passed.
-    parser: The parser object used to parse the command string.
-  """
-  try:
-    if options.sourcefiles is None or options.destination is None:
-      parser.print_help()
-      sys.exit(-1)
-  except AttributeError:
-    parser.print_help()
-    sys.exit(-1)
-
-
-def ParseSize(size_str):
-  """Parse the file size argument from a string to a number of bytes.
-
-  Args:
-    size_str: The string representation of the file size.
-
-  Returns:
-    The file size in bytes.
-
-  Raises:
-    ValueError: Raises an error if the numeric or qualifier portions of the
-      file size argument is invalid.
-  """
-  if len(size_str) < 2:
-    raise ValueError(('filesize argument not understood, please include'
-                      ' a numeric value and magnitude indicator'))
-  magnitude = size_str[-1]
-  if not magnitude in ('B', 'K', 'M', 'G'):
-    raise ValueError(('filesize magnitude indicator not valid, must be "B",'
-                      '"K","M", or "G"'))
-  numeral = float(size_str[:-1])
-  if magnitude == 'K':
-    numeral *= 1024
-  elif magnitude == 'M':
-    numeral *= 1048576
-  elif magnitude == 'G':
-    numeral *= 1073741824
-  return int(numeral)
-
-
-class DirectoryZipper(object):
-  """Class to compress a directory and all its sub-directories."""
-
-  def __init__(self, output_path, base_dir, archive_size, enable_compression):
-    """DirectoryZipper constructor.
-
-    Args:
-      output_path: A string, the path to write the archives and index file to.
-      base_dir: A string, the directory to compress.
-      archive_size: An number, the maximum size, in bytes, of a single
-        archive file.
-      enable_compression: A boolean, whether or not compression should be
-        enabled, if disabled, the files will be written into an uncompresed
-        zip.
-    """
-    self.output_dir = output_path
-    self.current_archive = '0.zip'
-    self.base_path = base_dir
-    self.max_size = archive_size
-    self.compress = enable_compression
-
-    # Set index_fp to None, because we don't know what it will be yet.
-    self.index_fp = None
-
-  def StartCompress(self):
-    """Start compress of the directory.
-
-    This will start the compression process and write the archives to the
-    specified output directory. It will also produce an 'index.txt' file in the
-    output directory that maps from file to archive.
-    """
-    self.index_fp = open(os.path.join(self.output_dir, 'main.py'), 'w')
-    self.index_fp.write(divide_and_compress_constants.file_preamble)
-    os.path.walk(self.base_path, self.CompressDirectory, 1)
-    self.index_fp.write(divide_and_compress_constants.file_endpiece)
-    self.index_fp.close()
-
-  def RemoveLastFile(self, archive_path=None):
-    """Removes the last item in the archive.
-
-    This removes the last item in the archive by reading the items out of the
-    archive, adding them to a new archive, deleting the old archive, and
-    moving the new archive to the location of the old archive.
-
-    Args:
-      archive_path: Path to the archive to modify. This archive should not be
-        open elsewhere, since it will need to be deleted.
-
-    Returns:
-      A new ZipFile object that points to the modified archive file.
-    """
-    if archive_path is None:
-      archive_path = os.path.join(self.output_dir, self.current_archive)
-
-    # Move the old file and create a new one at its old location.
-    root, ext = os.path.splitext(archive_path)
-    old_archive = ''.join([root, '-old', ext])
-    os.rename(archive_path, old_archive)
-    old_fp = self.OpenZipFileAtPath(old_archive, mode='r')
-
-    # By default, store uncompressed.
-    compress_bit = zipfile.ZIP_STORED
-    if self.compress:
-      compress_bit = zipfile.ZIP_DEFLATED
-    new_fp = self.OpenZipFileAtPath(archive_path,
-                                    mode='w',
-                                    compress=compress_bit)
-
-    # Read the old archive in a new archive, except the last one.
-    for zip_member in old_fp.infolist()[:-1]:
-      new_fp.writestr(zip_member, old_fp.read(zip_member.filename))
-
-    # Close files and delete the old one.
-    old_fp.close()
-    new_fp.close()
-    os.unlink(old_archive)
-
-  def OpenZipFileAtPath(self, path, mode=None, compress=zipfile.ZIP_DEFLATED):
-    """This method is mainly for testing purposes, eg dependency injection."""
-    if mode is None:
-      if os.path.exists(path):
-        mode = 'a'
-      else:
-        mode = 'w'
-
-    if mode == 'r':
-      return zipfile.ZipFile(path, mode)
-    else:
-      return zipfile.ZipFile(path, mode, compress)
-
-  def CompressDirectory(self, unused_id, dir_path, dir_contents):
-    """Method to compress the given directory.
-
-    This method compresses the directory 'dir_path'. It will add to an existing
-    zip file that still has space and create new ones as necessary to keep zip
-    file sizes under the maximum specified size. This also writes out the
-    mapping of files to archives to the self.index_fp file descriptor
-
-    Args:
-      unused_id: A numeric identifier passed by the os.path.walk method, this
-        is not used by this method.
-      dir_path: A string, the path to the directory to compress.
-      dir_contents: A list of directory contents to be compressed.
-    """
-    # Construct the queue of files to be added that this method will use
-    # it seems that dir_contents is given in reverse alphabetical order,
-    # so put them in alphabetical order by inserting to front of the list.
-    dir_contents.sort()
-    zip_queue = []
-    for filename in dir_contents:
-      zip_queue.append(os.path.join(dir_path, filename))
-    compress_bit = zipfile.ZIP_DEFLATED
-    if not self.compress:
-      compress_bit = zipfile.ZIP_STORED
-
-    # Zip all files in this directory, adding to existing archives and creating
-    # as necessary.
-    while zip_queue:
-      target_file = zip_queue[0]
-      if os.path.isfile(target_file):
-        self.AddFileToArchive(target_file, compress_bit)
-
-        # See if adding the new file made our archive too large.
-        if not self.ArchiveIsValid():
-
-          # IF fixing fails, the last added file was to large, skip it
-          # ELSE the current archive filled normally, make a new one and try
-          #  adding the file again.
-          if not self.FixArchive('SIZE'):
-            zip_queue.pop(0)
-          else:
-            self.current_archive = '%i.zip' % (
-                int(self.current_archive[
-                    0:self.current_archive.rfind('.zip')]) + 1)
-        else:
-
-          # Write an index record if necessary.
-          self.WriteIndexRecord()
-          zip_queue.pop(0)
-      else:
-        zip_queue.pop(0)
-
-  def WriteIndexRecord(self):
-    """Write an index record to the index file.
-
-    Only write an index record if this is the first file to go into archive
-
-    Returns:
-      True if an archive record is written, False if it isn't.
-    """
-    archive = self.OpenZipFileAtPath(
-        os.path.join(self.output_dir, self.current_archive), 'r')
-    archive_index = archive.infolist()
-    if len(archive_index) == 1:
-      self.index_fp.write(
-          '[\'%s\', \'%s\'],\n' % (self.current_archive,
-                                   archive_index[0].filename))
-      archive.close()
-      return True
-    else:
-      archive.close()
-      return False
-
-  def FixArchive(self, problem):
-    """Make the archive compliant.
-
-    Args:
-      problem: An enum, the reason the archive is invalid.
-
-    Returns:
-      Whether the file(s) removed to fix the archive could conceivably be
-      in an archive, but for some reason can't be added to this one.
-    """
-    archive_path = os.path.join(self.output_dir, self.current_archive)
-    return_value = None
-
-    if problem == 'SIZE':
-      archive_obj = self.OpenZipFileAtPath(archive_path, mode='r')
-      num_archive_files = len(archive_obj.infolist())
-
-      # IF there is a single file, that means its too large to compress,
-      # delete the created archive
-      # ELSE do normal finalization.
-      if num_archive_files == 1:
-        print ('WARNING: %s%s is too large to store.' % (
-            self.base_path, archive_obj.infolist()[0].filename))
-        archive_obj.close()
-        os.unlink(archive_path)
-        return_value = False
-      else:
-        archive_obj.close()
-        self.RemoveLastFile(
-          os.path.join(self.output_dir, self.current_archive))
-        print 'Final archive size for %s is %i' % (
-            self.current_archive, os.path.getsize(archive_path))
-        return_value = True
-    return return_value
-
-  def AddFileToArchive(self, filepath, compress_bit):
-    """Add the file at filepath to the current archive.
-
-    Args:
-      filepath: A string, the path of the file to add.
-      compress_bit: A boolean, whether or not this file should be compressed
-        when added.
-
-    Returns:
-      True if the file could be added (typically because this is a file) or
-      False if it couldn't be added (typically because its a directory).
-    """
-    curr_archive_path = os.path.join(self.output_dir, self.current_archive)
-    if os.path.isfile(filepath) and not os.path.islink(filepath):
-      if os.path.getsize(filepath) > 1048576:
-        print 'Warning: %s is potentially too large to serve on GAE' % filepath
-      archive = self.OpenZipFileAtPath(curr_archive_path,
-                                       compress=compress_bit)
-      # Add the file to the archive.
-      archive.write(filepath, filepath[len(self.base_path):])
-      archive.close()
-      return True
-    else:
-      return False
-
-  def ArchiveIsValid(self):
-    """Check whether the archive is valid.
-
-    Currently this only checks whether the archive is under the required size.
-    The thought is that eventually this will do additional validation
-
-    Returns:
-      True if the archive is valid, False if its not.
-    """
-    archive_path = os.path.join(self.output_dir, self.current_archive)
-    return os.path.getsize(archive_path) <= self.max_size
-
-
-def main(argv):
-  parser = CreateOptionsParser()
-  (options, unused_args) = parser.parse_args(args=argv[1:])
-  VerifyArguments(options, parser)
-  zipper = DirectoryZipper(options.destination,
-                           options.sourcefiles,
-                           ParseSize(options.filesize),
-                           options.compress)
-  zipper.StartCompress()
-
-
-if __name__ == '__main__':
-  main(sys.argv)
diff --git a/tools/scripts/divide_and_compress_constants.py b/tools/scripts/divide_and_compress_constants.py
deleted file mode 100644
index 15162b7..0000000
--- a/tools/scripts/divide_and_compress_constants.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/python2.4
-#
-# Copyright (C) 2008 Google Inc.
-#
-# 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.
-#
-
-"""Constants for the divide_and_compress script and DirectoryZipper class."""
-
-__author__ = 'jmatt@google.com (Justin Mattson)'
-
-file_preamble = """#!/usr/bin/env python
-#
-# Copyright 2008 Google Inc.
-#
-# 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.
-#
-
-import wsgiref.handlers\n'
-from google.appengine.ext import zipserve\n'
-from google.appengine.ext import webapp\n'
-import memcache_zipserve\n\n\n'
-class MainHandler(webapp.RequestHandler):
-
-  def get(self):
-    self.response.out.write('Hello world!')
-
-def main():
-  application = webapp.WSGIApplication(['/(.*)',
-    memcache_zipserve.create_handler(["""
-
-file_endpiece = """])),
-],
-debug=False)
-  wsgiref.handlers.CGIHandler().run(application)
-
-if __name__ == __main__:
-  main()"""
diff --git a/tools/scripts/divide_and_compress_test.py b/tools/scripts/divide_and_compress_test.py
deleted file mode 100755
index 426449a..0000000
--- a/tools/scripts/divide_and_compress_test.py
+++ /dev/null
@@ -1,489 +0,0 @@
-#!/usr/bin/python2.4
-#
-# Copyright (C) 2008 Google Inc.
-#
-# 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.
-#
-
-"""Tests for divide_and_compress.py.
-
-TODO(jmatt): Add tests for module methods.
-"""
-
-__author__ = 'jmatt@google.com (Justin Mattson)'
-
-import os
-import stat
-import unittest
-import zipfile
-
-import divide_and_compress
-import mox
-
-
-class BagOfParts(object):
-  """Just a generic class that I can use to assign random attributes to."""
-
-  def NoOp(self):
-    x = 1
-
-    
-class ValidAndRemoveTests(unittest.TestCase):
-  """Test the ArchiveIsValid and RemoveLastFile methods."""
-  
-  def setUp(self):
-    """Prepare the test.
-
-    Construct some mock objects for use with the tests.
-    """
-    self.my_mox = mox.Mox()
-    file1 = BagOfParts()
-    file1.filename = 'file1.txt'
-    file1.contents = 'This is a test file'
-    file2 = BagOfParts()
-    file2.filename = 'file2.txt'
-    file2.contents = ('akdjfk;djsf;kljdslkfjslkdfjlsfjkdvn;kn;2389rtu4i'
-                      'tn;ghf8:89H*hp748FJw80fu9WJFpwf39pujens;fihkhjfk'
-                      'sdjfljkgsc n;iself')
-    self.files = {'file1': file1, 'file2': file2}
-
-  def tearDown(self):
-    """Remove any stubs we've created."""
-    self.my_mox.UnsetStubs()
-
-  def testArchiveIsValid(self):
-    """Test the DirectoryZipper.ArchiveIsValid method.
-
-    Run two tests, one that we expect to pass and one that we expect to fail
-    """
-    test_file_size = 1056730
-    self.my_mox.StubOutWithMock(os, 'stat')
-    os.stat('/foo/0.zip').AndReturn([test_file_size])
-    self.my_mox.StubOutWithMock(stat, 'ST_SIZE')
-    stat.ST_SIZE = 0
-    os.stat('/baz/0.zip').AndReturn([test_file_size])
-    mox.Replay(os.stat)
-    test_target = divide_and_compress.DirectoryZipper('/foo/', 'bar', 
-                                                      test_file_size - 1, True)
-
-    self.assertEqual(False, test_target.ArchiveIsValid(),
-                     msg=('ERROR: Test failed, ArchiveIsValid should have '
-                          'returned false, but returned true'))
-
-    test_target = divide_and_compress.DirectoryZipper('/baz/', 'bar',
-                                                      test_file_size + 1, True)
-    self.assertEqual(True, test_target.ArchiveIsValid(),
-                     msg=('ERROR: Test failed, ArchiveIsValid should have'
-                          ' returned true, but returned false'))
-
-  def testRemoveLastFile(self):
-    """Test DirectoryZipper.RemoveLastFile method.
-
-    Construct a ZipInfo mock object with two records, verify that write is
-    only called once on the new ZipFile object.
-    """
-    source = self.CreateZipSource()
-    dest = self.CreateZipDestination()
-    source_path = ''.join([os.getcwd(), '/0-old.zip'])
-    dest_path = ''.join([os.getcwd(), '/0.zip'])
-    test_target = divide_and_compress.DirectoryZipper(
-        ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True)
-    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
-    test_target.OpenZipFileAtPath(source_path, mode='r').AndReturn(source)
-    test_target.OpenZipFileAtPath(dest_path,
-                                  compress=zipfile.ZIP_DEFLATED,
-                                  mode='w').AndReturn(dest)
-    self.my_mox.StubOutWithMock(os, 'rename')
-    os.rename(dest_path, source_path)
-    self.my_mox.StubOutWithMock(os, 'unlink')
-    os.unlink(source_path)
-    
-    self.my_mox.ReplayAll()
-    test_target.RemoveLastFile()
-    self.my_mox.VerifyAll()    
-
-  def CreateZipSource(self):
-    """Create a mock zip sourec object.
-
-    Read should only be called once, because the second file is the one
-    being removed.
-
-    Returns:
-      A configured mocked
-    """
-    
-    source_zip = self.my_mox.CreateMock(zipfile.ZipFile)
-    source_zip.infolist().AndReturn([self.files['file1'], self.files['file1']])
-    source_zip.infolist().AndReturn([self.files['file1'], self.files['file1']])
-    source_zip.read(self.files['file1'].filename).AndReturn(
-        self.files['file1'].contents)
-    source_zip.close()
-    return source_zip
-
-  def CreateZipDestination(self):
-    """Create mock destination zip.
-
-    Write should only be called once, because there are two files in the
-    source zip and we expect the second to be removed.
-
-    Returns:
-      A configured mocked
-    """
-    
-    dest_zip = mox.MockObject(zipfile.ZipFile)
-    dest_zip.writestr(self.files['file1'].filename,
-                      self.files['file1'].contents)
-    dest_zip.close()
-    return dest_zip
-
-
-class FixArchiveTests(unittest.TestCase):
-  """Tests for the DirectoryZipper.FixArchive method."""
-  
-  def setUp(self):
-    """Create a mock file object."""
-    self.my_mox = mox.Mox()
-    self.file1 = BagOfParts()
-    self.file1.filename = 'file1.txt'
-    self.file1.contents = 'This is a test file'
-
-  def tearDown(self):
-    """Unset any mocks that we've created."""
-    self.my_mox.UnsetStubs()
-
-  def _InitMultiFileData(self):
-    """Create an array of mock file objects.
-
-    Create three mock file objects that we can use for testing.
-    """
-    self.multi_file_dir = []
-    
-    file1 = BagOfParts()
-    file1.filename = 'file1.txt'
-    file1.contents = 'kjaskl;jkdjfkja;kjsnbvjnvnbuewklriujalvjsd'
-    self.multi_file_dir.append(file1)
-
-    file2 = BagOfParts()
-    file2.filename = 'file2.txt'
-    file2.contents = ('He entered the room and there in the center, it was.'
-                      ' Looking upon the thing, suddenly he could not remember'
-                      ' whether he had actually seen it before or whether'
-                      ' his memory of it was merely the effect of something'
-                      ' so often being imagined that it had long since become '
-                      ' manifest in his mind.')
-    self.multi_file_dir.append(file2)
-
-    file3 = BagOfParts()
-    file3.filename = 'file3.txt'
-    file3.contents = 'Whoa, what is \'file2.txt\' all about?'
-    self.multi_file_dir.append(file3)
-    
-  def testSingleFileArchive(self):
-    """Test behavior of FixArchive when the archive has a single member.
-
-    We expect that when this method is called with an archive that has a
-    single member that it will return False and unlink the archive.
-    """
-    test_target = divide_and_compress.DirectoryZipper(
-        ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True)
-    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
-    test_target.OpenZipFileAtPath(
-        ''.join([os.getcwd(), '/0.zip']), mode='r').AndReturn(
-            self.CreateSingleFileMock())
-    self.my_mox.StubOutWithMock(os, 'unlink')
-    os.unlink(''.join([os.getcwd(), '/0.zip']))
-    self.my_mox.ReplayAll()
-    self.assertEqual(False, test_target.FixArchive('SIZE'))
-    self.my_mox.VerifyAll()
-
-  def CreateSingleFileMock(self):
-    """Create a mock ZipFile object for testSingleFileArchive.
-
-    We just need it to return a single member infolist twice
-
-    Returns:
-      A configured mock object
-    """
-    mock_zip = self.my_mox.CreateMock(zipfile.ZipFile)
-    mock_zip.infolist().AndReturn([self.file1])
-    mock_zip.infolist().AndReturn([self.file1])
-    mock_zip.close()
-    return mock_zip
-
-  def testMultiFileArchive(self):
-    """Test behavior of DirectoryZipper.FixArchive with a multi-file archive.
-
-    We expect that FixArchive will rename the old archive, adding '-old' before
-    '.zip', read all the members except the last one of '-old' into a new
-    archive with the same name as the original, and then unlink the '-old' copy
-    """
-    test_target = divide_and_compress.DirectoryZipper(
-        ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True)
-    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
-    test_target.OpenZipFileAtPath(
-        ''.join([os.getcwd(), '/0.zip']), mode='r').AndReturn(
-            self.CreateMultiFileMock())
-    self.my_mox.StubOutWithMock(test_target, 'RemoveLastFile')
-    test_target.RemoveLastFile(''.join([os.getcwd(), '/0.zip']))
-    self.my_mox.StubOutWithMock(os, 'stat')
-    os.stat(''.join([os.getcwd(), '/0.zip'])).AndReturn([49302])
-    self.my_mox.StubOutWithMock(stat, 'ST_SIZE')
-    stat.ST_SIZE = 0
-    self.my_mox.ReplayAll()
-    self.assertEqual(True, test_target.FixArchive('SIZE'))
-    self.my_mox.VerifyAll()
-
-  def CreateMultiFileMock(self):
-    """Create mock ZipFile object for use with testMultiFileArchive.
-
-    The mock just needs to return the infolist mock that is prepared in
-    InitMultiFileData()
-
-    Returns:
-      A configured mock object
-    """
-    self._InitMultiFileData()
-    mock_zip = self.my_mox.CreateMock(zipfile.ZipFile)
-    mock_zip.infolist().AndReturn(self.multi_file_dir)
-    mock_zip.close()
-    return mock_zip
-
-
-class AddFileToArchiveTest(unittest.TestCase):
-  """Test behavior of method to add a file to an archive."""
-
-  def setUp(self):
-    """Setup the arguments for the DirectoryZipper object."""
-    self.my_mox = mox.Mox()
-    self.output_dir = '%s/' % os.getcwd()
-    self.file_to_add = 'file.txt'
-    self.input_dir = '/foo/bar/baz/'
-
-  def tearDown(self):
-    self.my_mox.UnsetStubs()
-
-  def testAddFileToArchive(self):
-    """Test the DirectoryZipper.AddFileToArchive method.
-
-    We are testing a pretty trivial method, we just expect it to look at the
-    file its adding, so that it possible can through out a warning.
-    """
-    test_target = divide_and_compress.DirectoryZipper(self.output_dir,
-                                                      self.input_dir,
-                                                      1024*1024, True)
-    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
-    archive_mock = self.CreateArchiveMock()
-    test_target.OpenZipFileAtPath(
-        ''.join([self.output_dir, '0.zip']),
-        compress=zipfile.ZIP_DEFLATED).AndReturn(archive_mock)
-    self.StubOutOsModule()
-    self.my_mox.ReplayAll()
-    test_target.AddFileToArchive(''.join([self.input_dir, self.file_to_add]),
-                                 zipfile.ZIP_DEFLATED)
-    self.my_mox.VerifyAll()
-
-  def StubOutOsModule(self):
-    """Create a mock for the os.path and os.stat objects.
-
-    Create a stub that will return the type (file or directory) and size of the
-    object that is to be added.
-    """
-    self.my_mox.StubOutWithMock(os.path, 'isfile')
-    os.path.isfile(''.join([self.input_dir, self.file_to_add])).AndReturn(True)
-    self.my_mox.StubOutWithMock(os, 'stat')
-    os.stat(''.join([self.input_dir, self.file_to_add])).AndReturn([39480])
-    self.my_mox.StubOutWithMock(stat, 'ST_SIZE')
-    stat.ST_SIZE = 0
-    
-  def CreateArchiveMock(self):
-    """Create a mock ZipFile for use with testAddFileToArchive.
-
-    Just verify that write is called with the file we expect and that the
-    archive is closed after the file addition
-
-    Returns:
-      A configured mock object
-    """
-    archive_mock = self.my_mox.CreateMock(zipfile.ZipFile)
-    archive_mock.write(''.join([self.input_dir, self.file_to_add]),
-                       self.file_to_add)
-    archive_mock.close()
-    return archive_mock
-
-
-class CompressDirectoryTest(unittest.TestCase):
-  """Test the master method of the class.
-
-  Testing with the following directory structure.
-  /dir1/
-  /dir1/file1.txt
-  /dir1/file2.txt
-  /dir1/dir2/
-  /dir1/dir2/dir3/
-  /dir1/dir2/dir4/
-  /dir1/dir2/dir4/file3.txt
-  /dir1/dir5/
-  /dir1/dir5/file4.txt
-  /dir1/dir5/file5.txt
-  /dir1/dir5/file6.txt
-  /dir1/dir5/file7.txt
-  /dir1/dir6/
-  /dir1/dir6/file8.txt
-
-  file1.txt., file2.txt, file3.txt should be in 0.zip
-  file4.txt should be in 1.zip
-  file5.txt, file6.txt should be in 2.zip
-  file7.txt will not be stored since it will be too large compressed
-  file8.txt should b in 3.zip
-  """
-
-  def setUp(self):
-    """Setup all the mocks for this test."""
-    self.my_mox = mox.Mox()
-
-    self.base_dir = '/dir1'
-    self.output_path = '/out_dir/'
-    self.test_target = divide_and_compress.DirectoryZipper(
-        self.output_path, self.base_dir, 1024*1024, True)
-    
-    self.InitArgLists()
-    self.InitOsDotPath()
-    self.InitArchiveIsValid()
-    self.InitWriteIndexRecord()
-    self.InitAddFileToArchive()
-
-  def tearDown(self):
-    self.my_mox.UnsetStubs()
-
-  def testCompressDirectory(self):
-    """Test the DirectoryZipper.CompressDirectory method."""
-    self.my_mox.ReplayAll()
-    for arguments in self.argument_lists:
-      self.test_target.CompressDirectory(None, arguments[0], arguments[1])
-    self.my_mox.VerifyAll()
-
-  def InitAddFileToArchive(self):
-    """Setup mock for DirectoryZipper.AddFileToArchive.
-
-    Make sure that the files are added in the order we expect.
-    """
-    self.my_mox.StubOutWithMock(self.test_target, 'AddFileToArchive')
-    self.test_target.AddFileToArchive('/dir1/file1.txt', zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/file2.txt', zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir2/dir4/file3.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir5/file4.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir5/file4.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir5/file5.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir5/file5.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir5/file6.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir5/file7.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir5/file7.txt',
-                                      zipfile.ZIP_DEFLATED)
-    self.test_target.AddFileToArchive('/dir1/dir6/file8.txt',
-                                      zipfile.ZIP_DEFLATED)
-  
-  def InitWriteIndexRecord(self):
-    """Setup mock for DirectoryZipper.WriteIndexRecord."""
-    self.my_mox.StubOutWithMock(self.test_target, 'WriteIndexRecord')
-
-    # we are trying to compress 8 files, but we should only attempt to
-    # write an index record 7 times, because one file is too large to be stored
-    self.test_target.WriteIndexRecord().AndReturn(True)
-    self.test_target.WriteIndexRecord().AndReturn(False)
-    self.test_target.WriteIndexRecord().AndReturn(False)
-    self.test_target.WriteIndexRecord().AndReturn(True)
-    self.test_target.WriteIndexRecord().AndReturn(True)
-    self.test_target.WriteIndexRecord().AndReturn(False)
-    self.test_target.WriteIndexRecord().AndReturn(True)
-
-  def InitArchiveIsValid(self):
-    """Mock out DirectoryZipper.ArchiveIsValid and DirectoryZipper.FixArchive.
-
-    Mock these methods out such that file1, file2, and file3 go into one
-    archive. file4 then goes into the next archive, file5 and file6 in the
-    next, file 7 should appear too large to compress into an archive, and
-    file8 goes into the final archive
-    """
-    self.my_mox.StubOutWithMock(self.test_target, 'ArchiveIsValid')
-    self.my_mox.StubOutWithMock(self.test_target, 'FixArchive')
-    self.test_target.ArchiveIsValid().AndReturn(True)
-    self.test_target.ArchiveIsValid().AndReturn(True)
-    self.test_target.ArchiveIsValid().AndReturn(True)
-
-    # should be file4.txt
-    self.test_target.ArchiveIsValid().AndReturn(False)
-    self.test_target.FixArchive('SIZE').AndReturn(True)
-    self.test_target.ArchiveIsValid().AndReturn(True)
-
-    # should be file5.txt
-    self.test_target.ArchiveIsValid().AndReturn(False)
-    self.test_target.FixArchive('SIZE').AndReturn(True)
-    self.test_target.ArchiveIsValid().AndReturn(True)
-    self.test_target.ArchiveIsValid().AndReturn(True)
-
-    # should be file7.txt
-    self.test_target.ArchiveIsValid().AndReturn(False)
-    self.test_target.FixArchive('SIZE').AndReturn(True)
-    self.test_target.ArchiveIsValid().AndReturn(False)
-    self.test_target.FixArchive('SIZE').AndReturn(False)
-    self.test_target.ArchiveIsValid().AndReturn(True)
-    
-  def InitOsDotPath(self):
-    """Mock out os.path.isfile.
-
-    Mock this out so the things we want to appear as files appear as files and
-    the things we want to appear as directories appear as directories. Also
-    make sure that the order of file visits is as we expect (which is why
-    InAnyOrder isn't used here).
-    """
-    self.my_mox.StubOutWithMock(os.path, 'isfile')
-    os.path.isfile('/dir1/dir2').AndReturn(False)
-    os.path.isfile('/dir1/dir5').AndReturn(False)
-    os.path.isfile('/dir1/dir6').AndReturn(False)
-    os.path.isfile('/dir1/file1.txt').AndReturn(True)
-    os.path.isfile('/dir1/file2.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir2/dir3').AndReturn(False)
-    os.path.isfile('/dir1/dir2/dir4').AndReturn(False)
-    os.path.isfile('/dir1/dir2/dir4/file3.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir5/file4.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir5/file4.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir5/file5.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir5/file5.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir5/file6.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir5/file7.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir5/file7.txt').AndReturn(True)
-    os.path.isfile('/dir1/dir6/file8.txt').AndReturn(True)
-
-  def InitArgLists(self):
-    """Create the directory path => directory contents mappings."""
-    self.argument_lists = []
-    self.argument_lists.append(['/dir1',
-                                ['file1.txt', 'file2.txt', 'dir2', 'dir5',
-                                 'dir6']])
-    self.argument_lists.append(['/dir1/dir2', ['dir3', 'dir4']])
-    self.argument_lists.append(['/dir1/dir2/dir3', []])
-    self.argument_lists.append(['/dir1/dir2/dir4', ['file3.txt']])
-    self.argument_lists.append(['/dir1/dir5',
-                                ['file4.txt', 'file5.txt', 'file6.txt',
-                                 'file7.txt']])
-    self.argument_lists.append(['/dir1/dir6', ['file8.txt']])
-      
-if __name__ == '__main__':
-  unittest.main()
diff --git a/tools/scripts/doc_source.properties b/tools/scripts/doc_source.properties
deleted file mode 100644
index fab394a..0000000
--- a/tools/scripts/doc_source.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-Pkg.UserSrc=false
-Platform.Version=2.0
-Pkg.Revision=1
-AndroidVersion.ApiLevel=5
-
diff --git a/tools/scripts/icon_hdpi.png b/tools/scripts/icon_hdpi.png
deleted file mode 100644
index 8074c4c..0000000
--- a/tools/scripts/icon_hdpi.png
+++ /dev/null
Binary files differ
diff --git a/tools/scripts/icon_ldpi.png b/tools/scripts/icon_ldpi.png
deleted file mode 100644
index 1095584..0000000
--- a/tools/scripts/icon_ldpi.png
+++ /dev/null
Binary files differ
diff --git a/tools/scripts/icon_mdpi.png b/tools/scripts/icon_mdpi.png
deleted file mode 100644
index a07c69f..0000000
--- a/tools/scripts/icon_mdpi.png
+++ /dev/null
Binary files differ
diff --git a/tools/scripts/java_file.template b/tools/scripts/java_file.template
deleted file mode 100644
index 19714a8..0000000
--- a/tools/scripts/java_file.template
+++ /dev/null
@@ -1,15 +0,0 @@
-package PACKAGE;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class ACTIVITY_CLASS_NAME extends Activity
-{
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState)
-    {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-    }
-}
diff --git a/tools/scripts/java_tests_file.template b/tools/scripts/java_tests_file.template
deleted file mode 100644
index 08d6f9b..0000000
--- a/tools/scripts/java_tests_file.template
+++ /dev/null
@@ -1,21 +0,0 @@
-package PACKAGE;
-
-import android.test.ActivityInstrumentationTestCase2;
-
-/**
- * This is a simple framework for a test of an Application.  See
- * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
- * how to write and extend Application tests.
- * <p/>
- * To run this test, you can type:
- * adb shell am instrument -w \
- * -e class ACTIVITY_FQ_NAME \
- * PACKAGE.tests/android.test.InstrumentationTestRunner
- */
-public class ACTIVITY_CLASS_NAME extends ActivityInstrumentationTestCase2<ACTIVITY_TESTED_CLASS_NAME> {
-
-    public ACTIVITY_CLASS_NAME() {
-        super("PACKAGE", ACTIVITY_TESTED_CLASS_NAME.class);
-    }
-
-}
\ No newline at end of file
diff --git a/tools/scripts/layout.template b/tools/scripts/layout.template
deleted file mode 100644
index f5e367c..0000000
--- a/tools/scripts/layout.template
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    >
-<TextView  
-    android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" 
-    android:text="Hello World, ACTIVITY_ENTRY_NAME"
-    />
-</LinearLayout>
-
diff --git a/tools/scripts/platform_source.properties b/tools/scripts/platform_source.properties
deleted file mode 100644
index 01f7807..0000000
--- a/tools/scripts/platform_source.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-Pkg.Desc=Android SDK Platform 2.0_r1
-Pkg.UserSrc=false
-Platform.Version=2.0
-Pkg.Revision=1
-AndroidVersion.ApiLevel=5
diff --git a/tools/scripts/plugin.prop b/tools/scripts/plugin.prop
deleted file mode 100644
index 39a8c42..0000000
--- a/tools/scripts/plugin.prop
+++ /dev/null
@@ -1,3 +0,0 @@
-# begin plugin.prop
-plugin.version=0.9.4
-# end plugin.prop
\ No newline at end of file
diff --git a/tools/scripts/sdk_files_NOTICE.txt b/tools/scripts/sdk_files_NOTICE.txt
deleted file mode 100644
index 1fdb31d..0000000
--- a/tools/scripts/sdk_files_NOTICE.txt
+++ /dev/null
@@ -1,195 +0,0 @@
-Notice for all the files in this folder.
-------------------------------------------------------------
-
-
-
-   Copyright (c) 2005-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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-
diff --git a/tools/scripts/strings.template b/tools/scripts/strings.template
deleted file mode 100644
index ee5af40..0000000
--- a/tools/scripts/strings.template
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="app_name">ACTIVITY_ENTRY_NAME</string>
-</resources>
diff --git a/tools/scripts/tools_source.properties b/tools/scripts/tools_source.properties
deleted file mode 100644
index b75e326..0000000
--- a/tools/scripts/tools_source.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-Pkg.UserSrc=false
-Pkg.Revision=4
diff --git a/tools/scripts/usbdriver_source.properties b/tools/scripts/usbdriver_source.properties
deleted file mode 100755
index 9db3852..0000000
--- a/tools/scripts/usbdriver_source.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-Pkg.Revision=1
-Archive.Os=WINDOWS
-Archive.Arch=ANY
-Extra.Path=usb_driver
diff --git a/tools/sdklauncher/.gitignore b/tools/sdklauncher/.gitignore
deleted file mode 100644
index 0c25b2a..0000000
--- a/tools/sdklauncher/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-images/android_icon.o
diff --git a/tools/sdklauncher/Android.mk b/tools/sdklauncher/Android.mk
deleted file mode 100644
index 3e92ea8..0000000
--- a/tools/sdklauncher/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-#
-# Android.mk for sdklauncher
-#
-# The "SDK Launcher" is for Windows only.
-# This simple .exe will sit at the root of the Windows SDK
-# and currently simply executes tools\android.bat.
-# Eventually it should simply replace the batch file.
-
-ifeq ($(HOST_OS),windows)
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	sdklauncher.c
-
-LOCAL_CFLAGS += -Wall -Wno-unused-parameter
-LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY
-LOCAL_MODULE := sdklauncher
-
-# Link the Windows icon file as well into the executable, based on the technique
-# used in external/qemu/Makefile.android.
-#
-INTERMEDIATE     := $(call intermediates-dir-for,EXECUTABLES,$(LOCAL_MODULE),true)
-ANDROID_ICON_OBJ := android_icon.o
-ANDROID_ICON_PATH := $(LOCAL_PATH)/images
-$(ANDROID_ICON_PATH)/$(ANDROID_ICON_OBJ): $(ANDROID_ICON_PATH)/android_icon.rc
-	windres $< -I $(ANDROID_ICON_PATH) -o $@
-
-# seems to be the only way to add an object file that was not generated from
-# a C/C++/Java source file to our build system. and very unfortunately,
-# $(TOPDIR)/$(LOCALPATH) will always be prepended to this value, which forces
-# us to put the object file in the source directory...
-#
-LOCAL_PREBUILT_OBJ_FILES += images/$(ANDROID_ICON_OBJ)
-
-include $(BUILD_HOST_EXECUTABLE)
-
-$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE))
-
-endif
diff --git a/tools/sdklauncher/images/android_icon.ico b/tools/sdklauncher/images/android_icon.ico
deleted file mode 100644
index bd25179..0000000
--- a/tools/sdklauncher/images/android_icon.ico
+++ /dev/null
Binary files differ
diff --git a/tools/sdklauncher/images/android_icon.rc b/tools/sdklauncher/images/android_icon.rc
deleted file mode 100644
index df468ac..0000000
--- a/tools/sdklauncher/images/android_icon.rc
+++ /dev/null
@@ -1,3 +0,0 @@
-1 ICON "../images/android_icon.ico"
-
-
diff --git a/tools/sdklauncher/sdklauncher.c b/tools/sdklauncher/sdklauncher.c
deleted file mode 100644
index d052284..0000000
--- a/tools/sdklauncher/sdklauncher.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The "SDK Launcher" is for Windows only.
- * This simple .exe will sit at the root of the Windows SDK
- * and currently simply executes tools\android.bat.
- * Eventually it should simply replace the batch file.
- *
- * TODO:
- * - detect that java is installed; error dialog if not, explaning where to get it.
- * - create temp dir, always copy *.jar there, exec android.jar
- * - get jars to copy from some file
- * - use a version number to copy jars only if needed (tools.revision?)
- */
-
-#ifdef _WIN32
-
-#include <stdio.h>
-#include <windows.h>
-
-int sdk_launcher() {
-    STARTUPINFO           startup;
-    PROCESS_INFORMATION   pinfo;
-    char                  program_path[MAX_PATH];
-    int                   ret;
-
-    ZeroMemory(&startup, sizeof(startup));
-    startup.cb = sizeof(startup);
-
-    ZeroMemory(&pinfo, sizeof(pinfo));
-
-    /* get path of current program */
-    GetModuleFileName(NULL, program_path, sizeof(program_path));
-
-    ret = CreateProcess(
-            NULL,                                  /* program path */
-            "tools\\android.bat update sdk",         /* command-line */
-            NULL,                  /* process handle is not inheritable */
-            NULL,                   /* thread handle is not inheritable */
-            TRUE,                          /* yes, inherit some handles */
-            CREATE_NO_WINDOW,                /* we don't want a console */
-            NULL,                     /* use parent's environment block */
-            NULL,                    /* use parent's starting directory */
-            &startup,                 /* startup info, i.e. std handles */
-            &pinfo);
-
-    if (!ret) {
-        DWORD err = GetLastError();
-        fprintf(stderr, "CreateProcess failure, error %ld\n", err);
-
-        LPSTR s;
-        if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */
-                          FORMAT_MESSAGE_FROM_SYSTEM,
-                          NULL,                             /* lpSource */
-                          err,                              /* dwMessageId */
-                          0,                                /* dwLanguageId */
-                          (LPSTR)&s,                        /* lpBuffer */
-                          0,                                /* nSize */
-                          NULL) != 0) {                     /* va_list args */
-            fprintf(stderr, "%s", s);
-            LocalFree(s);
-        }
-
-        return -1;
-    }
-
-    return 0;
-}
-
-int main(int argc, char **argv) {
-    return sdk_launcher();
-}
-
-#endif /* _WIN32 */
diff --git a/tools/sdkmanager/.gitignore b/tools/sdkmanager/.gitignore
deleted file mode 100644
index 48f206a..0000000
--- a/tools/sdkmanager/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-app/bin
-libs/sdklib/bin
-libs/sdkuilib/bin
-
diff --git a/tools/sdkmanager/Android.mk b/tools/sdkmanager/Android.mk
deleted file mode 100644
index 30df7f1..0000000
--- a/tools/sdkmanager/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-SDKMANAGER_LOCAL_DIR := $(call my-dir)
-include $(SDKMANAGER_LOCAL_DIR)/app/Android.mk
-include $(SDKMANAGER_LOCAL_DIR)/libs/Android.mk
diff --git a/tools/sdkmanager/MODULE_LICENSE_APACHE2 b/tools/sdkmanager/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/sdkmanager/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/sdkmanager/app/.classpath b/tools/sdkmanager/app/.classpath
deleted file mode 100644
index 3380ba1..0000000
--- a/tools/sdkmanager/app/.classpath
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="tests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/SdkUiLib"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/sdkmanager/app/.project b/tools/sdkmanager/app/.project
deleted file mode 100644
index aa82db5..0000000
--- a/tools/sdkmanager/app/.project
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>SdkManager</name>
-	<comment></comment>
-	<projects>
-		<project>SdkLib</project>
-		<project>SdkUiLib</project>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/sdkmanager/app/Android.mk b/tools/sdkmanager/app/Android.mk
deleted file mode 100644
index 24ba61f..0000000
--- a/tools/sdkmanager/app/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-SDKMANAGERAPP_LOCAL_DIR := $(call my-dir)
-include $(SDKMANAGERAPP_LOCAL_DIR)/etc/Android.mk
-include $(SDKMANAGERAPP_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkmanager/app/etc/Android.mk b/tools/sdkmanager/app/etc/Android.mk
deleted file mode 100644
index 8723cd8..0000000
--- a/tools/sdkmanager/app/etc/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := android
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/sdkmanager/app/etc/android b/tools/sdkmanager/app/etc/android
deleted file mode 100755
index 8feb5f2..0000000
--- a/tools/sdkmanager/app/etc/android
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/bin/sh
-# Copyright 2005-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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=sdkmanager.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo `basename "$prog"`": can't find $jarfile"
-    exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
-    # add this in for debugging
-    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
-    shift 1
-else
-    java_debug=
-fi
-
-java_cmd="java"
-
-# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
-if [ `uname` = "Darwin" ]; then
-    os_opts="-XstartOnFirstThread"
-else
-    os_opts=
-fi
-
-if [ `uname` = "Linux" ]; then
-    export GDK_NATIVE_WINDOWS=true
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
-    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
-    progdir=`cygpath -w  "$progdir"`
-else
-    jarpath="$frameworkdir/$jarfile"
-fi
-
-# Figure out the path to the swt.jar for the current architecture.
-# if ANDROID_SWT is defined, then just use this.
-# else, if running in the Android source tree, then look for the correct swt folder in prebuilt
-# else, look for the correct swt folder in the SDK under tools/lib/
-swtpath=""
-if [ -n "$ANDROID_SWT" ]; then
-    swtpath="$ANDROID_SWT"
-else
-    vmarch=`${java_cmd} -jar "${frameworkdir}"/archquery.jar`
-    if [ -n "$ANDROID_BUILD_TOP" ]; then
-        osname=`uname -s | tr A-Z a-z`
-        swtpath="${ANDROID_BUILD_TOP}/prebuilt/${osname}-${vmarch}/swt"
-    else
-        swtpath="${frameworkdir}/${vmarch}"
-    fi
-fi
-
-# Combine the swtpath and the framework dir path.
-if [ -d "$swtpath" ]; then
-    frameworkdir="${swtpath}:${frameworkdir}"
-else
-    echo "SWT folder '${swtpath}' does not exist."
-    echo "Please export ANDROID_SWT to point to the folder containing swt.jar for your platform."
-    exit 1
-fi
-
-if [ -z "$1" ]; then
-    echo "Starting Android SDK and AVD Manager"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec "$java_cmd" -Xmx256M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Dcom.android.sdkmanager.toolsdir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/sdkmanager/app/etc/android.bat b/tools/sdkmanager/app/etc/android.bat
deleted file mode 100755
index 58790ce..0000000
--- a/tools/sdkmanager/app/etc/android.bat
+++ /dev/null
@@ -1,70 +0,0 @@
-@echo off
-rem Copyright (C) 2007 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Grab current directory before we change it
-set workdir=%cd%
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-set jarpath=lib\sdkmanager.jar
-
-rem Set SWT.Jar path based on current architecture (x86 or x86_64)
-for /f %%a in ('java -jar lib\archquery.jar') do set swt_path=lib\%%a
-
-if "%1 %2"=="update sdk" goto StartUi
-if not "%1"=="" goto EndTempCopy
-:StartUi
-    echo Starting Android SDK and AVD Manager
-
-    rem We're now going to create a temp dir to hold all the Jar files needed
-    rem to run the android tool, copy them in the temp dir and finally execute
-    rem from that path. We do this only when the launcher is run without
-    rem arguments, to display the SDK Updater UI. This allows the updater to
-    rem update the tools directory where the updater itself is located.
-
-    set tmpdir=%TEMP%\temp-android-tool
-    xcopy lib\x86 %tmpdir%\lib\x86 /I /E /C /G /R /Y /Q > nul
-    copy /B /D /Y lib\androidprefs.jar   %tmpdir%\lib\       > nul
-    copy /B /D /Y lib\org.eclipse.*      %tmpdir%\lib\       > nul
-    copy /B /D /Y lib\sdk*               %tmpdir%\lib\       > nul
-    copy /B /D /Y lib\commons-compress*  %tmpdir%\lib\       > nul
-
-    rem jarpath and swt_path are relative to PWD so we don't need to adjust them, just change dirs.
-    set toolsdir=%cd%
-    cd %tmpdir%
-
-:EndTempCopy
-    
-rem The global ANDROID_SWT always override the SWT.Jar path
-if defined ANDROID_SWT set swt_path=%ANDROID_SWT%
-
-if exist %swt_path% goto SetPath
-    echo SWT folder '%swt_path%' does not exist.
-    echo Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.
-    exit /B
-
-:SetPath
-set javaextdirs=%swt_path%;lib\
-
-call java -Djava.ext.dirs=%javaextdirs% -Dcom.android.sdkmanager.toolsdir="%toolsdir%" -Dcom.android.sdkmanager.workdir="%workdir%" -jar %jarpath% %*
diff --git a/tools/sdkmanager/app/etc/manifest.txt b/tools/sdkmanager/app/etc/manifest.txt
deleted file mode 100644
index 5676634..0000000
--- a/tools/sdkmanager/app/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.sdkmanager.Main
diff --git a/tools/sdkmanager/app/src/Android.mk b/tools/sdkmanager/app/src/Android.mk
deleted file mode 100644
index b51a113..0000000
--- a/tools/sdkmanager/app/src/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := .
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	androidprefs \
-	sdklib \
-	sdkuilib \
-	swt \
-	org.eclipse.jface_3.4.2.M20090107-0800 \
-	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
-	org.eclipse.core.commands_3.4.0.I20080509-2000
-
-LOCAL_MODULE := sdkmanager
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
deleted file mode 100644
index ab105ec..0000000
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * 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.android.sdkmanager;
-
-import com.android.sdklib.ISdkLog;
-
-import java.util.HashMap;
-import java.util.Map.Entry;
-
-/**
- * Parses the command-line and stores flags needed or requested.
- * <p/>
- * This is a base class. To be useful you want to:
- * <ul>
- * <li>override it.
- * <li>pass an action array to the constructor.
- * <li>define flags for your actions.
- * </ul>
- * <p/>
- * To use, call {@link #parseArgs(String[])} and then
- * call {@link #getValue(String, String, String)}.
- */
-class CommandLineProcessor {
-
-    /*
-     * Steps needed to add a new action:
-     * - Each action is defined as a "verb object" followed by parameters.
-     * - Either reuse a VERB_ constant or define a new one.
-     * - Either reuse an OBJECT_ constant or define a new one.
-     * - Add a new entry to mAction with a one-line help summary.
-     * - In the constructor, add a define() call for each parameter (either mandatory
-     *   or optional) for the given action.
-     */
-
-    /** Internal verb name for internally hidden flags. */
-    public final static String GLOBAL_FLAG_VERB = "@@internal@@";
-
-    /** String to use when the verb doesn't need any object. */
-    public final static String NO_VERB_OBJECT = "";
-
-    /** The global help flag. */
-    public static final String KEY_HELP = "help";
-    /** The global verbose flag. */
-    public static final String KEY_VERBOSE = "verbose";
-    /** The global silent flag. */
-    public static final String KEY_SILENT = "silent";
-
-    /** Verb requested by the user. Null if none specified, which will be an error. */
-    private String mVerbRequested;
-    /** Direct object requested by the user. Can be null. */
-    private String mDirectObjectRequested;
-
-    /**
-     * Action definitions.
-     * <p/>
-     * This list serves two purposes: first it is used to know which verb/object
-     * actions are acceptable on the command-line; second it provides a summary
-     * for each action that is printed in the help.
-     * <p/>
-     * Each entry is a string array with:
-     * <ul>
-     * <li> the verb.
-     * <li> a direct object (use {@link #NO_VERB_OBJECT} if there's no object).
-     * <li> a description.
-     * <li> an alternate form for the object (e.g. plural).
-     * </ul>
-     */
-    private final String[][] mActions;
-
-    private static final int ACTION_VERB_INDEX = 0;
-    private static final int ACTION_OBJECT_INDEX = 1;
-    private static final int ACTION_DESC_INDEX = 2;
-    private static final int ACTION_ALT_OBJECT_INDEX = 3;
-
-    /**
-     * The map of all defined arguments.
-     * <p/>
-     * The key is a string "verb/directObject/longName".
-     */
-    private final HashMap<String, Arg> mArguments = new HashMap<String, Arg>();
-    /** Logger */
-    private final ISdkLog mLog;
-
-    /**
-     * Constructs a new command-line processor.
-     *
-     * @param logger An SDK logger object. Must not be null.
-     * @param actions The list of actions recognized on the command-line.
-     *                See the javadoc of {@link #mActions} for more details.
-     *
-     * @see #mActions
-     */
-    public CommandLineProcessor(ISdkLog logger, String[][] actions) {
-        mLog = logger;
-        mActions = actions;
-
-        define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "v", KEY_VERBOSE,
-                "Verbose mode: errors, warnings and informational messages are printed.",
-                false);
-        define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "s", KEY_SILENT,
-                "Silent mode: only errors are printed out.",
-                false);
-        define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "h", KEY_HELP,
-                "This help.",
-                false);
-    }
-
-    /**
-     * Indicates if this command-line can work when no verb is specified.
-     * The default is false, which generates an error when no verb/object is specified.
-     * Derived implementations can set this to true if they can deal with a lack
-     * of verb/action.
-     */
-    public boolean acceptLackOfVerb() {
-        return false;
-    }
-
-
-    //------------------
-    // Helpers to get flags values
-
-    /** Helper that returns true if --verbose was requested. */
-    public boolean isVerbose() {
-        return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_VERBOSE)).booleanValue();
-    }
-
-    /** Helper that returns true if --silent was requested. */
-    public boolean isSilent() {
-        return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_SILENT)).booleanValue();
-    }
-
-    /** Helper that returns true if --help was requested. */
-    public boolean isHelpRequested() {
-        return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_HELP)).booleanValue();
-    }
-
-    /** Returns the verb name from the command-line. Can be null. */
-    public String getVerb() {
-        return mVerbRequested;
-    }
-
-    /** Returns the direct object name from the command-line. Can be null. */
-    public String getDirectObject() {
-        return mDirectObjectRequested;
-    }
-
-    //------------------
-
-    /**
-     * Raw access to parsed parameter values.
-     * <p/>
-     * The default is to scan all parameters. Parameters that have been explicitly set on the
-     * command line are returned first. Otherwise one with a non-null value is returned.
-     * <p/>
-     * Both a verb and a direct object filter can be specified. When they are non-null they limit
-     * the scope of the search.
-     * <p/>
-     * If nothing has been found, return the last default value seen matching the filter.
-     *
-     * @param verb The verb name, including {@link #GLOBAL_FLAG_VERB}. If null, all possible
-     *             verbs that match the direct object condition will be examined and the first
-     *             value set will be used.
-     * @param directObject The direct object name, including {@link #NO_VERB_OBJECT}. If null,
-     *             all possible direct objects that match the verb condition will be examined and
-     *             the first value set will be used.
-     * @param longFlagName The long flag name for the given action. Mandatory. Cannot be null.
-     * @return The current value object stored in the parameter, which depends on the argument mode.
-     */
-    public Object getValue(String verb, String directObject, String longFlagName) {
-
-        if (verb != null && directObject != null) {
-            String key = verb + "/" + directObject + "/" + longFlagName;
-            Arg arg = mArguments.get(key);
-            return arg.getCurrentValue();
-        }
-
-        Object lastDefault = null;
-        for (Arg arg : mArguments.values()) {
-            if (arg.getLongArg().equals(longFlagName)) {
-                if (verb == null || arg.getVerb().equals(verb)) {
-                    if (directObject == null || arg.getDirectObject().equals(directObject)) {
-                        if (arg.isInCommandLine()) {
-                            return arg.getCurrentValue();
-                        }
-                        if (arg.getCurrentValue() != null) {
-                            lastDefault = arg.getCurrentValue();
-                        }
-                    }
-                }
-            }
-        }
-
-        return lastDefault;
-    }
-
-    /**
-     * Internal setter for raw parameter value.
-     * @param verb The verb name, including {@link #GLOBAL_FLAG_VERB}.
-     * @param directObject The direct object name, including {@link #NO_VERB_OBJECT}.
-     * @param longFlagName The long flag name for the given action.
-     * @param value The new current value object stored in the parameter, which depends on the
-     *              argument mode.
-     */
-    protected void setValue(String verb, String directObject, String longFlagName, Object value) {
-        String key = verb + "/" + directObject + "/" + longFlagName;
-        Arg arg = mArguments.get(key);
-        arg.setCurrentValue(value);
-    }
-
-    /**
-     * Parses the command-line arguments.
-     * <p/>
-     * This method will exit and not return if a parsing error arise.
-     *
-     * @param args The arguments typically received by a main method.
-     */
-    public void parseArgs(String[] args) {
-        String needsHelp = null;
-        String verb = null;
-        String directObject = null;
-
-        try {
-            int n = args.length;
-            for (int i = 0; i < n; i++) {
-                Arg arg = null;
-                String a = args[i];
-                if (a.startsWith("--")) {
-                    arg = findLongArg(verb, directObject, a.substring(2));
-                } else if (a.startsWith("-")) {
-                    arg = findShortArg(verb, directObject, a.substring(1));
-                }
-
-                // No matching argument name found
-                if (arg == null) {
-                    // Does it looks like a dashed parameter?
-                    if (a.startsWith("-")) {
-                        if (verb == null || directObject == null) {
-                            // It looks like a dashed parameter and we don't have a a verb/object
-                            // set yet, the parameter was just given too early.
-
-                            needsHelp = String.format(
-                                "Flag '%1$s' is not a valid global flag. Did you mean to specify it after the verb/object name?",
-                                a);
-                            return;
-                        } else {
-                            // It looks like a dashed parameter and but it is unknown by this
-                            // verb-object combination
-
-                            needsHelp = String.format(
-                                    "Flag '%1$s' is not valid for '%2$s %3$s'.",
-                                    a, verb, directObject);
-                            return;
-                        }
-                    }
-
-                    if (verb == null) {
-                        // Fill verb first. Find it.
-                        for (String[] actionDesc : mActions) {
-                            if (actionDesc[ACTION_VERB_INDEX].equals(a)) {
-                                verb = a;
-                                break;
-                            }
-                        }
-
-                        // Error if it was not a valid verb
-                        if (verb == null) {
-                            needsHelp = String.format(
-                                "Expected verb after global parameters but found '%1$s' instead.",
-                                a);
-                            return;
-                        }
-
-                    } else if (directObject == null) {
-                        // Then fill the direct object. Find it.
-                        for (String[] actionDesc : mActions) {
-                            if (actionDesc[ACTION_VERB_INDEX].equals(verb)) {
-                                if (actionDesc[ACTION_OBJECT_INDEX].equals(a)) {
-                                    directObject = a;
-                                    break;
-                                } else if (actionDesc.length > ACTION_ALT_OBJECT_INDEX &&
-                                        actionDesc[ACTION_ALT_OBJECT_INDEX].equals(a)) {
-                                    // if the alternate form exist and is used, we internally
-                                    // only memorize the default direct object form.
-                                    directObject = actionDesc[ACTION_OBJECT_INDEX];
-                                    break;
-                                }
-                            }
-                        }
-
-                        // Error if it was not a valid object for that verb
-                        if (directObject == null) {
-                            needsHelp = String.format(
-                                "Expected verb after global parameters but found '%1$s' instead.",
-                                a);
-                            return;
-
-                        }
-                    }
-                } else if (arg != null) {
-                    // This argument was present on the command line
-                    arg.setInCommandLine(true);
-
-                    // Process keyword
-                    String error = null;
-                    if (arg.getMode().needsExtra()) {
-                        if (++i >= n) {
-                            needsHelp = String.format("Missing argument for flag %1$s.", a);
-                            return;
-                        }
-
-                        error = arg.getMode().process(arg, args[i]);
-                    } else {
-                        error = arg.getMode().process(arg, null);
-
-                        // If we just toggled help, we want to exit now without printing any error.
-                        // We do this test here only when a Boolean flag is toggled since booleans
-                        // are the only flags that don't take parameters and help is a boolean.
-                        if (isHelpRequested()) {
-                            printHelpAndExit(null);
-                            // The call above should terminate however in unit tests we override
-                            // it so we still need to return here.
-                            return;
-                        }
-                    }
-
-                    if (error != null) {
-                        needsHelp = String.format("Invalid usage for flag %1$s: %2$s.", a, error);
-                        return;
-                    }
-                }
-            }
-
-            if (needsHelp == null) {
-                if (verb == null && !acceptLackOfVerb()) {
-                    needsHelp = "Missing verb name.";
-                } else if (verb != null) {
-                    if (directObject == null) {
-                        // Make sure this verb has an optional direct object
-                        for (String[] actionDesc : mActions) {
-                            if (actionDesc[ACTION_VERB_INDEX].equals(verb) &&
-                                    actionDesc[ACTION_OBJECT_INDEX].equals(NO_VERB_OBJECT)) {
-                                directObject = NO_VERB_OBJECT;
-                                break;
-                            }
-                        }
-
-                        if (directObject == null) {
-                            needsHelp = String.format("Missing object name for verb '%1$s'.", verb);
-                            return;
-                        }
-                    }
-
-                    // Validate that all mandatory arguments are non-null for this action
-                    String missing = null;
-                    boolean plural = false;
-                    for (Entry<String, Arg> entry : mArguments.entrySet()) {
-                        Arg arg = entry.getValue();
-                        if (arg.getVerb().equals(verb) &&
-                                arg.getDirectObject().equals(directObject)) {
-                            if (arg.isMandatory() && arg.getCurrentValue() == null) {
-                                if (missing == null) {
-                                    missing = "--" + arg.getLongArg();
-                                } else {
-                                    missing += ", --" + arg.getLongArg();
-                                    plural = true;
-                                }
-                            }
-                        }
-                    }
-
-                    if (missing != null) {
-                        needsHelp  = String.format(
-                                "The %1$s %2$s must be defined for action '%3$s %4$s'",
-                                plural ? "parameters" : "parameter",
-                                missing,
-                                verb,
-                                directObject);
-                    }
-
-                    mVerbRequested = verb;
-                    mDirectObjectRequested = directObject;
-                }
-            }
-        } finally {
-            if (needsHelp != null) {
-                printHelpAndExitForAction(verb, directObject, needsHelp);
-            }
-        }
-    }
-
-    /**
-     * Finds an {@link Arg} given an action name and a long flag name.
-     * @return The {@link Arg} found or null.
-     */
-    protected Arg findLongArg(String verb, String directObject, String longName) {
-        if (verb == null) {
-            verb = GLOBAL_FLAG_VERB;
-        }
-        if (directObject == null) {
-            directObject = NO_VERB_OBJECT;
-        }
-        String key = verb + "/" + directObject + "/" + longName;
-        return mArguments.get(key);
-    }
-
-    /**
-     * Finds an {@link Arg} given an action name and a short flag name.
-     * @return The {@link Arg} found or null.
-     */
-    protected Arg findShortArg(String verb, String directObject, String shortName) {
-        if (verb == null) {
-            verb = GLOBAL_FLAG_VERB;
-        }
-        if (directObject == null) {
-            directObject = NO_VERB_OBJECT;
-        }
-
-        for (Entry<String, Arg> entry : mArguments.entrySet()) {
-            Arg arg = entry.getValue();
-            if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) {
-                if (shortName.equals(arg.getShortArg())) {
-                    return arg;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Prints the help/usage and exits.
-     *
-     * @param errorFormat Optional error message to print prior to usage using String.format
-     * @param args Arguments for String.format
-     */
-    public void printHelpAndExit(String errorFormat, Object... args) {
-        printHelpAndExitForAction(null /*verb*/, null /*directObject*/, errorFormat, args);
-    }
-
-    /**
-     * Prints the help/usage and exits.
-     *
-     * @param verb If null, displays help for all verbs. If not null, display help only
-     *          for that specific verb. In all cases also displays general usage and action list.
-     * @param directObject If null, displays help for all verb objects.
-     *          If not null, displays help only for that specific action
-     *          In all cases also display general usage and action list.
-     * @param errorFormat Optional error message to print prior to usage using String.format
-     * @param args Arguments for String.format
-     */
-    public void printHelpAndExitForAction(String verb, String directObject,
-            String errorFormat, Object... args) {
-        if (errorFormat != null) {
-            stderr(errorFormat, args);
-        }
-
-        /*
-         * usage should fit in 80 columns
-         *   12345678901234567890123456789012345678901234567890123456789012345678901234567890
-         */
-        stdout("\n" +
-            "Usage:\n" +
-            "  android [global options] action [action options]\n" +
-            "\n" +
-            "Global options:");
-        listOptions(GLOBAL_FLAG_VERB, NO_VERB_OBJECT);
-
-        if (verb == null || directObject == null) {
-            stdout("\nValid actions are composed of a verb and an optional direct object:");
-            for (String[] action : mActions) {
-
-                stdout("- %1$6s %2$-12s: %3$s",
-                        action[ACTION_VERB_INDEX],
-                        action[ACTION_OBJECT_INDEX],
-                        action[ACTION_DESC_INDEX]);
-            }
-        }
-
-        for (String[] action : mActions) {
-            if (verb == null || verb.equals(action[ACTION_VERB_INDEX])) {
-                if (directObject == null || directObject.equals(action[ACTION_OBJECT_INDEX])) {
-                    stdout("\nAction \"%1$s %2$s\":",
-                            action[ACTION_VERB_INDEX],
-                            action[ACTION_OBJECT_INDEX]);
-                    stdout("  %1$s", action[ACTION_DESC_INDEX]);
-                    stdout("Options:");
-                    listOptions(action[ACTION_VERB_INDEX], action[ACTION_OBJECT_INDEX]);
-                }
-            }
-        }
-
-        exit();
-    }
-
-    /**
-     * Internal helper to print all the option flags for a given action name.
-     */
-    protected void listOptions(String verb, String directObject) {
-        int numOptions = 0;
-        for (Entry<String, Arg> entry : mArguments.entrySet()) {
-            Arg arg = entry.getValue();
-            if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) {
-
-                String value = "";
-                String required = "";
-                if (arg.isMandatory()) {
-                    required = " [required]";
-
-                } else {
-                    if (arg.getDefaultValue() instanceof String[]) {
-                        for (String v : (String[]) arg.getDefaultValue()) {
-                            if (value.length() > 0) {
-                                value += ", ";
-                            }
-                            value += v;
-                        }
-                    } else if (arg.getDefaultValue() != null) {
-                        Object v = arg.getDefaultValue();
-                        if (arg.getMode() != Mode.BOOLEAN || v.equals(Boolean.TRUE)) {
-                            value = v.toString();
-                        }
-                    }
-                    if (value.length() > 0) {
-                        value = " [Default: " + value + "]";
-                    }
-                }
-
-                stdout("  -%1$s %2$-10s %3$s%4$s%5$s",
-                        arg.getShortArg(),
-                        "--" + arg.getLongArg(),
-                        arg.getDescription(),
-                        value,
-                        required);
-                numOptions++;
-            }
-        }
-
-        if (numOptions == 0) {
-            stdout("  No options");
-        }
-    }
-
-    //----
-
-    /**
-     * The mode of an argument specifies the type of variable it represents,
-     * whether an extra parameter is required after the flag and how to parse it.
-     */
-    static enum Mode {
-        /** Argument value is a Boolean. Default value is a Boolean. */
-        BOOLEAN {
-            @Override
-            public boolean needsExtra() {
-                return false;
-            }
-            @Override
-            public String process(Arg arg, String extra) {
-                // Toggle the current value
-                arg.setCurrentValue(! ((Boolean) arg.getCurrentValue()).booleanValue());
-                return null;
-            }
-        },
-
-        /** Argument value is an Integer. Default value is an Integer. */
-        INTEGER {
-            @Override
-            public boolean needsExtra() {
-                return true;
-            }
-            @Override
-            public String process(Arg arg, String extra) {
-                try {
-                    arg.setCurrentValue(Integer.parseInt(extra));
-                    return null;
-                } catch (NumberFormatException e) {
-                    return String.format("Failed to parse '%1$s' as an integer: %2%s",
-                            extra, e.getMessage());
-                }
-            }
-        },
-
-        /** Argument value is a String. Default value is a String[]. */
-        ENUM {
-            @Override
-            public boolean needsExtra() {
-                return true;
-            }
-            @Override
-            public String process(Arg arg, String extra) {
-                StringBuilder desc = new StringBuilder();
-                String[] values = (String[]) arg.getDefaultValue();
-                for (String value : values) {
-                    if (value.equals(extra)) {
-                        arg.setCurrentValue(extra);
-                        return null;
-                    }
-
-                    if (desc.length() != 0) {
-                        desc.append(", ");
-                    }
-                    desc.append(value);
-                }
-
-                return String.format("'%1$s' is not one of %2$s", extra, desc.toString());
-            }
-        },
-
-        /** Argument value is a String. Default value is a null. */
-        STRING {
-            @Override
-            public boolean needsExtra() {
-                return true;
-            }
-            @Override
-            public String process(Arg arg, String extra) {
-                arg.setCurrentValue(extra);
-                return null;
-            }
-        };
-
-        /**
-         * Returns true if this mode requires an extra parameter.
-         */
-        public abstract boolean needsExtra();
-
-        /**
-         * Processes the flag for this argument.
-         *
-         * @param arg The argument being processed.
-         * @param extra The extra parameter. Null if {@link #needsExtra()} returned false.
-         * @return An error string or null if there's no error.
-         */
-        public abstract String process(Arg arg, String extra);
-    }
-
-    /**
-     * An argument accepted by the command-line, also called "a flag".
-     * Arguments must have a short version (one letter), a long version name and a description.
-     * They can have a default value, or it can be null.
-     * Depending on the {@link Mode}, the default value can be a Boolean, an Integer, a String
-     * or a String array (in which case the first item is the current by default.)
-     */
-    static class Arg {
-        /** Verb for that argument. Never null. */
-        private final String mVerb;
-        /** Direct Object for that argument. Never null, but can be empty string. */
-        private final String mDirectObject;
-        /** The 1-letter short name of the argument, e.g. -v. */
-        private final String mShortName;
-        /** The long name of the argument, e.g. --verbose. */
-        private final String mLongName;
-        /** A description. Never null. */
-        private final String mDescription;
-        /** A default value. Can be null. */
-        private final Object mDefaultValue;
-        /** The argument mode (type + process method). Never null. */
-        private final Mode mMode;
-        /** True if this argument is mandatory for this verb/directobject. */
-        private final boolean mMandatory;
-        /** Current value. Initially set to the default value. */
-        private Object mCurrentValue;
-        /** True if the argument has been used on the command line. */
-        private boolean mInCommandLine;
-
-        /**
-         * Creates a new argument flag description.
-         *
-         * @param mode The {@link Mode} for the argument.
-         * @param mandatory True if this argument is mandatory for this action.
-         * @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
-         * @param shortName The one-letter short argument name. Cannot be empty nor null.
-         * @param longName The long argument name. Cannot be empty nor null.
-         * @param description The description. Cannot be null.
-         * @param defaultValue The default value (or values), which depends on the selected {@link Mode}.
-         */
-        public Arg(Mode mode,
-                   boolean mandatory,
-                   String verb,
-                   String directObject,
-                   String shortName,
-                   String longName,
-                   String description,
-                   Object defaultValue) {
-            mMode = mode;
-            mMandatory = mandatory;
-            mVerb = verb;
-            mDirectObject = directObject;
-            mShortName = shortName;
-            mLongName = longName;
-            mDescription = description;
-            mDefaultValue = defaultValue;
-            mInCommandLine = false;
-            if (defaultValue instanceof String[]) {
-                mCurrentValue = ((String[])defaultValue)[0];
-            } else {
-                mCurrentValue = mDefaultValue;
-            }
-        }
-
-        /** Return true if this argument is mandatory for this verb/directobject. */
-        public boolean isMandatory() {
-            return mMandatory;
-        }
-
-        /** Returns the 1-letter short name of the argument, e.g. -v. */
-        public String getShortArg() {
-            return mShortName;
-        }
-
-        /** Returns the long name of the argument, e.g. --verbose. */
-        public String getLongArg() {
-            return mLongName;
-        }
-
-        /** Returns the description. Never null. */
-        public String getDescription() {
-            return mDescription;
-        }
-
-        /** Returns the verb for that argument. Never null. */
-        public String getVerb() {
-            return mVerb;
-        }
-
-        /** Returns the direct Object for that argument. Never null, but can be empty string. */
-        public String getDirectObject() {
-            return mDirectObject;
-        }
-
-        /** Returns the default value. Can be null. */
-        public Object getDefaultValue() {
-            return mDefaultValue;
-        }
-
-        /** Returns the current value. Initially set to the default value. Can be null. */
-        public Object getCurrentValue() {
-            return mCurrentValue;
-        }
-
-        /** Sets the current value. Can be null. */
-        public void setCurrentValue(Object currentValue) {
-            mCurrentValue = currentValue;
-        }
-
-        /** Returns the argument mode (type + process method). Never null. */
-        public Mode getMode() {
-            return mMode;
-        }
-
-        /** Returns true if the argument has been used on the command line. */
-        public boolean isInCommandLine() {
-            return mInCommandLine;
-        }
-
-        /** Sets if the argument has been used on the command line. */
-        public void setInCommandLine(boolean inCommandLine) {
-            mInCommandLine = inCommandLine;
-        }
-    }
-
-    /**
-     * Internal helper to define a new argument for a give action.
-     *
-     * @param mode The {@link Mode} for the argument.
-     * @param verb The verb name. Can be #INTERNAL_VERB.
-     * @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
-     * @param shortName The one-letter short argument name. Cannot be empty nor null.
-     * @param longName The long argument name. Cannot be empty nor null.
-     * @param description The description. Cannot be null.
-     * @param defaultValue The default value (or values), which depends on the selected {@link Mode}.
-     */
-    protected void define(Mode mode,
-            boolean mandatory,
-            String verb,
-            String directObject,
-            String shortName, String longName,
-            String description, Object defaultValue) {
-        assert(!(mandatory && mode == Mode.BOOLEAN)); // a boolean mode cannot be mandatory
-
-        if (directObject == null) {
-            directObject = NO_VERB_OBJECT;
-        }
-
-        String key = verb + "/" + directObject + "/" + longName;
-        mArguments.put(key, new Arg(mode, mandatory,
-                verb, directObject, shortName, longName, description, defaultValue));
-    }
-
-    /**
-     * Exits in case of error.
-     * This is protected so that it can be overridden in unit tests.
-     */
-    protected void exit() {
-        System.exit(1);
-    }
-
-    /**
-     * Prints a line to stdout.
-     * This is protected so that it can be overridden in unit tests.
-     *
-     * @param format The string to be formatted. Cannot be null.
-     * @param args Format arguments.
-     */
-    protected void stdout(String format, Object...args) {
-        mLog.printf(format + "\n", args);
-    }
-
-    /**
-     * Prints a line to stderr.
-     * This is protected so that it can be overridden in unit tests.
-     *
-     * @param format The string to be formatted. Cannot be null.
-     * @param args Format arguments.
-     */
-    protected void stderr(String format, Object...args) {
-        mLog.error(null, format, args);
-    }
-}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
deleted file mode 100644
index 55d4357..0000000
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ /dev/null
@@ -1,1189 +0,0 @@
-/*
- * 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.android.sdkmanager;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.avd.HardwareProperties;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty;
-import com.android.sdklib.internal.project.ProjectCreator;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.internal.project.ProjectCreator.OutputLevel;
-import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
-import com.android.sdklib.xml.AndroidXPathFactory;
-import com.android.sdkmanager.internal.repository.AboutPage;
-import com.android.sdkmanager.internal.repository.SettingsPage;
-import com.android.sdkuilib.internal.repository.LocalPackagesPage;
-import com.android.sdkuilib.repository.UpdaterWindow;
-
-import org.xml.sax.InputSource;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Main class for the 'android' application.
- */
-public class Main {
-
-    /** Java property that defines the location of the sdk/tools directory. */
-    public final static String TOOLSDIR = "com.android.sdkmanager.toolsdir";
-    /** Java property that defines the working directory. On Windows the current working directory
-     *  is actually the tools dir, in which case this is used to get the original CWD. */
-    private final static String WORKDIR = "com.android.sdkmanager.workdir";
-
-    /** Value returned by {@link #resolveTargetName(String)} when the target id does not match. */
-    private final static int INVALID_TARGET_ID = 0;
-
-    private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
-    private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
-
-    /** Path to the SDK folder. This is the parent of {@link #TOOLSDIR}. */
-    private String mOsSdkFolder;
-    /** Logger object. Use this to print normal output, warnings or errors. */
-    private ISdkLog mSdkLog;
-    /** The SDK manager parses the SDK folder and gives access to the content. */
-    private SdkManager mSdkManager;
-    /** Command-line processor with options specific to SdkManager. */
-    private SdkCommandLine mSdkCommandLine;
-    /** The working directory, either null or set to an existing absolute canonical directory. */
-    private File mWorkDir;
-
-    public static void main(String[] args) {
-        new Main().run(args);
-    }
-
-    /**
-     * Runs the sdk manager app
-     */
-    private void run(String[] args) {
-        createLogger();
-        init();
-        mSdkCommandLine.parseArgs(args);
-        parseSdk();
-        doAction();
-    }
-
-    /**
-     * Creates the {@link #mSdkLog} object.
-     * <p/>
-     * This must be done before {@link #init()} as it will be used to report errors.
-     */
-    private void createLogger() {
-        mSdkLog = new ISdkLog() {
-            public void error(Throwable t, String errorFormat, Object... args) {
-                if (errorFormat != null) {
-                    System.err.printf("Error: " + errorFormat, args);
-                    if (!errorFormat.endsWith("\n")) {
-                        System.err.printf("\n");
-                    }
-                }
-                if (t != null) {
-                    System.err.printf("Error: %s\n", t.getMessage());
-                }
-            }
-
-            public void warning(String warningFormat, Object... args) {
-                if (mSdkCommandLine.isVerbose()) {
-                    System.out.printf("Warning: " + warningFormat, args);
-                    if (!warningFormat.endsWith("\n")) {
-                        System.out.printf("\n");
-                    }
-                }
-            }
-
-            public void printf(String msgFormat, Object... args) {
-                System.out.printf(msgFormat, args);
-            }
-        };
-    }
-
-    /**
-     * Init the application by making sure the SDK path is available and
-     * doing basic parsing of the SDK.
-     */
-    private void init() {
-        mSdkCommandLine = new SdkCommandLine(mSdkLog);
-
-        // We get passed a property for the tools dir
-        String toolsDirProp = System.getProperty(TOOLSDIR);
-        if (toolsDirProp == null) {
-            // for debugging, it's easier to override using the process environment
-            toolsDirProp = System.getenv(TOOLSDIR);
-        }
-
-        if (toolsDirProp != null) {
-            // got back a level for the SDK folder
-            File tools;
-            if (toolsDirProp.length() > 0) {
-                tools = new File(toolsDirProp);
-                mOsSdkFolder = tools.getParent();
-            } else {
-                try {
-                    tools = new File(".").getCanonicalFile();
-                    mOsSdkFolder = tools.getParent();
-                } catch (IOException e) {
-                    // Will print an error below since mSdkFolder is not defined
-                }
-            }
-        }
-
-        if (mOsSdkFolder == null) {
-            errorAndExit("The tools directory property is not set, please make sure you are executing %1$s",
-                SdkConstants.androidCmdName());
-        }
-
-        // We might get passed a property for the working directory
-        // Either it is a valid directory and mWorkDir is set to it's absolute canonical value
-        // or mWorkDir remains null.
-        String workDirProp = System.getProperty(WORKDIR);
-        if (workDirProp == null) {
-            workDirProp = System.getenv(WORKDIR);
-        }
-        if (workDirProp != null) {
-            // This should be a valid directory
-            mWorkDir = new File(workDirProp);
-            try {
-                mWorkDir = mWorkDir.getCanonicalFile().getAbsoluteFile();
-            } catch (IOException e) {
-                mWorkDir = null;
-            }
-            if (mWorkDir == null || !mWorkDir.isDirectory()) {
-                errorAndExit("The working directory does not seem to be valid: '%1$s", workDirProp);
-            }
-        }
-    }
-
-    /**
-     * Does the basic SDK parsing required for all actions
-     */
-    private void parseSdk() {
-        mSdkManager = SdkManager.createManager(mOsSdkFolder, mSdkLog);
-
-        if (mSdkManager == null) {
-            errorAndExit("Unable to parse SDK content.");
-        }
-    }
-
-    /**
-     * Actually do an action...
-     */
-    private void doAction() {
-        String verb = mSdkCommandLine.getVerb();
-        String directObject = mSdkCommandLine.getDirectObject();
-
-        if (SdkCommandLine.VERB_LIST.equals(verb)) {
-            // list action.
-            if (SdkCommandLine.OBJECT_TARGET.equals(directObject)) {
-                displayTargetList();
-            } else if (SdkCommandLine.OBJECT_AVD.equals(directObject)) {
-                displayAvdList();
-            } else {
-                displayTargetList();
-                displayAvdList();
-            }
-
-        } else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
-                SdkCommandLine.OBJECT_AVD.equals(directObject)) {
-            createAvd();
-
-        } else if (SdkCommandLine.VERB_DELETE.equals(verb) &&
-                SdkCommandLine.OBJECT_AVD.equals(directObject)) {
-            deleteAvd();
-
-        } else if (SdkCommandLine.VERB_MOVE.equals(verb) &&
-                SdkCommandLine.OBJECT_AVD.equals(directObject)) {
-            moveAvd();
-
-        } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
-                SdkCommandLine.OBJECT_AVD.equals(directObject)) {
-            updateAvd();
-
-        } else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
-                SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
-            createProject();
-
-        } else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
-                SdkCommandLine.OBJECT_TEST_PROJECT.equals(directObject)) {
-            createTestProject();
-
-        } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
-                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(false /*autoUpdate*/);
-
-        } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
-                SdkCommandLine.OBJECT_SDK.equals(directObject)) {
-            showMainWindow(true /*autoUpdate*/);
-
-        } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
-                SdkCommandLine.OBJECT_ADB.equals(directObject)) {
-            updateAdb();
-
-        } else {
-            mSdkCommandLine.printHelpAndExit(null);
-        }
-    }
-
-    /**
-     * Display the main SdkManager app window
-     */
-    private void showMainWindow(boolean autoUpdate) {
-        try {
-            // display a message talking about the command line version
-            System.out.printf("No command line parameters provided, launching UI.\n" +
-                    "See 'android --help' for operations from the command line.\n");
-            UpdaterWindow window = new UpdaterWindow(
-                    null /* parentShell */,
-                    mSdkLog,
-                    mOsSdkFolder,
-                    false /*userCanChangeSdkRoot*/);
-            window.registerPage("Settings", SettingsPage.class);
-            window.registerPage("About", AboutPage.class);
-            if (autoUpdate) {
-                window.setInitialPage(LocalPackagesPage.class);
-                window.setRequestAutoUpdate(true);
-            }
-            window.open();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Creates a new Android project based on command-line parameters
-     */
-    private void createProject() {
-        // get the target and try to resolve it.
-        int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
-        IAndroidTarget[] targets = mSdkManager.getTargets();
-        if (targetId == INVALID_TARGET_ID || targetId > targets.length) {
-            errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
-                    SdkConstants.androidCmdName());
-        }
-        IAndroidTarget target = targets[targetId - 1];  // target id is 1-based
-
-        ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
-                mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
-                    mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
-                        OutputLevel.NORMAL,
-                mSdkLog);
-
-        String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
-
-        String projectName = mSdkCommandLine.getParamName();
-        String packageName = mSdkCommandLine.getParamProjectPackage();
-        String activityName = mSdkCommandLine.getParamProjectActivity();
-
-        if (projectName != null &&
-                !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
-            errorAndExit(
-                "Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
-                projectName, ProjectCreator.CHARS_PROJECT_NAME);
-            return;
-        }
-
-        if (activityName != null &&
-                !ProjectCreator.RE_ACTIVITY_NAME.matcher(activityName).matches()) {
-            errorAndExit(
-                "Activity name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
-                activityName, ProjectCreator.CHARS_ACTIVITY_NAME);
-            return;
-        }
-
-        if (packageName != null &&
-                !ProjectCreator.RE_PACKAGE_NAME.matcher(packageName).matches()) {
-            errorAndExit(
-                "Package name '%1$s' contains invalid characters.\n" +
-                "A package name must be constitued of two Java identifiers.\n" +
-                "Each identifier allowed characters are: %2$s",
-                packageName, ProjectCreator.CHARS_PACKAGE_NAME);
-            return;
-        }
-
-        creator.createProject(projectDir,
-                projectName,
-                packageName,
-                activityName,
-                target,
-                null /*pathToMain*/);
-    }
-
-    /**
-     * Creates a new Android test project based on command-line parameters
-     */
-    private void createTestProject() {
-
-        String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
-
-        // first check the path of the parent project, and make sure it's valid.
-        String pathToMainProject = mSdkCommandLine.getParamTestProjectMain();
-
-        File parentProject = new File(pathToMainProject);
-        if (parentProject.isAbsolute() == false) {
-            // if the path is not absolute, we need to resolve it based on the
-            // destination path of the project
-            try {
-                parentProject = new File(projectDir, pathToMainProject).getCanonicalFile();
-            } catch (IOException e) {
-                errorAndExit("Unable to resolve Main project's directory: %1$s",
-                        pathToMainProject);
-                return; // help Eclipse static analyzer understand we'll never execute the rest.
-            }
-        }
-
-        if (parentProject.isDirectory() == false) {
-            errorAndExit("Main project's directory does not exist: %1$s",
-                    pathToMainProject);
-            return;
-        }
-
-        // now look for a manifest in there
-        File manifest = new File(parentProject, SdkConstants.FN_ANDROID_MANIFEST_XML);
-        if (manifest.isFile() == false) {
-            errorAndExit("No AndroidManifest.xml file found in the main project directory: %1$s",
-                    parentProject.getAbsolutePath());
-            return;
-        }
-
-        // now query the manifest for the package file.
-        XPath xpath = AndroidXPathFactory.newXPath();
-        String packageName, activityName;
-
-        try {
-            packageName = xpath.evaluate("/manifest/@package",
-                    new InputSource(new FileInputStream(manifest)));
-
-            mSdkLog.printf("Found main project package: %1$s\n", packageName);
-
-            // now get the name of the first activity we find
-            activityName = xpath.evaluate("/manifest/application/activity[1]/@android:name",
-                    new InputSource(new FileInputStream(manifest)));
-            // xpath will return empty string when there's no match
-            if (activityName == null || activityName.length() == 0) {
-                activityName = null;
-            } else {
-                mSdkLog.printf("Found main project activity: %1$s\n", activityName);
-            }
-        } catch (FileNotFoundException e) {
-            // this shouldn't happen as we test it above.
-            errorAndExit("No AndroidManifest.xml file found in main project.");
-            return; // this is not strictly needed because errorAndExit will stop the execution,
-            // but this makes the java compiler happy, wrt to uninitialized variables.
-        } catch (XPathExpressionException e) {
-            // looks like the main manifest is not valid.
-            errorAndExit("Unable to parse main project manifest to get information.");
-            return; // this is not strictly needed because errorAndExit will stop the execution,
-                    // but this makes the java compiler happy, wrt to uninitialized variables.
-        }
-
-        // now get the target hash
-        ProjectProperties p = ProjectProperties.load(parentProject.getAbsolutePath(),
-                PropertyType.DEFAULT);
-        String targetHash = p.getProperty(ProjectProperties.PROPERTY_TARGET);
-        if (targetHash == null) {
-            errorAndExit("Couldn't find the main project target");
-            return;
-        }
-
-        // and resolve it.
-        IAndroidTarget target = mSdkManager.getTargetFromHashString(targetHash);
-        if (target == null) {
-            errorAndExit(
-                    "Unable to resolve main project target '%1$s'. You may want to install the platform in your SDK.",
-                    targetHash);
-            return;
-        }
-
-        mSdkLog.printf("Found main project target: %1$s\n", target.getFullName());
-
-        ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
-                mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
-                    mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
-                        OutputLevel.NORMAL,
-                mSdkLog);
-
-        String projectName = mSdkCommandLine.getParamName();
-
-        if (projectName != null &&
-                !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
-            errorAndExit(
-                "Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
-                projectName, ProjectCreator.CHARS_PROJECT_NAME);
-            return;
-        }
-
-        creator.createProject(projectDir,
-                projectName,
-                packageName,
-                activityName,
-                target,
-                pathToMainProject);
-    }
-
-
-    /**
-     * Updates an existing Android project based on command-line parameters
-     */
-    private void updateProject() {
-        // get the target and try to resolve it.
-        IAndroidTarget target = null;
-        String targetStr = mSdkCommandLine.getParamTargetId();
-        // For "update project" the target parameter is optional so having null is acceptable.
-        // However if there's a value, it must be valid.
-        if (targetStr != null) {
-            IAndroidTarget[] targets = mSdkManager.getTargets();
-            int targetId = resolveTargetName(targetStr);
-            if (targetId == INVALID_TARGET_ID || targetId > targets.length) {
-                errorAndExit("Target id '%1$s' is not valid. Use '%2$s list targets' to get the target ids.",
-                        targetStr,
-                        SdkConstants.androidCmdName());
-            }
-            target = targets[targetId - 1];  // target id is 1-based
-        }
-
-        ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
-                mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
-                    mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
-                        OutputLevel.NORMAL,
-                mSdkLog);
-
-        String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
-
-        creator.updateProject(projectDir,
-                target,
-                mSdkCommandLine.getParamName());
-
-        boolean doSubProjects = mSdkCommandLine.getParamSubProject();
-        boolean couldHaveDone = false;
-
-        // If there are any sub-folders with a manifest, try to update them as projects
-        // too. This will take care of updating any underlying test project even if the
-        // user changed the folder name.
-        File[] files = new File(projectDir).listFiles();
-        if (files != null) {
-            for (File dir : files) {
-                if (dir.isDirectory() &&
-                        new File(dir, SdkConstants.FN_ANDROID_MANIFEST_XML).isFile()) {
-                    if (doSubProjects) {
-                        creator.updateProject(dir.getPath(),
-                                target,
-                                mSdkCommandLine.getParamName());
-                    } else {
-                        couldHaveDone = true;
-                    }
-                }
-            }
-        }
-
-        if (couldHaveDone) {
-            mSdkLog.printf("It seems that there are sub-projects. If you want to update them\nplease use the --%1$s parameter.",
-                    SdkCommandLine.KEY_SUBPROJECTS);
-        }
-    }
-
-    /**
-     * 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.
-     *
-     * @return The project absolute path relative to {@link #mWorkDir} or the original
-     *         newProjectLocation otherwise.
-     */
-    private String getProjectLocation(String newProjectLocation) {
-
-        // If the new project location is absolute, use it as-is
-        File projectDir = new File(newProjectLocation);
-        if (projectDir.isAbsolute()) {
-            return newProjectLocation;
-        }
-
-        // if there's no working directory, just use the project location as-is.
-        if (mWorkDir == null) {
-            return newProjectLocation;
-        }
-
-        // Combine then and get an absolute canonical directory
-        try {
-            projectDir = new File(mWorkDir, newProjectLocation).getCanonicalFile();
-
-            return projectDir.getPath();
-        } catch (IOException e) {
-            errorAndExit("Failed to combine working directory '%1$s' with project location '%2$s': %3$s",
-                    mWorkDir.getPath(),
-                    newProjectLocation,
-                    e.getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * Displays the list of available Targets (Platforms and Add-ons)
-     */
-    private void displayTargetList() {
-        mSdkLog.printf("Available Android targets:\n");
-
-        int index = 1;
-        for (IAndroidTarget target : mSdkManager.getTargets()) {
-            mSdkLog.printf("id: %1$d or \"%2$s\"\n", index, target.hashString());
-            mSdkLog.printf("     Name: %s\n", target.getName());
-            if (target.isPlatform()) {
-                mSdkLog.printf("     Type: Platform\n");
-                mSdkLog.printf("     API level: %s\n", target.getVersion().getApiString());
-                mSdkLog.printf("     Revision: %d\n", target.getRevision());
-            } else {
-                mSdkLog.printf("     Type: Add-On\n");
-                mSdkLog.printf("     Vendor: %s\n", target.getVendor());
-                mSdkLog.printf("     Revision: %d\n", target.getRevision());
-                if (target.getDescription() != null) {
-                    mSdkLog.printf("     Description: %s\n", target.getDescription());
-                }
-                mSdkLog.printf("     Based on Android %s (API level %s)\n",
-                        target.getVersionName(), target.getVersion().getApiString());
-
-                // display the optional libraries.
-                IOptionalLibrary[] libraries = target.getOptionalLibraries();
-                if (libraries != null) {
-                    mSdkLog.printf("     Libraries:\n");
-                    for (IOptionalLibrary library : libraries) {
-                        mSdkLog.printf("      * %1$s (%2$s)\n",
-                                library.getName(), library.getJarName());
-                        mSdkLog.printf(String.format(
-                                "          %1$s\n", library.getDescription()));
-                    }
-                }
-            }
-
-            // get the target skins
-            displaySkinList(target, "     Skins: ");
-
-            if (target.getUsbVendorId() != IAndroidTarget.NO_USB_ID) {
-                mSdkLog.printf("     Adds USB support for devices (Vendor: 0x%04X)\n",
-                        target.getUsbVendorId());
-            }
-
-            index++;
-        }
-    }
-
-    /**
-     * Displays the skins valid for the given target.
-     */
-    private void displaySkinList(IAndroidTarget target, String message) {
-        String[] skins = target.getSkins();
-        String defaultSkin = target.getDefaultSkin();
-        mSdkLog.printf(message);
-        if (skins != null) {
-            boolean first = true;
-            for (String skin : skins) {
-                if (first == false) {
-                    mSdkLog.printf(", ");
-                } else {
-                    first = false;
-                }
-                mSdkLog.printf(skin);
-
-                if (skin.equals(defaultSkin)) {
-                    mSdkLog.printf(" (default)");
-                }
-            }
-            mSdkLog.printf("\n");
-        } else {
-            mSdkLog.printf("no skins.\n");
-        }
-    }
-
-    /**
-     * Displays the list of available AVDs.
-     */
-    private void displayAvdList() {
-        try {
-            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
-
-            mSdkLog.printf("Available Android Virtual Devices:\n");
-
-            AvdInfo[] avds = avdManager.getValidAvds();
-            for (int index = 0 ; index < avds.length ; index++) {
-                AvdInfo info = avds[index];
-                if (index > 0) {
-                    mSdkLog.printf("---------\n");
-                }
-                mSdkLog.printf("    Name: %s\n", info.getName());
-                mSdkLog.printf("    Path: %s\n", info.getPath());
-
-                // get the target of the AVD
-                IAndroidTarget target = info.getTarget();
-                if (target.isPlatform()) {
-                    mSdkLog.printf("  Target: %s (API level %s)\n", target.getName(),
-                            target.getVersion().getApiString());
-                } else {
-                    mSdkLog.printf("  Target: %s (%s)\n", target.getName(), target
-                            .getVendor());
-                    mSdkLog.printf("          Based on Android %s (API level %s)\n",
-                            target.getVersionName(), target.getVersion().getApiString());
-                }
-
-                // display some extra values.
-                Map<String, String> properties = info.getProperties();
-                if (properties != null) {
-                    String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME);
-                    if (skin != null) {
-                        mSdkLog.printf("    Skin: %s\n", skin);
-                    }
-                    String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE);
-                    if (sdcard == null) {
-                        sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
-                    }
-                    if (sdcard != null) {
-                        mSdkLog.printf("  Sdcard: %s\n", sdcard);
-                    }
-                }
-            }
-
-            // Are there some unused AVDs?
-            AvdInfo[] badAvds = avdManager.getBrokenAvds();
-
-            if (badAvds.length == 0) {
-                return;
-            }
-
-            mSdkLog.printf("\nThe following Android Virtual Devices could not be loaded:\n");
-            boolean needSeparator = false;
-            for (AvdInfo info : badAvds) {
-                if (needSeparator) {
-                    mSdkLog.printf("---------\n");
-                }
-                mSdkLog.printf("    Name: %s\n", info.getName() == null ? "--" : info.getName());
-                mSdkLog.printf("    Path: %s\n", info.getPath() == null ? "--" : info.getPath());
-
-                String error = info.getErrorMessage();
-                mSdkLog.printf("   Error: %s\n", error == null ? "Uknown error" : error);
-                needSeparator = true;
-            }
-        } catch (AndroidLocationException e) {
-            errorAndExit(e.getMessage());
-        }
-    }
-
-    /**
-     * Creates a new AVD. This is a text based creation with command line prompt.
-     */
-    private void createAvd() {
-        // find a matching target
-        int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
-        IAndroidTarget[] targets = mSdkManager.getTargets();
-
-        if (targetId == INVALID_TARGET_ID || targetId > targets.length) {
-            errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
-                    SdkConstants.androidCmdName());
-        }
-
-        IAndroidTarget target = targets[targetId-1]; // target id is 1-based
-
-        try {
-            boolean removePrevious = mSdkCommandLine.getFlagForce();
-            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
-
-            String avdName = mSdkCommandLine.getParamName();
-
-            if (!AvdManager.RE_AVD_NAME.matcher(avdName).matches()) {
-                errorAndExit(
-                    "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
-                    avdName, AvdManager.CHARS_AVD_NAME);
-                return;
-            }
-
-            AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/);
-            if (info != null) {
-                if (removePrevious) {
-                    mSdkLog.warning(
-                            "Android Virtual Device '%s' already exists and will be replaced.",
-                            avdName);
-                } else {
-                    errorAndExit("Android Virtual Device '%s' already exists.\n" +
-                                 "Use --force if you want to replace it.",
-                                 avdName);
-                    return;
-                }
-            }
-
-            String paramFolderPath = mSdkCommandLine.getParamLocationPath();
-            File avdFolder = null;
-            if (paramFolderPath != null) {
-                avdFolder = new File(paramFolderPath);
-            } else {
-                avdFolder = new File(AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
-                        avdName + AvdManager.AVD_FOLDER_EXTENSION);
-            }
-
-            // Validate skin is either default (empty) or NNNxMMM or a valid skin name.
-            Map<String, String> skinHardwareConfig = null;
-            String skin = mSdkCommandLine.getParamSkin();
-            if (skin != null && skin.length() == 0) {
-                skin = null;
-            }
-
-            if (skin != null && target != null) {
-                boolean valid = false;
-                // Is it a know skin name for this target?
-                for (String s : target.getSkins()) {
-                    if (skin.equalsIgnoreCase(s)) {
-                        skin = s;  // Make skin names case-insensitive.
-                        valid = true;
-
-                        // get the hardware properties for this skin
-                        File skinFolder = avdManager.getSkinPath(skin, target);
-                        File skinHardwareFile = new File(skinFolder, AvdManager.HARDWARE_INI);
-                        if (skinHardwareFile.isFile()) {
-                            skinHardwareConfig = SdkManager.parsePropertyFile(
-                                    skinHardwareFile, mSdkLog);
-                        }
-                        break;
-                    }
-                }
-
-                // Is it NNNxMMM?
-                if (!valid) {
-                    valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches();
-                }
-
-                if (!valid) {
-                    displaySkinList(target, "Valid skins: ");
-                    errorAndExit("'%s' is not a valid skin name or size (NNNxMMM)", skin);
-                    return;
-                }
-            }
-
-            Map<String, String> hardwareConfig = null;
-            if (target != null && target.isPlatform()) {
-                try {
-                    hardwareConfig = promptForHardware(target, skinHardwareConfig);
-                } catch (IOException e) {
-                    errorAndExit(e.getMessage());
-                }
-            }
-
-            @SuppressWarnings("unused") // oldAvdInfo is never read, yet useful for debugging
-            AvdInfo oldAvdInfo = null;
-            if (removePrevious) {
-                oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/);
-            }
-
-            @SuppressWarnings("unused") // newAvdInfo is never read, yet useful for debugging
-            AvdInfo newAvdInfo = avdManager.createAvd(avdFolder,
-                    avdName,
-                    target,
-                    skin,
-                    mSdkCommandLine.getParamSdCard(),
-                    hardwareConfig,
-                    removePrevious,
-                    mSdkLog);
-
-        } catch (AndroidLocationException e) {
-            errorAndExit(e.getMessage());
-        }
-    }
-
-    /**
-     * Delete an AVD. If the AVD name is not part of the available ones look for an
-     * invalid AVD (one not loaded due to some error) to remove it too.
-     */
-    private void deleteAvd() {
-        try {
-            String avdName = mSdkCommandLine.getParamName();
-            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
-            AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/);
-
-            if (info == null) {
-                errorAndExit("There is no Android Virtual Device named '%s'.", avdName);
-                return;
-            }
-
-            avdManager.deleteAvd(info, mSdkLog);
-        } catch (AndroidLocationException e) {
-            errorAndExit(e.getMessage());
-        }
-    }
-
-    /**
-     * Moves an AVD.
-     */
-    private void moveAvd() {
-        try {
-            String avdName = mSdkCommandLine.getParamName();
-            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
-            AvdInfo info = avdManager.getAvd(avdName, true /*validAvdOnly*/);
-
-            if (info == null) {
-                errorAndExit("There is no valid Android Virtual Device named '%s'.", avdName);
-                return;
-            }
-
-            // This is a rename if there's a new name for the AVD
-            String newName = mSdkCommandLine.getParamMoveNewName();
-            if (newName != null && newName.equals(info.getName())) {
-                // same name, not actually a rename operation
-                newName = null;
-            }
-
-            // This is a move (of the data files) if there's a new location path
-            String paramFolderPath = mSdkCommandLine.getParamLocationPath();
-            if (paramFolderPath != null) {
-                // check if paths are the same. Use File methods to account for OS idiosyncrasies.
-                try {
-                    File f1 = new File(paramFolderPath).getCanonicalFile();
-                    File f2 = new File(info.getPath()).getCanonicalFile();
-                    if (f1.equals(f2)) {
-                        // same canonical path, so not actually a move
-                        paramFolderPath = null;
-                    }
-                } catch (IOException e) {
-                    // Fail to resolve canonical path. Fail now since a move operation might fail
-                    // later and be harder to recover from.
-                    errorAndExit(e.getMessage());
-                    return;
-                }
-            }
-
-            if (newName == null && paramFolderPath == null) {
-                mSdkLog.warning("Move operation aborted: same AVD name, same canonical data path");
-                return;
-            }
-
-            // If a rename was requested and no data move was requested, check if the original
-            // data path is our default constructed from the AVD name. In this case we still want
-            // to rename that folder too.
-            if (newName != null && paramFolderPath == null) {
-                // Compute the original data path
-                File originalFolder = new File(
-                        AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
-                        info.getName() + AvdManager.AVD_FOLDER_EXTENSION);
-                if (originalFolder.equals(info.getPath())) {
-                    try {
-                        // The AVD is using the default data folder path based on the AVD name.
-                        // That folder needs to be adjusted to use the new name.
-                        File f = new File(AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
-                                     newName + AvdManager.AVD_FOLDER_EXTENSION);
-                        paramFolderPath = f.getCanonicalPath();
-                    } catch (IOException e) {
-                        // Fail to resolve canonical path. Fail now rather than later.
-                        errorAndExit(e.getMessage());
-                    }
-                }
-            }
-
-            // Check for conflicts
-            if (newName != null) {
-                if (avdManager.getAvd(newName, false /*validAvdOnly*/) != null) {
-                    errorAndExit("There is already an AVD named '%s'.", newName);
-                    return;
-                }
-
-                File ini = info.getIniFile();
-                if (ini.equals(AvdInfo.getIniFile(newName))) {
-                    errorAndExit("The AVD file '%s' is in the way.", ini.getCanonicalPath());
-                    return;
-                }
-            }
-
-            if (paramFolderPath != null && new File(paramFolderPath).exists()) {
-                errorAndExit(
-                        "There is already a file or directory at '%s'.\nUse --path to specify a different data folder.",
-                        paramFolderPath);
-            }
-
-            avdManager.moveAvd(info, newName, paramFolderPath, mSdkLog);
-        } catch (AndroidLocationException e) {
-            errorAndExit(e.getMessage());
-        } catch (IOException e) {
-            errorAndExit(e.getMessage());
-        }
-    }
-
-    /**
-     * Updates a broken AVD.
-     */
-    private void updateAvd() {
-        try {
-            String avdName = mSdkCommandLine.getParamName();
-            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
-            avdManager.updateAvd(avdName, mSdkLog);
-        } catch (AndroidLocationException e) {
-            errorAndExit(e.getMessage());
-        } catch (IOException e) {
-            errorAndExit(e.getMessage());
-        }
-    }
-
-    /**
-     * Updates adb with the USB devices declared in the SDK add-ons.
-     */
-    private void updateAdb() {
-        try {
-            mSdkManager.updateAdb();
-
-            mSdkLog.printf(
-                    "adb has been updated. You must restart adb with the following commands\n" +
-                    "\tadb kill-server\n" +
-                    "\tadb start-server\n");
-        } catch (AndroidLocationException e) {
-            errorAndExit(e.getMessage());
-        } catch (IOException e) {
-            errorAndExit(e.getMessage());
-        }
-    }
-
-    /**
-     * Prompts the user to setup a hardware config for a Platform-based AVD.
-     * @throws IOException
-     */
-    private Map<String, String> promptForHardware(IAndroidTarget createTarget,
-            Map<String, String> skinHardwareConfig) throws IOException {
-        byte[] readLineBuffer = new byte[256];
-        String result;
-        String defaultAnswer = "no";
-
-        mSdkLog.printf("%s is a basic Android platform.\n", createTarget.getName());
-        mSdkLog.printf("Do you wish to create a custom hardware profile [%s]",
-                defaultAnswer);
-
-        result = readLine(readLineBuffer).trim();
-        // handle default:
-        if (result.length() == 0) {
-            result = defaultAnswer;
-        }
-
-        if (getBooleanReply(result) == false) {
-            // no custom config, return the skin hardware config in case there is one.
-            return skinHardwareConfig;
-        }
-
-        mSdkLog.printf("\n"); // empty line
-
-        // get the list of possible hardware properties
-        File hardwareDefs = new File (mOsSdkFolder + File.separator +
-                SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI);
-        Map<String, HardwareProperty> hwMap = HardwareProperties.parseHardwareDefinitions(
-                hardwareDefs, null /*sdkLog*/);
-
-        HashMap<String, String> map = new HashMap<String, String>();
-
-        // we just want to loop on the HardwareProperties
-        HardwareProperty[] hwProperties = hwMap.values().toArray(
-                new HardwareProperty[hwMap.size()]);
-        for (int i = 0 ; i < hwProperties.length ;) {
-            HardwareProperty property = hwProperties[i];
-
-            String description = property.getDescription();
-            if (description != null) {
-                mSdkLog.printf("%s: %s\n", property.getAbstract(), description);
-            } else {
-                mSdkLog.printf("%s\n", property.getAbstract());
-            }
-
-            String defaultValue = property.getDefault();
-            String defaultFromSkin = skinHardwareConfig != null ? skinHardwareConfig.get(
-                    property.getName()) : null;
-
-            if (defaultFromSkin != null) {
-                mSdkLog.printf("%s [%s (from skin)]:", property.getName(), defaultFromSkin);
-            } else if (defaultValue != null) {
-                mSdkLog.printf("%s [%s]:", property.getName(), defaultValue);
-            } else {
-                mSdkLog.printf("%s (%s):", property.getName(), property.getType());
-            }
-
-            result = readLine(readLineBuffer);
-            if (result.length() == 0) {
-                if (defaultFromSkin != null || defaultValue != null) {
-                    if (defaultFromSkin != null) {
-                        // we need to write this one in the AVD file
-                        map.put(property.getName(), defaultFromSkin);
-                    }
-
-                    mSdkLog.printf("\n"); // empty line
-                    i++; // go to the next property if we have a valid default value.
-                         // if there's no default, we'll redo this property
-                }
-                continue;
-            }
-
-            switch (property.getType()) {
-                case BOOLEAN:
-                    try {
-                        if (getBooleanReply(result)) {
-                            map.put(property.getName(), "yes");
-                            i++; // valid reply, move to next property
-                        } else {
-                            map.put(property.getName(), "no");
-                            i++; // valid reply, move to next property
-                        }
-                    } catch (IOException e) {
-                        // display error, and do not increment i to redo this property
-                        mSdkLog.printf("\n%s\n", e.getMessage());
-                    }
-                    break;
-                case INTEGER:
-                    try {
-                        Integer.parseInt(result);
-                        map.put(property.getName(), result);
-                        i++; // valid reply, move to next property
-                    } catch (NumberFormatException e) {
-                        // display error, and do not increment i to redo this property
-                        mSdkLog.printf("\n%s\n", e.getMessage());
-                    }
-                    break;
-                case DISKSIZE:
-                    // TODO check validity
-                    map.put(property.getName(), result);
-                    i++; // valid reply, move to next property
-                    break;
-            }
-
-            mSdkLog.printf("\n"); // empty line
-        }
-
-        return map;
-    }
-
-    /**
-     * Reads the line from the input stream.
-     * @param buffer
-     * @throws IOException
-     */
-    private String readLine(byte[] buffer) throws IOException {
-        int count = System.in.read(buffer);
-
-        // is the input longer than the buffer?
-        if (count == buffer.length && buffer[count-1] != 10) {
-            // create a new temp buffer
-            byte[] tempBuffer = new byte[256];
-
-            // and read the rest
-            String secondHalf = readLine(tempBuffer);
-
-            // return a concat of both
-            return new String(buffer, 0, count) + secondHalf;
-        }
-
-        // ignore end whitespace
-        while (count > 0 && (buffer[count-1] == '\r' || buffer[count-1] == '\n')) {
-            count--;
-        }
-
-        return new String(buffer, 0, count);
-    }
-
-    /**
-     * Returns the boolean value represented by the string.
-     * @throws IOException If the value is not a boolean string.
-     */
-    private boolean getBooleanReply(String reply) throws IOException {
-
-        for (String valid : BOOLEAN_YES_REPLIES) {
-            if (valid.equalsIgnoreCase(reply)) {
-                return true;
-            }
-        }
-
-        for (String valid : BOOLEAN_NO_REPLIES) {
-            if (valid.equalsIgnoreCase(reply)) {
-                return false;
-            }
-        }
-
-        throw new IOException(String.format("%s is not a valid reply", reply));
-    }
-
-    private void errorAndExit(String format, Object...args) {
-        mSdkLog.error(null, format, args);
-        System.exit(1);
-    }
-
-    /**
-     * Converts a symbolic target name (such as those accepted by --target on the command-line)
-     * to an internal target index id. A valid target name is either a numeric target id (> 0)
-     * or a target hash string.
-     * <p/>
-     * If the given target can't be mapped, {@link #INVALID_TARGET_ID} (0) is returned.
-     * It's up to the caller to output an error.
-     * <p/>
-     * On success, returns a value > 0.
-     */
-    private int resolveTargetName(String targetName) {
-
-        if (targetName == null) {
-            return INVALID_TARGET_ID;
-        }
-
-        targetName = targetName.trim();
-
-        // Case of an integer number
-        if (targetName.matches("[0-9]*")) {
-            try {
-                int n = Integer.parseInt(targetName);
-                return n < 1 ? INVALID_TARGET_ID : n;
-            } catch (NumberFormatException e) {
-                // Ignore. Should not happen.
-            }
-        }
-
-        // Let's try to find a platform or addon name.
-        IAndroidTarget[] targets = mSdkManager.getTargets();
-        for (int i = 0; i < targets.length; i++) {
-            if (targetName.equals(targets[i].hashString())) {
-                return i + 1;
-            }
-        }
-
-        return INVALID_TARGET_ID;
-    }
-}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
deleted file mode 100644
index 80ee5dd..0000000
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * 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.android.sdkmanager;
-
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkManager;
-
-
-/**
- * Specific command-line flags for the {@link SdkManager}.
- */
-class SdkCommandLine extends CommandLineProcessor {
-
-    /*
-     * Steps needed to add a new action:
-     * - Each action is defined as a "verb object" followed by parameters.
-     * - Either reuse a VERB_ constant or define a new one.
-     * - Either reuse an OBJECT_ constant or define a new one.
-     * - Add a new entry to mAction with a one-line help summary.
-     * - In the constructor, add a define() call for each parameter (either mandatory
-     *   or optional) for the given action.
-     */
-
-    public final static String VERB_LIST   = "list";
-    public final static String VERB_CREATE = "create";
-    public final static String VERB_MOVE   = "move";
-    public final static String VERB_DELETE = "delete";
-    public final static String VERB_UPDATE = "update";
-
-    public static final String OBJECT_SDK          = "sdk";
-    public static final String OBJECT_AVD          = "avd";
-    public static final String OBJECT_AVDS         = "avds";
-    public static final String OBJECT_TARGET       = "target";
-    public static final String OBJECT_TARGETS      = "targets";
-    public static final String OBJECT_PROJECT      = "project";
-    public static final String OBJECT_TEST_PROJECT = "test-project";
-    public static final String OBJECT_ADB          = "adb";
-
-    public static final String ARG_ALIAS        = "alias";
-    public static final String ARG_ACTIVITY     = "activity";
-
-    public static final String KEY_ACTIVITY     = ARG_ACTIVITY;
-    public static final String KEY_PACKAGE      = "package";
-    public static final String KEY_MODE         = "mode";
-    public static final String KEY_TARGET_ID    = OBJECT_TARGET;
-    public static final String KEY_NAME         = "name";
-    public static final String KEY_PATH         = "path";
-    public static final String KEY_FILTER       = "filter";
-    public static final String KEY_SKIN         = "skin";
-    public static final String KEY_SDCARD       = "sdcard";
-    public static final String KEY_FORCE        = "force";
-    public static final String KEY_RENAME       = "rename";
-    public static final String KEY_SUBPROJECTS  = "subprojects";
-    public static final String KEY_MAIN_PROJECT = "main";
-
-    /**
-     * Action definitions for SdkManager command line.
-     * <p/>
-     * This list serves two purposes: first it is used to know which verb/object
-     * actions are acceptable on the command-line; second it provides a summary
-     * for each action that is printed in the help.
-     * <p/>
-     * Each entry is a string array with:
-     * <ul>
-     * <li> the verb.
-     * <li> an object (use #NO_VERB_OBJECT if there's no object).
-     * <li> a description.
-     * <li> an alternate form for the object (e.g. plural).
-     * </ul>
-     */
-    private final static String[][] ACTIONS = {
-            { VERB_LIST, NO_VERB_OBJECT,
-                "Lists existing targets or virtual devices." },
-            { VERB_LIST, OBJECT_AVD,
-                "Lists existing Android Virtual Devices.",
-                OBJECT_AVDS },
-            { VERB_LIST, OBJECT_TARGET,
-                "Lists existing targets.",
-                OBJECT_TARGETS },
-
-            { VERB_CREATE, OBJECT_AVD,
-                "Creates a new Android Virtual Device." },
-            { VERB_MOVE, OBJECT_AVD,
-                "Moves or renames an Android Virtual Device." },
-            { VERB_DELETE, OBJECT_AVD,
-                "Deletes an Android Virtual Device." },
-            { VERB_UPDATE, OBJECT_AVD,
-                "Updates an Android Virtual Device to match the folders of a new SDK." },
-
-            { VERB_CREATE, OBJECT_PROJECT,
-                "Creates a new Android Project." },
-            { VERB_UPDATE, OBJECT_PROJECT,
-                "Updates an Android Project (must have an AndroidManifest.xml)." },
-
-            { VERB_CREATE, OBJECT_TEST_PROJECT,
-                "Creates a new Android Test Project." },
-            { VERB_UPDATE, OBJECT_TEST_PROJECT,
-                "Updates an Android Test Project (must have an AndroidManifest.xml)." },
-
-            { VERB_UPDATE, OBJECT_ADB,
-                "Updates adb to support the USB devices declared in the SDK add-ons." },
-
-            { VERB_UPDATE, OBJECT_SDK,
-                "Updates the SDK by suggesting new platforms to install if available." }
-        };
-
-    public SdkCommandLine(ISdkLog logger) {
-        super(logger, ACTIONS);
-
-        // The following defines the parameters of the actions defined in mAction.
-
-        // --- create avd ---
-
-        define(Mode.STRING, false,
-                VERB_CREATE, OBJECT_AVD, "p", KEY_PATH,
-                "Location path of the directory where the new AVD will be created", null);
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_AVD, "n", KEY_NAME,
-                "Name of the new AVD", null);
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_AVD, "t", KEY_TARGET_ID,
-                "Target id of the new AVD", null);
-        define(Mode.STRING, false,
-                VERB_CREATE, OBJECT_AVD, "s", KEY_SKIN,
-                "Skin of the new AVD", null);
-        define(Mode.STRING, false,
-                VERB_CREATE, OBJECT_AVD, "c", KEY_SDCARD,
-                "Path to a shared SD card image, or size of a new sdcard for the new AVD", null);
-        define(Mode.BOOLEAN, false,
-                VERB_CREATE, OBJECT_AVD, "f", KEY_FORCE,
-                "Force creation (override an existing AVD)", false);
-
-        // --- delete avd ---
-
-        define(Mode.STRING, true,
-                VERB_DELETE, OBJECT_AVD, "n", KEY_NAME,
-                "Name of the AVD to delete", null);
-
-        // --- move avd ---
-
-        define(Mode.STRING, true,
-                VERB_MOVE, OBJECT_AVD, "n", KEY_NAME,
-                "Name of the AVD to move or rename", null);
-        define(Mode.STRING, false,
-                VERB_MOVE, OBJECT_AVD, "r", KEY_RENAME,
-                "New name of the AVD to rename", null);
-        define(Mode.STRING, false,
-                VERB_MOVE, OBJECT_AVD, "p", KEY_PATH,
-                "New location path of the directory where to move the AVD", null);
-
-        // --- update avd ---
-
-        define(Mode.STRING, true,
-                VERB_UPDATE, OBJECT_AVD, "n", KEY_NAME,
-                "Name of the AVD to update", null);
-
-        // --- create project ---
-
-        /* Disabled for ADT 0.9 / Cupcake SDK 1.5_r1 release. [bug #1795718].
-           This currently does not work, the alias build rules need to be fixed.
-
-        define(Mode.ENUM, true,
-                VERB_CREATE, OBJECT_PROJECT, "m", KEY_MODE,
-                "Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
-        */
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_PROJECT,
-                "p", KEY_PATH,
-                "Location path of new project", null);
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_PROJECT, "t", KEY_TARGET_ID,
-                "Target id of the new project", null);
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_PROJECT, "k", KEY_PACKAGE,
-                "Package name", null);
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_PROJECT, "a", KEY_ACTIVITY,
-                "Activity name", null);
-        define(Mode.STRING, false,
-                VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
-                "Project name", null);
-
-        // --- create test-project ---
-
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_TEST_PROJECT,
-                "p", KEY_PATH,
-                "Location path of new project", null);
-        define(Mode.STRING, false,
-                VERB_CREATE, OBJECT_TEST_PROJECT, "n", KEY_NAME,
-                "Project name", null);
-        define(Mode.STRING, true,
-                VERB_CREATE, OBJECT_TEST_PROJECT, "m", KEY_MAIN_PROJECT,
-                "Location path of the project to test, relative to the new project", null);
-
-        // --- update project ---
-
-        define(Mode.STRING, true,
-                VERB_UPDATE, OBJECT_PROJECT,
-                "p", KEY_PATH,
-                "Location path of the project", null);
-        define(Mode.STRING, false,
-                VERB_UPDATE, OBJECT_PROJECT,
-                "t", KEY_TARGET_ID,
-                "Target id to set for the project", null);
-        define(Mode.STRING, false,
-                VERB_UPDATE, OBJECT_PROJECT,
-                "n", KEY_NAME,
-                "Project name", null);
-        define(Mode.BOOLEAN, false,
-                VERB_UPDATE, OBJECT_PROJECT,
-                "s", KEY_SUBPROJECTS,
-                "Also update any projects in sub-folders, such as test projects.", false);
-
-        // --- update test project ---
-
-        define(Mode.STRING, true,
-                VERB_UPDATE, OBJECT_TEST_PROJECT,
-                "p", KEY_PATH,
-                "Location path of the project", null);
-        define(Mode.STRING, true,
-                VERB_UPDATE, OBJECT_TEST_PROJECT,
-                "m", KEY_MAIN_PROJECT,
-                "Location path of the project to test, relative to the new project", null);
-    }
-
-    @Override
-    public boolean acceptLackOfVerb() {
-        return true;
-    }
-
-    // -- some helpers for generic action flags
-
-    /** Helper to retrieve the --path value. */
-    public String getParamLocationPath() {
-        return (String) getValue(null, null, KEY_PATH);
-    }
-
-    /**
-     * Helper to retrieve the --target id value.
-     * The id is a string. It can be one of:
-     * - an integer, in which case it's the index of the target (cf "android list targets")
-     * - a symbolic name such as android-N for platforn API N
-     * - a symbolic add-on name such as written in the avd/*.ini files,
-     *   e.g. "Google Inc.:Google APIs:3"
-     */
-    public String getParamTargetId() {
-        return (String) getValue(null, null, KEY_TARGET_ID);
-    }
-
-    /** Helper to retrieve the --name value. */
-    public String getParamName() {
-        return (String) getValue(null, null, KEY_NAME);
-    }
-
-    /** Helper to retrieve the --skin value. */
-    public String getParamSkin() {
-        return (String) getValue(null, null, KEY_SKIN);
-    }
-
-    /** Helper to retrieve the --sdcard value. */
-    public String getParamSdCard() {
-        return (String) getValue(null, null, KEY_SDCARD);
-    }
-
-    /** Helper to retrieve the --force flag. */
-    public boolean getFlagForce() {
-        return ((Boolean) getValue(null, null, KEY_FORCE)).booleanValue();
-    }
-
-    // -- some helpers for avd action flags
-
-    /** Helper to retrieve the --rename value for a move verb. */
-    public String getParamMoveNewName() {
-        return (String) getValue(VERB_MOVE, null, KEY_RENAME);
-    }
-
-
-    // -- some helpers for project action flags
-
-    /** Helper to retrieve the --package value. */
-    public String getParamProjectPackage() {
-        return ((String) getValue(null, OBJECT_PROJECT, KEY_PACKAGE));
-    }
-
-    /** Helper to retrieve the --activity for any project action. */
-    public String getParamProjectActivity() {
-        return ((String) getValue(null, OBJECT_PROJECT, KEY_ACTIVITY));
-    }
-
-    /** Helper to retrieve the --subprojects for any project action. */
-    public boolean getParamSubProject() {
-        return ((Boolean) getValue(null, OBJECT_PROJECT, KEY_SUBPROJECTS)).booleanValue();
-    }
-
-    // -- some helpers for test-project action flags
-
-    /** Helper to retrieve the --main value. */
-    public String getParamTestProjectMain() {
-        return ((String) getValue(null, null, KEY_MAIN_PROJECT));
-    }
-}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/AboutPage.java b/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/AboutPage.java
deleted file mode 100755
index 742a065..0000000
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/AboutPage.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkmanager.internal.repository;
-
-
-import com.android.sdkmanager.*;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-public class AboutPage extends Composite {
-
-    private Label mLabel;
-
-    /**
-     * Create the composite.
-     * @param parent The parent of the composite.
-     */
-    public AboutPage(Composite parent) {
-        super(parent, SWT.BORDER);
-
-        createContents(this);
-
-        postCreate();  //$hide$
-    }
-
-    private void createContents(Composite parent) {
-        parent.setLayout(new GridLayout(2, false));
-
-        Label logo = new Label(parent, SWT.NONE);
-        InputStream imageStream = this.getClass().getResourceAsStream("logo.png");
-
-        if (imageStream != null) {
-            Image img = new Image(parent.getShell().getDisplay(), imageStream);
-            logo.setImage(img);
-        }
-
-        mLabel = new Label(parent, SWT.NONE);
-        mLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
-        mLabel.setText(String.format(
-                "Android SDK Updater.\nRevision %1$s\nCopyright (C) 2009 The Android Open Source Project.",
-                getRevision()));
-    }
-
-    @Override
-    protected void checkSubclass() {
-        // Disable the check that prevents subclassing of SWT components
-    }
-
-    // -- Start of internal part ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    /**
-     * Called by the constructor right after {@link #createContents(Composite)}.
-     */
-    private void postCreate() {
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-
-    private String getRevision() {
-        Properties p = new Properties();
-        try{
-            String toolsdir = System.getProperty(Main.TOOLSDIR);
-            File sourceProp;
-            if (toolsdir == null || toolsdir.length() == 0) {
-                sourceProp = new File("source.properties"); //$NON-NLS-1$
-            } else {
-                sourceProp = new File(toolsdir, "source.properties"); //$NON-NLS-1$
-            }
-            p.load(new FileInputStream(sourceProp));
-            String revision = p.getProperty("Pkg.Revision"); //$NON-NLS-1$
-            if (revision != null) {
-                return revision;
-            }
-        } catch (FileNotFoundException e) {
-            // couldn't find the file? don't ping.
-        } catch (IOException e) {
-            // couldn't find the file? don't ping.
-        }
-
-        return "?";
-    }
-}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java b/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java
deleted file mode 100755
index c800054..0000000
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkmanager.internal.repository;
-
-import com.android.sdkuilib.internal.repository.ISettingsPage;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.Properties;
-
-
-public class SettingsPage extends Composite implements ISettingsPage {
-
-    // data members
-    private SettingsChangedCallback mSettingsChangedCallback;
-
-    // UI widgets
-    private Group mProxySettingsGroup;
-    private Group mMiscGroup;
-    private Button mApplyButton;
-    private Label mProxyServerLabel;
-    private Label mProxyPortLabel;
-    private Text mProxyServerText;
-    private Text mProxyPortText;
-    private Button mForceHttpCheck;
-    private Button mAskAdbRestartCheck;
-
-    private ModifyListener mSetApplyDirty = new ModifyListener() {
-        public void modifyText(ModifyEvent e) {
-            mApplyButton.setEnabled(true);
-        }
-    };
-
-
-    /**
-     * Create the composite.
-     * @param parent The parent of the composite.
-     */
-    public SettingsPage(Composite parent) {
-        super(parent, SWT.BORDER);
-
-        createContents(this);
-
-        mProxySettingsGroup = new Group(this, SWT.NONE);
-        mProxySettingsGroup.setText("Proxy Settings");
-        mProxySettingsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
-        mProxySettingsGroup.setLayout(new GridLayout(2, false));
-
-        mProxyServerLabel = new Label(mProxySettingsGroup, SWT.NONE);
-        mProxyServerLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-        mProxyServerLabel.setText("HTTP Proxy Server");
-        String tooltip = "The DNS name or IP of the HTTP proxy server to use. " +
-                         "When empty, no HTTP proxy is used.";
-        mProxyServerLabel.setToolTipText(tooltip);
-
-        mProxyServerText = new Text(mProxySettingsGroup, SWT.BORDER);
-        mProxyServerText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-        mProxyServerText.addModifyListener(mSetApplyDirty);
-        mProxyServerText.setToolTipText(tooltip);
-
-        mProxyPortLabel = new Label(mProxySettingsGroup, SWT.NONE);
-        mProxyPortLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-        mProxyPortLabel.setText("HTTP Proxy Port");
-        tooltip = "The port of the HTTP proxy server to use. " +
-                  "When empty, the default for HTTP or HTTPS is used.";
-        mProxyPortLabel.setToolTipText(tooltip);
-
-        mProxyPortText = new Text(mProxySettingsGroup, SWT.BORDER);
-        mProxyPortText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-        mProxyPortText.addModifyListener(mSetApplyDirty);
-        mProxyPortText.setToolTipText(tooltip);
-
-        mMiscGroup = new Group(this, SWT.NONE);
-        mMiscGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
-        mMiscGroup.setText("Misc");
-        mMiscGroup.setLayout(new GridLayout(2, false));
-
-        mForceHttpCheck = new Button(mMiscGroup, SWT.CHECK);
-        mForceHttpCheck.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
-        mForceHttpCheck.setText("Force https://... sources to be fetched using http://...");
-        mForceHttpCheck.setToolTipText("If you are not able to connect to the official Android repository " +
-                "using HTTPS, enable this setting to force accessing it via HTTP.");
-        mForceHttpCheck.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onForceHttpSelected();  //$hide$
-            }
-        });
-
-        mAskAdbRestartCheck = new Button(mMiscGroup, SWT.CHECK);
-        mAskAdbRestartCheck.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
-        mAskAdbRestartCheck.setText("Ask before restarting ADB");
-        mAskAdbRestartCheck.setToolTipText("When checked, the user will be asked for permission " +
-                "to restart ADB after updating an addon-on package or a tool package.");
-        mAskAdbRestartCheck.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onForceHttpSelected();  //$hide$
-            }
-        });
-
-        mApplyButton = new Button(this, SWT.NONE);
-        mApplyButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-        mApplyButton.setText("Save && Apply");
-        mApplyButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onApplySelected(); //$hide$
-            }
-        });
-
-        postCreate();  //$hide$
-    }
-
-    private void createContents(Composite parent) {
-        parent.setLayout(new GridLayout(1, false));
-    }
-
-    @Override
-    protected void checkSubclass() {
-        // Disable the check that prevents subclassing of SWT components
-    }
-
-
-
-    // -- Start of internal part ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    /**
-     * Called by the constructor right after {@link #createContents(Composite)}.
-     */
-    private void postCreate() {
-    }
-
-    /** Loads settings from the given {@link Properties} container and update the page UI. */
-    public void loadSettings(Properties in_settings) {
-        mProxyServerText.setText(in_settings.getProperty(KEY_HTTP_PROXY_HOST, ""));  //$NON-NLS-1$
-        mProxyPortText.setText(  in_settings.getProperty(KEY_HTTP_PROXY_PORT, ""));  //$NON-NLS-1$
-        mForceHttpCheck.setSelection(Boolean.parseBoolean(in_settings.getProperty(KEY_FORCE_HTTP)));
-        mAskAdbRestartCheck.setSelection(Boolean.parseBoolean(in_settings.getProperty(KEY_ASK_ADB_RESTART)));
-
-        // We loaded fresh settings so there's nothing dirty to apply
-        mApplyButton.setEnabled(false);
-    }
-
-    /** Called by the application to retrieve settings from the UI and store them in
-     * the given {@link Properties} container. */
-    public void retrieveSettings(Properties out_settings) {
-        out_settings.setProperty(KEY_HTTP_PROXY_HOST, mProxyServerText.getText());
-        out_settings.setProperty(KEY_HTTP_PROXY_PORT, mProxyPortText.getText());
-        out_settings.setProperty(KEY_FORCE_HTTP,
-                Boolean.toString(mForceHttpCheck.getSelection()));
-        out_settings.setProperty(KEY_ASK_ADB_RESTART,
-                Boolean.toString(mAskAdbRestartCheck.getSelection()));
-    }
-
-    /**
-     * Called by the application to give a callback that the page should invoke when
-     * settings must be applied. The page does not apply the settings itself, instead
-     * it notifies the application.
-     */
-    public void setOnSettingsChanged(SettingsChangedCallback settingsChangedCallback) {
-        mSettingsChangedCallback = settingsChangedCallback;
-    }
-
-    /**
-     * Callback invoked when user presses the "Save and Apply" button.
-     * Notify the application that settings have changed.
-     */
-    private void onApplySelected() {
-        if (mSettingsChangedCallback != null) {
-            mSettingsChangedCallback.onSettingsChanged(this);
-            mApplyButton.setEnabled(false);
-        }
-    }
-
-    /**
-     * Callback invoked when the users presses the Force HTTPS checkbox.
-     */
-    private void onForceHttpSelected() {
-        mSetApplyDirty.modifyText(null);
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/logo.png b/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/logo.png
deleted file mode 100644
index 0f1670d..0000000
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/internal/repository/logo.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java
deleted file mode 100644
index a213652..0000000
--- a/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.android.sdkmanager;
-
-import com.android.sdklib.ISdkLog;
-
-import junit.framework.TestCase;
-
-
-public class CommandLineProcessorTest extends TestCase {
-
-    private MockStdLogger mLog;
-    
-    /**
-     * A mock version of the {@link CommandLineProcessor} class that does not
-     * exits and captures its stdout/stderr output.
-     */
-    public static class MockCommandLineProcessor extends CommandLineProcessor {
-        private boolean mExitCalled;
-        private boolean mHelpCalled;
-        private String mStdOut = "";
-        private String mStdErr = "";
-        
-        public MockCommandLineProcessor(ISdkLog logger) {
-            super(logger,
-                  new String[][] {
-                    { "verb1", "action1", "Some action" },
-                    { "verb1", "action2", "Another action" },
-            });
-            define(Mode.STRING, false /*mandatory*/,
-                    "verb1", "action1", "1", "first", "non-mandatory flag", null);
-            define(Mode.STRING, true /*mandatory*/,
-                    "verb1", "action1", "2", "second", "mandatory flag", null);
-        }
-        
-        @Override
-        public void printHelpAndExitForAction(String verb, String directObject,
-                String errorFormat, Object... args) {
-            mHelpCalled = true;
-            super.printHelpAndExitForAction(verb, directObject, errorFormat, args);
-        }
-        
-        @Override
-        protected void exit() {
-            mExitCalled = true;
-        }
-        
-        @Override
-        protected void stdout(String format, Object... args) {
-            String s = String.format(format, args);
-            mStdOut += s + "\n";
-            // don't call super to avoid printing stuff
-        }
-        
-        @Override
-        protected void stderr(String format, Object... args) {
-            String s = String.format(format, args);
-            mStdErr += s + "\n";
-            // don't call super to avoid printing stuff
-        }
-        
-        public boolean wasHelpCalled() {
-            return mHelpCalled;
-        }
-        
-        public boolean wasExitCalled() {
-            return mExitCalled;
-        }
-        
-        public String getStdOut() {
-            return mStdOut;
-        }
-        
-        public String getStdErr() {
-            return mStdErr;
-        }
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        mLog = new MockStdLogger();
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public final void testPrintHelpAndExit() {
-        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
-        assertFalse(c.wasExitCalled());
-        assertFalse(c.wasHelpCalled());
-        assertTrue(c.getStdOut().equals(""));
-        assertTrue(c.getStdErr().equals(""));
-        c.printHelpAndExit(null);
-        assertTrue(c.getStdOut().indexOf("-v") != -1);
-        assertTrue(c.getStdOut().indexOf("--verbose") != -1);
-        assertTrue(c.getStdErr().equals(""));
-        assertTrue(c.wasExitCalled());
-
-        c = new MockCommandLineProcessor(mLog);        
-        assertFalse(c.wasExitCalled());
-        assertTrue(c.getStdOut().equals(""));
-        assertTrue(c.getStdErr().indexOf("Missing parameter") == -1);
-
-        c.printHelpAndExit("Missing %s", "parameter");
-        assertTrue(c.wasExitCalled());
-        assertFalse(c.getStdOut().equals(""));
-        assertTrue(c.getStdErr().indexOf("Missing parameter") != -1);
-    }
-    
-    public final void testVerbose() {
-        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
-
-        assertFalse(c.isVerbose());
-        c.parseArgs(new String[] { "-v" });
-        assertTrue(c.isVerbose());
-        assertTrue(c.wasExitCalled());
-        assertTrue(c.wasHelpCalled());
-        assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1);
-
-        c = new MockCommandLineProcessor(mLog);        
-        c.parseArgs(new String[] { "--verbose" });
-        assertTrue(c.isVerbose());
-        assertTrue(c.wasExitCalled());
-        assertTrue(c.wasHelpCalled());
-        assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1);
-    }
-    
-    public final void testHelp() {
-        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
-
-        c.parseArgs(new String[] { "-h" });
-        assertTrue(c.wasExitCalled());
-        assertTrue(c.wasHelpCalled());
-        assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1);
-
-        c = new MockCommandLineProcessor(mLog);        
-        c.parseArgs(new String[] { "--help" });
-        assertTrue(c.wasExitCalled());
-        assertTrue(c.wasHelpCalled());
-        assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1);
-    }
-
-    public final void testMandatory() {
-        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
-
-        c.parseArgs(new String[] { "verb1", "action1", "-1", "value1", "-2", "value2" });
-        assertFalse(c.wasExitCalled());
-        assertFalse(c.wasHelpCalled());
-        assertEquals("", c.getStdErr());
-        assertEquals("value1", c.getValue("verb1", "action1", "first"));
-        assertEquals("value2", c.getValue("verb1", "action1", "second"));
-
-        c = new MockCommandLineProcessor(mLog);        
-        c.parseArgs(new String[] { "verb1", "action1", "-2", "value2" });
-        assertFalse(c.wasExitCalled());
-        assertFalse(c.wasHelpCalled());
-        assertEquals("", c.getStdErr());
-        assertEquals(null, c.getValue("verb1", "action1", "first"));
-        assertEquals("value2", c.getValue("verb1", "action1", "second"));
-
-        c = new MockCommandLineProcessor(mLog);        
-        c.parseArgs(new String[] { "verb1", "action1" });
-        assertTrue(c.wasExitCalled());
-        assertTrue(c.wasHelpCalled());
-        assertTrue(c.getStdErr().indexOf("must be defined") != -1);
-        assertEquals(null, c.getValue("verb1", "action1", "first"));
-        assertEquals(null, c.getValue("verb1", "action1", "second"));
-    }
-}
diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java
deleted file mode 100644
index 961e88d..0000000
--- a/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkmanager;
-
-import com.android.sdklib.ISdkLog;
-
-/**
- * 
- */
-public class MockStdLogger implements ISdkLog {
-
-    public void error(Throwable t, String errorFormat, Object... args) {
-        if (errorFormat != null) {
-            System.err.printf("Error: " + errorFormat, args);
-            if (!errorFormat.endsWith("\n")) {
-                System.err.printf("\n");
-            }
-        }
-        if (t != null) {
-            System.err.printf("Error: %s\n", t.getMessage());
-        }
-    }
-
-    public void warning(String warningFormat, Object... args) {
-        System.out.printf("Warning: " + warningFormat, args);
-        if (!warningFormat.endsWith("\n")) {
-            System.out.printf("\n");
-        }
-    }
-
-    public void printf(String msgFormat, Object... args) {
-        System.out.printf(msgFormat, args);
-    }
-}
diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java
deleted file mode 100644
index 07a32e0..0000000
--- a/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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.android.sdkmanager;
-
-import com.android.sdklib.ISdkLog;
-
-import junit.framework.TestCase;
-
-public class SdkCommandLineTest extends TestCase {
-
-    private MockStdLogger mLog;
-    
-    /**
-     * A mock version of the {@link SdkCommandLine} class that does not
-     * exits and discards its stdout/stderr output.
-     */
-    public static class MockSdkCommandLine extends SdkCommandLine {
-        private boolean mExitCalled;
-        private boolean mHelpCalled;
-        
-        public MockSdkCommandLine(ISdkLog logger) {
-            super(logger);
-        }
-
-        @Override
-        public void printHelpAndExitForAction(String verb, String directObject,
-                String errorFormat, Object... args) {
-            mHelpCalled = true;
-            super.printHelpAndExitForAction(verb, directObject, errorFormat, args);
-        }
-
-        @Override
-        protected void exit() {
-            mExitCalled = true;
-        }
-        
-        @Override
-        protected void stdout(String format, Object... args) {
-            // discard
-        }
-        
-        @Override
-        protected void stderr(String format, Object... args) {
-            // discard
-        }
-
-        public boolean wasExitCalled() {
-            return mExitCalled;
-        }
-        
-        public boolean wasHelpCalled() {
-            return mHelpCalled;
-        }
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        mLog = new MockStdLogger();
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /** Test list */
-    public final void testList_Avd_Verbose() {
-        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
-        c.parseArgs(new String[] { "-v", "list", "avd" });
-        assertFalse(c.wasHelpCalled());
-        assertFalse(c.wasExitCalled());
-        assertEquals("list", c.getVerb());
-        assertEquals("avd", c.getDirectObject());
-        assertTrue(c.isVerbose());
-    }
-
-    public final void testList_Target() {
-        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
-        c.parseArgs(new String[] { "list", "target" });
-        assertFalse(c.wasHelpCalled());
-        assertFalse(c.wasExitCalled());
-        assertEquals("list", c.getVerb());
-        assertEquals("target", c.getDirectObject());
-        assertFalse(c.isVerbose());
-    }
-
-    public final void testList_None() {
-        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
-        c.parseArgs(new String[] { "list" });
-        assertFalse(c.wasHelpCalled());
-        assertFalse(c.wasExitCalled());
-        assertEquals("list", c.getVerb());
-        assertEquals("", c.getDirectObject());
-        assertFalse(c.isVerbose());
-    }
-
-    public final void testList_Invalid() {
-        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
-        c.parseArgs(new String[] { "list", "unknown" });
-        assertTrue(c.wasHelpCalled());
-        assertTrue(c.wasExitCalled());
-        assertEquals(null, c.getVerb());
-        assertEquals(null, c.getDirectObject());
-        assertFalse(c.isVerbose());
-    }
-
-    public final void testList_Plural() {
-        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
-        c.parseArgs(new String[] { "list", "avds" });
-        assertFalse(c.wasHelpCalled());
-        assertFalse(c.wasExitCalled());
-        assertEquals("list", c.getVerb());
-        // we get the non-plural form
-        assertEquals("avd", c.getDirectObject());
-        assertFalse(c.isVerbose());
-
-        c = new MockSdkCommandLine(mLog);
-        c.parseArgs(new String[] { "list", "targets" });
-        assertFalse(c.wasHelpCalled());
-        assertFalse(c.wasExitCalled());
-        assertEquals("list", c.getVerb());
-        // we get the non-plural form
-        assertEquals("target", c.getDirectObject());
-        assertFalse(c.isVerbose());
-    }
-}
diff --git a/tools/sdkmanager/libs/Android.mk b/tools/sdkmanager/libs/Android.mk
deleted file mode 100644
index a934aa7..0000000
--- a/tools/sdkmanager/libs/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-SDKLIBS_LOCAL_DIR := $(call my-dir)
-include $(SDKLIBS_LOCAL_DIR)/sdklib/Android.mk
-include $(SDKLIBS_LOCAL_DIR)/sdkuilib/Android.mk
diff --git a/tools/sdkmanager/libs/sdklib/.classpath b/tools/sdkmanager/libs/sdklib/.classpath
deleted file mode 100644
index 123ceef..0000000
--- a/tools/sdkmanager/libs/sdklib/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="tests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/commons-compress/commons-compress-1.0.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/sdkmanager/libs/sdklib/.project b/tools/sdkmanager/libs/sdklib/.project
deleted file mode 100644
index 97a8578..0000000
--- a/tools/sdkmanager/libs/sdklib/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>SdkLib</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/sdkmanager/libs/sdklib/Android.mk b/tools/sdkmanager/libs/sdklib/Android.mk
deleted file mode 100644
index 509c573..0000000
--- a/tools/sdkmanager/libs/sdklib/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# 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.
-#
-SDKLIB_LOCAL_DIR := $(call my-dir)
-include $(SDKLIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkmanager/libs/sdklib/src/Android.mk b/tools/sdkmanager/libs/sdklib/src/Android.mk
deleted file mode 100644
index c8d6f71..0000000
--- a/tools/sdkmanager/libs/sdklib/src/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := .
-
-LOCAL_JAVA_LIBRARIES := \
-        androidprefs \
-        commons-compress-1.0
-
-LOCAL_MODULE := sdklib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
deleted file mode 100644
index d72cd94..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * 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.android.sdklib;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Represents an add-on target in the SDK.
- * An add-on extends a standard {@link PlatformTarget}.
- */
-final class AddOnTarget implements IAndroidTarget {
-    /**
-     * String to compute hash for add-on targets.
-     * Format is vendor:name:apiVersion
-     * */
-    private final static String ADD_ON_FORMAT = "%s:%s:%s"; //$NON-NLS-1$
-
-    private final static class OptionalLibrary implements IOptionalLibrary {
-        private final String mJarName;
-        private final String mJarPath;
-        private final String mName;
-        private final String mDescription;
-
-        OptionalLibrary(String jarName, String jarPath, String name, String description) {
-            mJarName = jarName;
-            mJarPath = jarPath;
-            mName = name;
-            mDescription = description;
-        }
-
-        public String getJarName() {
-            return mJarName;
-        }
-
-        public String getJarPath() {
-            return mJarPath;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public String getDescription() {
-            return mDescription;
-        }
-    }
-
-    private final String mLocation;
-    private final PlatformTarget mBasePlatform;
-    private final String mName;
-    private final String mVendor;
-    private final int mRevision;
-    private final String mDescription;
-    private String[] mSkins;
-    private String mDefaultSkin;
-    private IOptionalLibrary[] mLibraries;
-    private int mVendorId = NO_USB_ID;
-
-    /**
-     * Creates a new add-on
-     * @param location the OS path location of the add-on
-     * @param name the name of the add-on
-     * @param vendor the vendor name of the add-on
-     * @param revision the revision of the add-on
-     * @param description the add-on description
-     * @param libMap A map containing the optional libraries. The map key is the fully-qualified
-     * library name. The value is a 2 string array with the .jar filename, and the description.
-     * @param basePlatform the platform the add-on is extending.
-     */
-    AddOnTarget(String location, String name, String vendor, int revision, String description,
-            Map<String, String[]> libMap, PlatformTarget basePlatform) {
-        if (location.endsWith(File.separator) == false) {
-            location = location + File.separator;
-        }
-
-        mLocation = location;
-        mName = name;
-        mVendor = vendor;
-        mRevision = revision;
-        mDescription = description;
-        mBasePlatform = basePlatform;
-
-        // handle the optional libraries.
-        if (libMap != null) {
-            mLibraries = new IOptionalLibrary[libMap.size()];
-            int index = 0;
-            for (Entry<String, String[]> entry : libMap.entrySet()) {
-                String jarFile = entry.getValue()[0];
-                String desc = entry.getValue()[1];
-                mLibraries[index++] = new OptionalLibrary(jarFile,
-                        mLocation + SdkConstants.OS_ADDON_LIBS_FOLDER + jarFile,
-                        entry.getKey(), desc);
-            }
-        }
-    }
-
-    public String getLocation() {
-        return mLocation;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public String getVendor() {
-        return mVendor;
-    }
-
-    public String getFullName() {
-        return String.format("%1$s (%2$s)", mName, mVendor);
-    }
-
-    public String getClasspathName() {
-        return String.format("%1$s [%2$s]", mName, mBasePlatform.getName());
-    }
-
-    public String getDescription() {
-        return mDescription;
-    }
-
-    public AndroidVersion getVersion() {
-        // this is always defined by the base platform
-        return mBasePlatform.getVersion();
-    }
-
-    public String getVersionName() {
-        return mBasePlatform.getVersionName();
-    }
-
-    public int getRevision() {
-        return mRevision;
-    }
-
-    public boolean isPlatform() {
-        return false;
-    }
-
-    public IAndroidTarget getParent() {
-        return mBasePlatform;
-    }
-
-    public String getPath(int pathId) {
-        switch (pathId) {
-            case IMAGES:
-                return mLocation + SdkConstants.OS_IMAGES_FOLDER;
-            case SKINS:
-                return mLocation + SdkConstants.OS_SKINS_FOLDER;
-            case DOCS:
-                return mLocation + SdkConstants.FD_DOCS + File.separator
-                        + SdkConstants.FD_DOCS_REFERENCE;
-            case SAMPLES:
-                // only return the add-on samples folder if there is actually a sample (or more)
-                File sampleLoc = new File(mLocation, SdkConstants.FD_SAMPLES);
-                if (sampleLoc.isDirectory()) {
-                    File[] files = sampleLoc.listFiles(new FileFilter() {
-                        public boolean accept(File pathname) {
-                            return pathname.isDirectory();
-                        }
-
-                    });
-                    if (files != null && files.length > 0) {
-                        return sampleLoc.getAbsolutePath();
-                    }
-                }
-                // INTENDED FALL-THROUGH
-            default :
-                return mBasePlatform.getPath(pathId);
-        }
-    }
-
-    public String[] getSkins() {
-        return mSkins;
-    }
-
-    public String getDefaultSkin() {
-        return mDefaultSkin;
-    }
-
-    public IOptionalLibrary[] getOptionalLibraries() {
-        return mLibraries;
-    }
-
-    /**
-     * Returns the list of libraries of the underlying platform.
-     *
-     * {@inheritDoc}
-     */
-    public String[] getPlatformLibraries() {
-        return mBasePlatform.getPlatformLibraries();
-    }
-
-    public int getUsbVendorId() {
-        return mVendorId;
-    }
-
-    public boolean isCompatibleBaseFor(IAndroidTarget target) {
-        // basic test
-        if (target == this) {
-            return true;
-        }
-
-        /*
-         * The method javadoc indicates:
-         * Returns whether the given target is compatible with the receiver.
-         * <p/>A target is considered compatible if applications developed for the receiver can
-         * run on the given target.
-         */
-
-        // The receiver is an add-on. There are 2 big use cases: The add-on has libraries
-        // or the add-on doesn't (in which case we consider it a platform).
-        if (mLibraries.length == 0) {
-            return mBasePlatform.isCompatibleBaseFor(target);
-        } else {
-            // the only targets that can run the receiver are the same add-on in the same or later
-            // versions.
-            // first check: vendor/name
-            if (mVendor.equals(target.getVendor()) == false ||
-                            mName.equals(target.getName()) == false) {
-                return false;
-            }
-
-            // now check the version. At this point since we checked the add-on part,
-            // we can revert to the basic check on version/codename which are done by the
-            // base platform already.
-            return mBasePlatform.isCompatibleBaseFor(target);
-        }
-
-    }
-
-    public String hashString() {
-        return String.format(ADD_ON_FORMAT, mVendor, mName,
-                mBasePlatform.getVersion().getApiString());
-    }
-
-    @Override
-    public int hashCode() {
-        return hashString().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof AddOnTarget) {
-            AddOnTarget addon = (AddOnTarget)obj;
-
-            return mVendor.equals(addon.mVendor) && mName.equals(addon.mName) &&
-                mBasePlatform.getVersion().equals(addon.mBasePlatform.getVersion());
-        }
-
-        return false;
-    }
-
-    /*
-     * Always return +1 if the object we compare to is a platform.
-     * Otherwise, do vendor then name then api version comparison.
-     * (non-Javadoc)
-     * @see java.lang.Comparable#compareTo(java.lang.Object)
-     */
-    public int compareTo(IAndroidTarget target) {
-        if (target.isPlatform()) {
-            return +1;
-        }
-
-        // compare vendor
-        int value = mVendor.compareTo(target.getVendor());
-
-        // if same vendor, compare name
-        if (value == 0) {
-            value = mName.compareTo(target.getName());
-        }
-
-        // if same vendor/name, compare version
-        if (value == 0) {
-            if (getVersion().isPreview() == true) {
-                value = target.getVersion().isPreview() == true ?
-                        getVersion().getApiString().compareTo(target.getVersion().getApiString()) :
-                        +1; // put the preview at the end.
-            } else {
-                value = target.getVersion().isPreview() == true ?
-                        -1 : // put the preview at the end :
-                        getVersion().getApiLevel() - target.getVersion().getApiLevel();
-            }
-        }
-
-        return value;
-    }
-
-    // ---- local methods.
-
-    void setSkins(String[] skins, String defaultSkin) {
-        mDefaultSkin = defaultSkin;
-
-        // we mix the add-on and base platform skins
-        HashSet<String> skinSet = new HashSet<String>();
-        skinSet.addAll(Arrays.asList(skins));
-        skinSet.addAll(Arrays.asList(mBasePlatform.getSkins()));
-
-        mSkins = skinSet.toArray(new String[skinSet.size()]);
-    }
-
-    /**
-     * Sets the USB vendor id in the add-on.
-     */
-    void setUsbVendorId(int vendorId) {
-        if (vendorId == 0) {
-            throw new IllegalArgumentException( "VendorId must be > 0");
-        }
-
-        mVendorId = vendorId;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AndroidVersion.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AndroidVersion.java
deleted file mode 100644
index 13c3ea1..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AndroidVersion.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib;
-
-import java.util.Properties;
-
-/**
- * Represents the version of a target or device.
- * <p/>
- * A version is defined by an API level and an optional code name.
- * <ul><li>Release versions of the Android platform are identified by their API level (integer),
- * (technically the code name for release version is "REL" but this class will return
- * <code>null<code> instead.)</li>
- * <li>Preview versions of the platform are identified by a code name. Their API level
- * is usually set to the value of the previous platform.</li></ul>
- * <p/>
- * While this class contains both values, its goal is to abstract them, so that code comparing 2+
- * versions doesn't have to deal with the logic of handle both values.
- * <p/>
- * There are some cases where ones may want to access the values directly. This can be done
- * with {@link #getApiLevel()} and {@link #getCodename()}.
- * <p/>
- * For generic UI display of the API version, {@link #getApiString()} is to be used.
- *
- */
-public class AndroidVersion {
-
-    private static final String PROP_API_LEVEL = "AndroidVersion.ApiLevel";  //$NON-NLS-1$
-    private static final String PROP_CODENAME = "AndroidVersion.CodeName";   //$NON-NLS-1$
-
-    private final int mApiLevel;
-    private final String mCodename;
-
-    /**
-     * Creates an {@link AndroidVersion} with the given api level and codename.
-     * Codename should be null for a release version, otherwise it's a preview codename.
-     */
-    public AndroidVersion(int apiLevel, String codename) {
-        mApiLevel = apiLevel;
-        mCodename = codename;
-    }
-
-    /**
-     * Creates an {@link AndroidVersion} from {@link Properties}, with default values if the
-     * {@link Properties} object doesn't contain the expected values.
-     * <p/>The {@link Properties} is expected to have been filled with
-     * {@link #saveProperties(Properties)}.
-     */
-    public AndroidVersion(Properties properties, int defaultApiLevel, String defaultCodeName) {
-        if (properties == null) {
-            mApiLevel = defaultApiLevel;
-            mCodename = defaultCodeName;
-        } else {
-            mApiLevel = Integer.parseInt(properties.getProperty(PROP_API_LEVEL,
-                    Integer.toString(defaultApiLevel)));
-            mCodename = properties.getProperty(PROP_CODENAME, defaultCodeName);
-        }
-    }
-
-    public void saveProperties(Properties props) {
-        props.setProperty(PROP_API_LEVEL, Integer.toString(mApiLevel));
-        if (mCodename != null) {
-            props.setProperty(PROP_CODENAME, mCodename);
-        }
-    }
-
-    /**
-     * Returns the api level as an integer.
-     * <p/>For target that are in preview mode, this can be superseded by
-     * {@link #getCodename()}.
-     * <p/>To display the API level in the UI, use {@link #getApiString()}, which will use the
-     * codename if applicable.
-     * @see #getCodename()
-     * @see #getApiString()
-     */
-    public int getApiLevel() {
-        return mApiLevel;
-    }
-
-    /**
-     * Returns the version code name if applicable, null otherwise.
-     * <p/>If the codename is non null, then the API level should be ignored, and this should be
-     * used as a unique identifier of the target instead.
-     */
-    public String getCodename() {
-        return mCodename;
-    }
-
-    /**
-     * Returns a string representing the API level and/or the code name.
-     */
-    public String getApiString() {
-        if (mCodename != null) {
-            return mCodename;
-        }
-
-        return Integer.toString(mApiLevel);
-    }
-
-    /**
-     * Returns whether or not the version is a preview version.
-     */
-    public boolean isPreview() {
-        return mCodename != null;
-    }
-
-    /**
-     * Checks whether a device running a version similar to the receiver can run a project compiled
-     * for the given <var>version</var>.
-     * <p/>
-     * Be aware that this is not a perfect test, as other properties could break compatibility
-     * despite this method returning true. For a more comprehensive test, see
-     * {@link IAndroidTarget#isCompatibleBaseFor(IAndroidTarget)}.
-     * <p/>
-     * Nevertheless, when testing if an application can run on a device (where there is no
-     * access to the list of optional libraries), this method can give a good indication of whether
-     * there is a chance the application could run, or if there's a direct incompatibility.
-     */
-    public boolean canRun(AndroidVersion appVersion) {
-        // if the application is compiled for a preview version, the device must be running exactly
-        // the same.
-        if (appVersion.mCodename != null) {
-            return appVersion.mCodename.equals(mCodename);
-        }
-
-        // otherwise, we check the api level (note that a device running a preview version
-        // will have the api level of the previous platform).
-        return mApiLevel >= appVersion.mApiLevel;
-    }
-
-    /**
-     * Returns <code>true</code> if the AndroidVersion is an API level equals to
-     * <var>apiLevel</var>.
-     */
-    public boolean equals(int apiLevel) {
-        return mCodename == null && apiLevel == mApiLevel;
-    }
-
-    /**
-     * Compares the receiver with either an {@link AndroidVersion} object or a {@link String}
-     * object.
-     * <p/>If <var>obj</var> is a {@link String}, then the method will first check if it's a string
-     * representation of a number, in which case it'll compare it to the api level. Otherwise, it'll
-     * compare it against the code name.
-     * <p/>For all other type of object give as parameter, this method will return
-     * <code>false</code>.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof AndroidVersion) {
-            AndroidVersion version = (AndroidVersion)obj;
-
-            if (mCodename == null) {
-                return version.mCodename == null &&
-                        mApiLevel == version.mApiLevel;
-            } else {
-                return mCodename.equals(version.mCodename) &&
-                        mApiLevel == version.mApiLevel;
-            }
-
-        } else if (obj instanceof String) {
-            // if we have a code name, this must match.
-            if (mCodename != null) {
-                return mCodename.equals(obj);
-            }
-
-            // else we try to convert to a int and compare to the api level
-            try {
-                int value = Integer.parseInt((String)obj);
-                return value == mApiLevel;
-            } catch (NumberFormatException e) {
-                // not a number? we'll return false below.
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mCodename != null) {
-            return mCodename.hashCode();
-        }
-
-        // there may be some collisions between the hashcode of the codename and the api level
-        // but it's acceptable.
-        return mApiLevel;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
deleted file mode 100644
index 095a593..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * 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.android.sdklib;
-
-
-
-/**
- * A version of Android that applications can target when building.
- */
-public interface IAndroidTarget extends Comparable<IAndroidTarget> {
-
-    /** OS Path to the "android.jar" file. */
-    public final static int ANDROID_JAR         = 1;
-    /** OS Path to the "framework.aidl" file. */
-    public final static int ANDROID_AIDL        = 2;
-    /** OS Path to "images" folder which contains the emulator system images. */
-    public final static int IMAGES              = 3;
-    /** OS Path to the "samples" folder which contains sample projects. */
-    public final static int SAMPLES             = 4;
-    /** OS Path to the "skins" folder which contains the emulator skins. */
-    public final static int SKINS               = 5;
-    /** OS Path to the "templates" folder which contains the templates for new projects. */
-    public final static int TEMPLATES           = 6;
-    /** OS Path to the "data" folder which contains data & libraries for the SDK tools. */
-    public final static int DATA                = 7;
-    /** OS Path to the "attrs.xml" file. */
-    public final static int ATTRIBUTES          = 8;
-    /** OS Path to the "attrs_manifest.xml" file. */
-    public final static int MANIFEST_ATTRIBUTES = 9;
-    /** OS Path to the "data/layoutlib.jar" library. */
-    public final static int LAYOUT_LIB          = 10;
-    /** OS Path to the "data/res" folder. */
-    public final static int RESOURCES           = 11;
-    /** OS Path to the "data/fonts" folder. */
-    public final static int FONTS               = 12;
-    /** OS Path to the "data/widgets.txt" file. */
-    public final static int WIDGETS             = 13;
-    /** OS Path to the "data/activity_actions.txt" file. */
-    public final static int ACTIONS_ACTIVITY    = 14;
-    /** OS Path to the "data/broadcast_actions.txt" file. */
-    public final static int ACTIONS_BROADCAST   = 15;
-    /** OS Path to the "data/service_actions.txt" file. */
-    public final static int ACTIONS_SERVICE     = 16;
-    /** OS Path to the "data/categories.txt" file. */
-    public final static int CATEGORIES          = 17;
-    /** OS Path to the "sources" folder. */
-    public final static int SOURCES             = 18;
-    /** OS Path to the target specific docs */
-    public final static int DOCS                = 19;
-    /** OS Path to the target's version of the aapt tool. */
-    public final static int AAPT                = 20;
-    /** OS Path to the target's version of the aidl tool. */
-    public final static int AIDL                = 21;
-    /** OS Path to the target's version of the dx too. */
-    public final static int DX                  = 22;
-    /** OS Path to the target's version of the dx.jar file. */
-    public final static int DX_JAR              = 23;
-
-    /**
-     * Return value for {@link #getUsbVendorId()} meaning no USB vendor IDs are defined by the
-     * Android target.
-     */
-    public final static int NO_USB_ID = 0;
-
-    /** An optional library provided by an Android Target */
-    public interface IOptionalLibrary {
-        /** The name of the library, as used in the manifest (&lt;uses-library&gt;). */
-        String getName();
-        /** The file name of the jar file. */
-        String getJarName();
-        /** Absolute OS path to the jar file. */
-        String getJarPath();
-        /** Description of the library. */
-        String getDescription();
-    }
-
-    /**
-     * Returns the target location.
-     */
-    String getLocation();
-
-    /**
-     * Returns the name of the vendor of the target.
-     */
-    String getVendor();
-
-    /**
-     * Returns the name of the target.
-     */
-    String getName();
-
-    /**
-     * Returns the full name of the target, possibly including vendor name.
-     */
-    String getFullName();
-
-    /**
-     * Returns the name to be displayed when representing all the libraries this target contains.
-     */
-    String getClasspathName();
-
-    /**
-     * Returns the description of the target.
-     */
-    String getDescription();
-
-    /**
-     * Returns the version of the target. This is guaranteed to be non-null.
-     */
-    AndroidVersion getVersion();
-
-    /**
-     * Returns the platform version as a readable string.
-     */
-    public String getVersionName();
-
-    /** Returns the revision number for the target. */
-    int getRevision();
-
-    /**
-     * Returns true if the target is a standard Android platform.
-     */
-    boolean isPlatform();
-
-    /**
-     * Returns the parent target. This is likely to only be non <code>null</code> if
-     * {@link #isPlatform()} returns <code>false</code>
-     */
-    IAndroidTarget getParent();
-
-    /**
-     * Returns the path of a platform component.
-     * @param pathId the id representing the path to return. Any of the constants defined in the
-     * {@link IAndroidTarget} interface can be used.
-     */
-    String getPath(int pathId);
-
-    /**
-     * Returns the available skins for this target.
-     */
-    String[] getSkins();
-
-    /**
-     * Returns the default skin for this target.
-     */
-    String getDefaultSkin();
-
-    /**
-     * Returns the available optional libraries for this target.
-     * @return an array of optional libraries or <code>null</code> if there is none.
-     */
-    IOptionalLibrary[] getOptionalLibraries();
-
-    /**
-     * Returns the list of libraries available for a given platform.
-     *
-     * @return an array of libraries provided by the platform or <code>null</code> if there is none.
-     */
-    String[] getPlatformLibraries();
-
-    /**
-     * Returns the USB Vendor ID for the vendor of this target.
-     * <p/>If the target defines no USB Vendor ID, then the method return 0.
-     */
-    int getUsbVendorId();
-
-    /**
-     * Returns whether the given target is compatible with the receiver.
-     * <p/>A target is considered compatible if applications developed for the receiver can run on
-     * the given target.
-     *
-     * @param target the IAndroidTarget to test.
-     */
-    boolean isCompatibleBaseFor(IAndroidTarget target);
-
-    /**
-     * Returns a string able to uniquely identify a target.
-     * Typically the target will encode information such as api level, whether it's a platform
-     * or add-on, and if it's an add-on vendor and add-on name.
-     */
-    String hashString();
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java
deleted file mode 100644
index 163f7a9..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.android.sdklib;
-
-import java.util.Formatter;
-
-/**
- * Interface used to display warnings/errors while parsing the SDK content.
- */
-public interface ISdkLog {
-    
-    /**
-     * Prints a warning message on stdout.
-     * <p/>
-     * The message will be tagged with "Warning" on the output so the caller does not
-     * need to put such a prefix in the format string.
-     * <p/>
-     * Implementations should only display warnings in verbose mode.
-     * 
-     * @param warningFormat is an optional error format. If non-null, it will be printed
-     *          using a {@link Formatter} with the provided arguments.
-     * @param args provides the arguments for warningFormat.
-     */
-    void warning(String warningFormat, Object... args);
-    
-    /**
-     * Prints an error message on stderr.
-     * <p/>
-     * The message will be tagged with "Error" on the output so the caller does not
-     * need to put such a prefix in the format string.
-     * <p/>
-     * Implementation should always display errors, independent of verbose mode.
-     * 
-     * @param t is an optional {@link Throwable} or {@link Exception}. If non-null, it's
-     *          message will be printed out.
-     * @param errorFormat is an optional error format. If non-null, it will be printed
-     *          using a {@link Formatter} with the provided arguments.
-     * @param args provides the arguments for errorFormat.
-     */
-    void error(Throwable t, String errorFormat, Object... args);
-    
-    /**
-     * Prints a message as-is on stdout.
-     * <p/>
-     * Implementation should always display errors, independent of verbose mode.
-     * No prefix is used, the message is printed as-is after formatting.
-     * 
-     * @param msgFormat is an optional error format. If non-null, it will be printed
-     *          using a {@link Formatter} with the provided arguments.
-     * @param args provides the arguments for msgFormat.
-     */
-    void printf(String msgFormat, Object... args);
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/NullSdkLog.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/NullSdkLog.java
deleted file mode 100644
index e860f5b..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/NullSdkLog.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.android.sdklib;
-
-/**
- * Dummy implementation of an {@link ISdkLog}.
- * <p/>
- * Use {@link #getLogger()} to get a default instance of this {@link NullSdkLog}.
- *
- */
-public class NullSdkLog implements ISdkLog {
-
-    private static final ISdkLog sThis = new NullSdkLog();
-
-    public static ISdkLog getLogger() {
-        return sThis;
-    }
-
-    public void error(Throwable t, String errorFormat, Object... args) {
-        // ignore
-    }
-
-    public void printf(String msgFormat, Object... args) {
-        // ignore
-    }
-
-    public void warning(String warningFormat, Object... args) {
-        // ignore
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
deleted file mode 100644
index d0f009f..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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.android.sdklib;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Represents a platform target in the SDK.
- */
-final class PlatformTarget implements IAndroidTarget {
-    /** String used to get a hash to the platform target */
-    private final static String PLATFORM_HASH = "android-%s";
-
-    private final static String PLATFORM_VENDOR = "Android Open Source Project";
-
-    private final static String PLATFORM_NAME = "Android %s";
-    private final static String PLATFORM_NAME_PREVIEW = "Android %s (Preview)";
-
-    private final String mLocation;
-    private final String mName;
-    private final AndroidVersion mVersion;
-    private final String mVersionName;
-    private final int mRevision;
-    private final Map<String, String> mProperties;
-    private final Map<Integer, String> mPaths = new HashMap<Integer, String>();
-    private String[] mSkins;
-
-
-    PlatformTarget(String location, Map<String, String> properties,
-            int apiLevel, String codeName, String versionName, int revision) {
-        if (location.endsWith(File.separator) == false) {
-            location = location + File.separator;
-        }
-        mLocation = location;
-        mProperties = Collections.unmodifiableMap(properties);
-        mVersion = new AndroidVersion(apiLevel, codeName);
-        mVersionName = versionName;
-        mRevision = revision;
-
-        if (mVersion.isPreview()) {
-            mName =  String.format(PLATFORM_NAME_PREVIEW, mVersionName);
-        } else {
-            mName = String.format(PLATFORM_NAME, mVersionName);
-        }
-
-        // pre-build the path to the platform components
-        mPaths.put(ANDROID_JAR, mLocation + SdkConstants.FN_FRAMEWORK_LIBRARY);
-        mPaths.put(SOURCES, mLocation + SdkConstants.FD_ANDROID_SOURCES);
-        mPaths.put(ANDROID_AIDL, mLocation + SdkConstants.FN_FRAMEWORK_AIDL);
-        mPaths.put(IMAGES, mLocation + SdkConstants.OS_IMAGES_FOLDER);
-        mPaths.put(SAMPLES, mLocation + SdkConstants.OS_PLATFORM_SAMPLES_FOLDER);
-        mPaths.put(SKINS, mLocation + SdkConstants.OS_SKINS_FOLDER);
-        mPaths.put(TEMPLATES, mLocation + SdkConstants.OS_PLATFORM_TEMPLATES_FOLDER);
-        mPaths.put(DATA, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER);
-        mPaths.put(ATTRIBUTES, mLocation + SdkConstants.OS_PLATFORM_ATTRS_XML);
-        mPaths.put(MANIFEST_ATTRIBUTES, mLocation + SdkConstants.OS_PLATFORM_ATTRS_MANIFEST_XML);
-        mPaths.put(RESOURCES, mLocation + SdkConstants.OS_PLATFORM_RESOURCES_FOLDER);
-        mPaths.put(FONTS, mLocation + SdkConstants.OS_PLATFORM_FONTS_FOLDER);
-        mPaths.put(LAYOUT_LIB, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
-                SdkConstants.FN_LAYOUTLIB_JAR);
-        mPaths.put(WIDGETS, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
-                SdkConstants.FN_WIDGETS);
-        mPaths.put(ACTIONS_ACTIVITY, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
-                SdkConstants.FN_INTENT_ACTIONS_ACTIVITY);
-        mPaths.put(ACTIONS_BROADCAST, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
-                SdkConstants.FN_INTENT_ACTIONS_BROADCAST);
-        mPaths.put(ACTIONS_SERVICE, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
-                SdkConstants.FN_INTENT_ACTIONS_SERVICE);
-        mPaths.put(CATEGORIES, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
-                SdkConstants.FN_INTENT_CATEGORIES);
-        mPaths.put(AAPT, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AAPT);
-        mPaths.put(AIDL, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AIDL);
-        mPaths.put(DX, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_DX);
-        mPaths.put(DX_JAR, mLocation + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER +
-                SdkConstants.FN_DX_JAR);
-    }
-
-    public String getLocation() {
-        return mLocation;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * For Platform, the vendor name is always "Android".
-     *
-     * @see com.android.sdklib.IAndroidTarget#getVendor()
-     */
-    public String getVendor() {
-        return PLATFORM_VENDOR;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public String getFullName() {
-        return mName;
-    }
-
-    public String getClasspathName() {
-        return mName;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * Description for the Android platform is dynamically generated.
-     *
-     * @see com.android.sdklib.IAndroidTarget#getDescription()
-     */
-    public String getDescription() {
-        return String.format("Standard Android platform %s", mVersionName);
-    }
-
-    public AndroidVersion getVersion() {
-        return mVersion;
-    }
-
-    public String getVersionName() {
-        return mVersionName;
-    }
-
-    public int getRevision() {
-        return mRevision;
-    }
-
-    public boolean isPlatform() {
-        return true;
-    }
-
-    public IAndroidTarget getParent() {
-        return null;
-    }
-
-    public String getPath(int pathId) {
-        return mPaths.get(pathId);
-    }
-
-    public String[] getSkins() {
-        return mSkins;
-    }
-
-    public String getDefaultSkin() {
-        // at this time, this is the default skin for all the platform.
-        return "HVGA";
-    }
-
-    /**
-     * Always returns null, as a standard platform ha no optional libraries.
-     *
-     * {@inheritDoc}
-     * @see com.android.sdklib.IAndroidTarget#getOptionalLibraries()
-     */
-    public IOptionalLibrary[] getOptionalLibraries() {
-        return null;
-    }
-
-    /**
-     * Currently always return a fixed list with "android.test.runner" in it.
-     * <p/>
-     * TODO change the fixed library list to be build-dependent later.
-     * {@inheritDoc}
-     */
-    public String[] getPlatformLibraries() {
-        return new String[] { SdkConstants.ANDROID_TEST_RUNNER_LIB };
-    }
-
-    /**
-     * The platform has no USB Vendor Id: always return {@link IAndroidTarget#NO_USB_ID}.
-     * {@inheritDoc}
-     */
-    public int getUsbVendorId() {
-        return NO_USB_ID;
-    }
-
-    public boolean isCompatibleBaseFor(IAndroidTarget target) {
-        // basic test
-        if (target == this) {
-            return true;
-        }
-
-        // if the platform has a codename (ie it's a preview of an upcoming platform), then
-        // both platforms must be exactly identical.
-        if (mVersion.getCodename() != null) {
-            return mVersion.equals(target.getVersion());
-        }
-
-        // target is compatible wit the receiver as long as its api version number is greater or
-        // equal.
-        return target.getVersion().getApiLevel() >= mVersion.getApiLevel();
-    }
-
-    public String hashString() {
-        return String.format(PLATFORM_HASH, mVersion.getApiString());
-    }
-
-    @Override
-    public int hashCode() {
-        return hashString().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof PlatformTarget) {
-            PlatformTarget platform = (PlatformTarget)obj;
-
-            return mVersion.equals(platform.getVersion());
-        }
-
-        return false;
-    }
-
-    /*
-     * Always return -1 if the object we compare to is an addon.
-     * Otherwise, compare api level.
-     * (non-Javadoc)
-     * @see java.lang.Comparable#compareTo(java.lang.Object)
-     */
-    public int compareTo(IAndroidTarget target) {
-        if (target.isPlatform() == false) {
-            return -1;
-        }
-
-        int apiDiff = mVersion.getApiLevel() - target.getVersion().getApiLevel();
-
-        if (mVersion.getCodename() != null && apiDiff == 0) {
-            if (target.getVersion().getCodename() == null) {
-                return +1; // preview showed last
-            }
-            return mVersion.getCodename().compareTo(target.getVersion().getCodename());
-        }
-
-        return apiDiff;
-    }
-
-    // ---- platform only methods.
-
-    public String getProperty(String name) {
-        return mProperties.get(name);
-    }
-
-    public Map<String, String> getProperties() {
-        return mProperties; // mProperties is unmodifiable.
-    }
-
-    void setSkins(String[] skins) {
-        mSkins = skins;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
deleted file mode 100644
index b276ae3..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * 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.android.sdklib;
-
-import java.io.File;
-
-/**
- * Constant definition class.<br>
- * <br>
- * Most constants have a prefix defining the content.
- * <ul>
- * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
- * <li><code>FN_</code> File name constant.</li>
- * <li><code>FD_</code> Folder name constant.</li>
- * </ul>
- *
- */
-public final class SdkConstants {
-    public final static int PLATFORM_UNKNOWN = 0;
-    public final static int PLATFORM_LINUX = 1;
-    public final static int PLATFORM_WINDOWS = 2;
-    public final static int PLATFORM_DARWIN = 3;
-
-    /**
-     * Returns current platform, one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
-     * {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
-     */
-    public final static int CURRENT_PLATFORM = currentPlatform();
-
-    /**
-     * Charset for the ini file handled by the SDK.
-     */
-    public final static String INI_CHARSET = "UTF-8";
-
-    /** An SDK Project's AndroidManifest.xml file */
-    public static final String FN_ANDROID_MANIFEST_XML= "AndroidManifest.xml";
-    /** An SDK Project's build.xml file */
-    public final static String FN_BUILD_XML = "build.xml";
-
-    /** Name of the framework library, i.e. "android.jar" */
-    public static final String FN_FRAMEWORK_LIBRARY = "android.jar";
-    /** Name of the layout attributes, i.e. "attrs.xml" */
-    public static final String FN_ATTRS_XML = "attrs.xml";
-    /** Name of the layout attributes, i.e. "attrs_manifest.xml" */
-    public static final String FN_ATTRS_MANIFEST_XML = "attrs_manifest.xml";
-    /** framework aidl import file */
-    public static final String FN_FRAMEWORK_AIDL = "framework.aidl";
-    /** layoutlib.jar file */
-    public static final String FN_LAYOUTLIB_JAR = "layoutlib.jar";
-    /** widget list file */
-    public static final String FN_WIDGETS = "widgets.txt";
-    /** Intent activity actions list file */
-    public static final String FN_INTENT_ACTIONS_ACTIVITY = "activity_actions.txt";
-    /** Intent broadcast actions list file */
-    public static final String FN_INTENT_ACTIONS_BROADCAST = "broadcast_actions.txt";
-    /** Intent service actions list file */
-    public static final String FN_INTENT_ACTIONS_SERVICE = "service_actions.txt";
-    /** Intent category list file */
-    public static final String FN_INTENT_CATEGORIES = "categories.txt";
-
-    /** platform build property file */
-    public final static String FN_BUILD_PROP = "build.prop";
-    /** plugin properties file */
-    public final static String FN_PLUGIN_PROP = "plugin.prop";
-    /** add-on manifest file */
-    public final static String FN_MANIFEST_INI = "manifest.ini";
-    /** add-on layout device XML file. */
-    public final static String FN_DEVICES_XML = "devices.xml";
-    /** hardware properties definition file */
-    public final static String FN_HARDWARE_INI = "hardware-properties.ini";
-
-    /** Skin layout file */
-    public final static String FN_SKIN_LAYOUT = "layout";//$NON-NLS-1$
-
-    /** dex.jar file */
-    public static final String FN_DX_JAR = "dx.jar"; //$NON-NLS-1$
-
-    /** dx executable (with extension for the current OS)  */
-    public final static String FN_DX = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "dx.bat" : "dx"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /** aapt executable (with extension for the current OS)  */
-    public final static String FN_AAPT = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "aapt.exe" : "aapt"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /** aidl executable (with extension for the current OS)  */
-    public final static String FN_AIDL = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "aidl.exe" : "aidl"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /** adb executable (with extension for the current OS)  */
-    public final static String FN_ADB = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "adb.exe" : "adb"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /** emulator executable (with extension for the current OS) */
-    public final static String FN_EMULATOR = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "emulator.exe" : "emulator"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /** zipalign executable (with extension for the current OS)  */
-    public final static String FN_ZIPALIGN = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
-            "zipalign.exe" : "zipalign"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    /* Folder Names for Android Projects . */
-
-    /** Resources folder name, i.e. "res". */
-    public final static String FD_RESOURCES = "res"; //$NON-NLS-1$
-    /** Assets folder name, i.e. "assets" */
-    public final static String FD_ASSETS = "assets"; //$NON-NLS-1$
-    /** Default source folder name, i.e. "src" */
-    public final static String FD_SOURCES = "src"; //$NON-NLS-1$
-    /** Default generated source folder name, i.e. "gen" */
-    public final static String FD_GEN_SOURCES = "gen"; //$NON-NLS-1$
-    /** Default native library folder name inside the project, i.e. "libs"
-     * While the folder inside the .apk is "lib", we call that one libs because
-     * that's what we use in ant for both .jar and .so and we need to make the 2 development ways
-     * compatible. */
-    public final static String FD_NATIVE_LIBS = "libs"; //$NON-NLS-1$
-    /** Native lib folder inside the APK: "lib" */
-    public final static String FD_APK_NATIVE_LIBS = "lib"; //$NON-NLS-1$
-    /** Default output folder name, i.e. "bin" */
-    public final static String FD_OUTPUT = "bin"; //$NON-NLS-1$
-    /** Default anim resource folder name, i.e. "anim" */
-    public final static String FD_ANIM = "anim"; //$NON-NLS-1$
-    /** Default color resource folder name, i.e. "color" */
-    public final static String FD_COLOR = "color"; //$NON-NLS-1$
-    /** Default drawable resource folder name, i.e. "drawable" */
-    public final static String FD_DRAWABLE = "drawable"; //$NON-NLS-1$
-    /** Default layout resource folder name, i.e. "layout" */
-    public final static String FD_LAYOUT = "layout"; //$NON-NLS-1$
-    /** Default menu resource folder name, i.e. "menu" */
-    public final static String FD_MENU = "menu"; //$NON-NLS-1$
-    /** Default values resource folder name, i.e. "values" */
-    public final static String FD_VALUES = "values"; //$NON-NLS-1$
-    /** Default xml resource folder name, i.e. "xml" */
-    public final static String FD_XML = "xml"; //$NON-NLS-1$
-    /** Default raw resource folder name, i.e. "raw" */
-    public final static String FD_RAW = "raw"; //$NON-NLS-1$
-
-    /* Folder Names for the Android SDK */
-
-    /** Name of the SDK platforms folder. */
-    public final static String FD_PLATFORMS = "platforms";
-    /** Name of the SDK addons folder. */
-    public final static String FD_ADDONS = "add-ons";
-    /** Name of the SDK tools folder. */
-    public final static String FD_TOOLS = "tools";
-    /** Name of the SDK tools/lib folder. */
-    public final static String FD_LIB = "lib";
-    /** Name of the SDK docs folder. */
-    public final static String FD_DOCS = "docs";
-    /** Name of the doc folder containing API reference doc (javadoc) */
-    public static final String FD_DOCS_REFERENCE = "reference";
-    /** Name of the SDK images folder. */
-    public final static String FD_IMAGES = "images";
-    /** Name of the SDK skins folder. */
-    public final static String FD_SKINS = "skins";
-    /** Name of the SDK samples folder. */
-    public final static String FD_SAMPLES = "samples";
-    /** Name of the SDK templates folder, i.e. "templates" */
-    public final static String FD_TEMPLATES = "templates";
-    /** Name of the SDK data folder, i.e. "data" */
-    public final static String FD_DATA = "data";
-    /** Name of the SDK resources folder, i.e. "res" */
-    public final static String FD_RES = "res";
-    /** Name of the SDK font folder, i.e. "fonts" */
-    public final static String FD_FONTS = "fonts";
-    /** Name of the android sources directory */
-    public static final String FD_ANDROID_SOURCES = "sources";
-    /** Name of the addon libs folder. */
-    public final static String FD_ADDON_LIBS = "libs";
-
-    /** Namespace for the resource XML, i.e. "http://schemas.android.com/apk/res/android" */
-    public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
-
-    /** The name of the uses-library that provides "android.test.runner" */
-    public final static String ANDROID_TEST_RUNNER_LIB = "android.test.runner";
-
-    /* Folder path relative to the SDK root */
-    /** Path of the documentation directory relative to the sdk folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_SDK_DOCS_FOLDER = FD_DOCS + File.separator;
-
-    /** Path of the tools directory relative to the sdk folder, or to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_SDK_TOOLS_FOLDER = FD_TOOLS + File.separator;
-
-    /** Path of the lib directory relative to the sdk folder, or to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_SDK_TOOLS_LIB_FOLDER =
-            OS_SDK_TOOLS_FOLDER + FD_LIB + File.separator;
-
-    /* Folder paths relative to a platform or add-on folder */
-
-    /** Path of the images directory relative to a platform or addon folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_IMAGES_FOLDER = FD_IMAGES + File.separator;
-
-    /** Path of the skin directory relative to a platform or addon folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_SKINS_FOLDER = FD_SKINS + File.separator;
-
-    /* Folder paths relative to a Platform folder */
-
-    /** Path of the data directory relative to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_PLATFORM_DATA_FOLDER = FD_DATA + File.separator;
-
-    /** Path of the samples directory relative to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_PLATFORM_SAMPLES_FOLDER = FD_SAMPLES + File.separator;
-
-    /** Path of the resources directory relative to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_PLATFORM_RESOURCES_FOLDER =
-            OS_PLATFORM_DATA_FOLDER + FD_RES + File.separator;
-
-    /** Path of the fonts directory relative to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_PLATFORM_FONTS_FOLDER =
-            OS_PLATFORM_DATA_FOLDER + FD_FONTS + File.separator;
-
-    /** Path of the android source directory relative to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_PLATFORM_SOURCES_FOLDER = FD_ANDROID_SOURCES + File.separator;
-
-    /** Path of the android templates directory relative to a platform folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_PLATFORM_TEMPLATES_FOLDER = FD_TEMPLATES + File.separator;
-
-    /** Path of the attrs.xml file relative to a platform folder. */
-    public final static String OS_PLATFORM_ATTRS_XML =
-            OS_PLATFORM_RESOURCES_FOLDER + FD_VALUES + File.separator + FN_ATTRS_XML;
-
-    /** Path of the attrs_manifest.xml file relative to a platform folder. */
-    public final static String OS_PLATFORM_ATTRS_MANIFEST_XML =
-            OS_PLATFORM_RESOURCES_FOLDER + FD_VALUES + File.separator + FN_ATTRS_MANIFEST_XML;
-
-    /** Path of the layoutlib.jar file relative to a platform folder. */
-    public final static String OS_PLATFORM_LAYOUTLIB_JAR =
-            OS_PLATFORM_DATA_FOLDER + FN_LAYOUTLIB_JAR;
-
-    /* Folder paths relative to a addon folder */
-
-    /** Path of the images directory relative to a folder folder.
-     *  This is an OS path, ending with a separator. */
-    public final static String OS_ADDON_LIBS_FOLDER = FD_ADDON_LIBS + File.separator;
-
-
-    /** Skin default **/
-    public final static String SKIN_DEFAULT = "default";
-
-    /** Returns the appropriate name for the 'android' command, which is 'android.bat' for
-     * Windows and 'android' for all other platforms. */
-    public static String androidCmdName() {
-        String os = System.getProperty("os.name");
-        String cmd = "android";
-        if (os.startsWith("Windows")) {
-            cmd += ".bat";
-        }
-        return cmd;
-    }
-
-    /** Returns the appropriate name for the 'mksdcard' command, which is 'mksdcard.exe' for
-     * Windows and 'mkdsdcard' for all other platforms. */
-    public static String mkSdCardCmdName() {
-        String os = System.getProperty("os.name");
-        String cmd = "mksdcard";
-        if (os.startsWith("Windows")) {
-            cmd += ".exe";
-        }
-        return cmd;
-    }
-
-    /**
-     * Returns current platform
-     *
-     * @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
-     * {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
-     */
-    public static int currentPlatform() {
-        String os = System.getProperty("os.name");          //$NON-NLS-1$
-        if (os.startsWith("Mac OS")) {                      //$NON-NLS-1$
-            return PLATFORM_DARWIN;
-        } else if (os.startsWith("Windows")) {              //$NON-NLS-1$
-            return PLATFORM_WINDOWS;
-        } else if (os.startsWith("Linux")) {                //$NON-NLS-1$
-            return PLATFORM_LINUX;
-        }
-
-        return PLATFORM_UNKNOWN;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java
deleted file mode 100644
index 9009274..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * 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.android.sdklib;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The SDK manager parses the SDK folder and gives access to the content.
- * @see PlatformTarget
- * @see AddOnTarget
- */
-public final class SdkManager {
-
-    public final static String PROP_VERSION_SDK = "ro.build.version.sdk";
-    public final static String PROP_VERSION_CODENAME = "ro.build.version.codename";
-    public final static String PROP_VERSION_RELEASE = "ro.build.version.release";
-
-    private final static String ADDON_NAME = "name";
-    private final static String ADDON_VENDOR = "vendor";
-    private final static String ADDON_API = "api";
-    private final static String ADDON_DESCRIPTION = "description";
-    private final static String ADDON_LIBRARIES = "libraries";
-    private final static String ADDON_DEFAULT_SKIN = "skin";
-    private final static String ADDON_USB_VENDOR = "usb-vendor";
-    private final static String ADDON_REVISION = "revision";
-    private final static String ADDON_REVISION_OLD = "version";
-
-    private final static Pattern PATTERN_PROP = Pattern.compile(
-            "^([a-zA-Z0-9._-]+)\\s*=\\s*(.*)\\s*$");
-
-    private final static Pattern PATTERN_LIB_DATA = Pattern.compile(
-            "^([a-zA-Z0-9._-]+\\.jar);(.*)$", Pattern.CASE_INSENSITIVE);
-
-     // usb ids are 16-bit hexadecimal values.
-    private final static Pattern PATTERN_USB_IDS = Pattern.compile(
-            "^0x[a-f0-9]{4}$", Pattern.CASE_INSENSITIVE);
-
-    /** List of items in the platform to check when parsing it. These paths are relative to the
-     * platform root folder. */
-    private final static String[] sPlatformContentList = new String[] {
-        SdkConstants.FN_FRAMEWORK_LIBRARY,
-        SdkConstants.FN_FRAMEWORK_AIDL,
-        SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AAPT,
-        SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AIDL,
-        SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_DX,
-        SdkConstants.OS_SDK_TOOLS_LIB_FOLDER + SdkConstants.FN_DX_JAR,
-    };
-
-    /** Preference file containing the usb ids for adb */
-    private final static String ADB_INI_FILE = "adb_usb.ini";
-       //0--------90--------90--------90--------90--------90--------90--------90--------9
-    private final static String ADB_INI_HEADER =
-        "# ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT.\n" +
-        "# USE 'android update adb' TO GENERATE.\n" +
-        "# 1 USB VENDOR ID PER LINE.\n";
-
-    /** the location of the SDK */
-    private final String mSdkLocation;
-    private IAndroidTarget[] mTargets;
-
-    /**
-     * Create a new {@link SdkManager} instance.
-     * External users should use {@link #createManager(String, ISdkLog)}.
-     *
-     * @param sdkLocation the location of the SDK.
-     */
-    private SdkManager(String sdkLocation) {
-        mSdkLocation = sdkLocation;
-    }
-
-    /**
-     * Creates an {@link SdkManager} for a given sdk location.
-     * @param sdkLocation the location of the SDK.
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     * @return the created {@link SdkManager} or null if the location is not valid.
-     */
-    public static SdkManager createManager(String sdkLocation, ISdkLog log) {
-        try {
-            SdkManager manager = new SdkManager(sdkLocation);
-            ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
-            loadPlatforms(sdkLocation, list, log);
-            loadAddOns(sdkLocation, list, log);
-
-            // sort the targets/add-ons
-            Collections.sort(list);
-
-            manager.setTargets(list.toArray(new IAndroidTarget[list.size()]));
-
-            return manager;
-        } catch (IllegalArgumentException e) {
-            if (log != null) {
-                log.error(e, "Error parsing the sdk.");
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the location of the SDK.
-     */
-    public String getLocation() {
-        return mSdkLocation;
-    }
-
-    /**
-     * Returns the targets that are available in the SDK.
-     * <p/>
-     * The array can be empty but not null.
-     */
-    public IAndroidTarget[] getTargets() {
-        return mTargets;
-    }
-
-    /**
-     * Sets the targets that are available in the SDK.
-     * <p/>
-     * The array can be empty but not null.
-     */
-    private void setTargets(IAndroidTarget[] targets) {
-        assert targets != null;
-        mTargets = targets;
-    }
-
-    /**
-     * Returns a target from a hash that was generated by {@link IAndroidTarget#hashString()}.
-     *
-     * @param hash the {@link IAndroidTarget} hash string.
-     * @return The matching {@link IAndroidTarget} or null.
-     */
-    public IAndroidTarget getTargetFromHashString(String hash) {
-        if (hash != null) {
-            for (IAndroidTarget target : mTargets) {
-                if (hash.equals(target.hashString())) {
-                    return target;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Updates adb with the USB devices declared in the SDK add-ons.
-     * @throws AndroidLocationException
-     * @throws IOException
-     */
-    public void updateAdb() throws AndroidLocationException, IOException {
-        FileWriter writer = null;
-        try {
-            // get the android prefs location to know where to write the file.
-            File adbIni = new File(AndroidLocation.getFolder(), ADB_INI_FILE);
-            writer = new FileWriter(adbIni);
-
-            // first, put all the vendor id in an HashSet to remove duplicate.
-            HashSet<Integer> set = new HashSet<Integer>();
-            IAndroidTarget[] targets = getTargets();
-            for (IAndroidTarget target : targets) {
-                if (target.getUsbVendorId() != IAndroidTarget.NO_USB_ID) {
-                    set.add(target.getUsbVendorId());
-                }
-            }
-
-            // write file header.
-            writer.write(ADB_INI_HEADER);
-
-            // now write the Id in a text file, one per line.
-            for (Integer i : set) {
-                writer.write(String.format("0x%04x\n", i));
-            }
-        } finally {
-            if (writer != null) {
-                writer.close();
-            }
-        }
-    }
-
-    /**
-     * Reloads the content of the SDK.
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     */
-    public void reloadSdk(ISdkLog log) {
-        // get the current target list.
-        ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
-        loadPlatforms(mSdkLocation, list, log);
-        loadAddOns(mSdkLocation, list, log);
-
-        // For now replace the old list with the new one.
-        // In the future we may want to keep the current objects, so that ADT doesn't have to deal
-        // with new IAndroidTarget objects when a target didn't actually change.
-
-        // sort the targets/add-ons
-        Collections.sort(list);
-        setTargets(list.toArray(new IAndroidTarget[list.size()]));
-    }
-
-    /**
-     * Loads the Platforms from the SDK.
-     * @param location Location of the SDK
-     * @param list the list to fill with the platforms.
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     */
-    private static void loadPlatforms(String location, ArrayList<IAndroidTarget> list,
-            ISdkLog log) {
-        File platformFolder = new File(location, SdkConstants.FD_PLATFORMS);
-        if (platformFolder.isDirectory()) {
-            File[] platforms  = platformFolder.listFiles();
-
-            for (File platform : platforms) {
-                if (platform.isDirectory()) {
-                    PlatformTarget target = loadPlatform(platform, log);
-                    if (target != null) {
-                        list.add(target);
-                    }
-                } else if (log != null) {
-                    log.warning("Ignoring platform '%1$s', not a folder.", platform.getName());
-                }
-            }
-
-            return;
-        }
-
-        String message = null;
-        if (platformFolder.exists() == false) {
-            message = "%s is missing.";
-        } else {
-            message = "%s is not a folder.";
-        }
-
-        throw new IllegalArgumentException(String.format(message,
-                platformFolder.getAbsolutePath()));
-    }
-
-    /**
-     * Loads a specific Platform at a given location.
-     * @param platform the location of the platform.
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     */
-    private static PlatformTarget loadPlatform(File platform, ISdkLog log) {
-        File buildProp = new File(platform, SdkConstants.FN_BUILD_PROP);
-
-        if (buildProp.isFile()) {
-            Map<String, String> map = parsePropertyFile(buildProp, log);
-
-            if (map != null) {
-                // look for some specific values in the map.
-
-                // version string
-                String apiName = map.get(PROP_VERSION_RELEASE);
-                if (apiName == null) {
-                    if (log != null) {
-                        log.error(null,
-                                "Ignoring platform '%1$s': %2$s is missing from '%3$s'",
-                                platform.getName(), PROP_VERSION_RELEASE,
-                                SdkConstants.FN_BUILD_PROP);
-                    }
-                    return null;
-                }
-
-                // api level
-                int apiNumber;
-                String stringValue = map.get(PROP_VERSION_SDK);
-                if (stringValue == null) {
-                    if (log != null) {
-                        log.error(null,
-                                "Ignoring platform '%1$s': %2$s is missing from '%3$s'",
-                                platform.getName(), PROP_VERSION_SDK,
-                                SdkConstants.FN_BUILD_PROP);
-                    }
-                    return null;
-                } else {
-                    try {
-                         apiNumber = Integer.parseInt(stringValue);
-                    } catch (NumberFormatException e) {
-                        // looks like apiNumber does not parse to a number.
-                        // Ignore this platform.
-                        if (log != null) {
-                            log.error(null,
-                                    "Ignoring platform '%1$s': %2$s is not a valid number in %3$s.",
-                                    platform.getName(), PROP_VERSION_SDK,
-                                    SdkConstants.FN_BUILD_PROP);
-                        }
-                        return null;
-                    }
-                }
-
-                // codename (optional)
-                String apiCodename = map.get(PROP_VERSION_CODENAME);
-                if (apiCodename != null && apiCodename.equals("REL")) {
-                    apiCodename = null; // REL means it's a release version and therefore the
-                                        // codename is irrelevant at this point.
-                }
-
-                int revision = 1;
-                // FIXME: properly parse the platform revision.
-
-                // api number and name look valid, perform a few more checks
-                if (checkPlatformContent(platform, log) == false) {
-                    return null;
-                }
-                // create the target.
-                PlatformTarget target = new PlatformTarget(
-                        platform.getAbsolutePath(),
-                        map,
-                        apiNumber,
-                        apiCodename,
-                        apiName,
-                        revision);
-
-                // need to parse the skins.
-                String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
-                target.setSkins(skins);
-
-                return target;
-            }
-        } else if (log != null) {
-            log.error(null, "Ignoring platform '%1$s': %2$s is missing.", platform.getName(),
-                    SdkConstants.FN_BUILD_PROP);
-        }
-
-        return null;
-    }
-
-    /**
-     * Loads the Add-on from the SDK.
-     * @param location Location of the SDK
-     * @param list the list to fill with the add-ons.
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     */
-    private static void loadAddOns(String location, ArrayList<IAndroidTarget> list, ISdkLog log) {
-        File addonFolder = new File(location, SdkConstants.FD_ADDONS);
-        if (addonFolder.isDirectory()) {
-            File[] addons  = addonFolder.listFiles();
-
-            for (File addon : addons) {
-                // Add-ons have to be folders. Ignore files and no need to warn about them.
-                if (addon.isDirectory()) {
-                    AddOnTarget target = loadAddon(addon, list, log);
-                    if (target != null) {
-                        list.add(target);
-                    }
-                }
-            }
-
-            return;
-        }
-
-        String message = null;
-        if (addonFolder.exists() == false) {
-            message = "%s is missing.";
-        } else {
-            message = "%s is not a folder.";
-        }
-
-        throw new IllegalArgumentException(String.format(message,
-                addonFolder.getAbsolutePath()));
-    }
-
-    /**
-     * Loads a specific Add-on at a given location.
-     * @param addon the location of the addon.
-     * @param targetList The list of Android target that were already loaded from the SDK.
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     */
-    private static AddOnTarget loadAddon(File addon, ArrayList<IAndroidTarget> targetList,
-            ISdkLog log) {
-        File addOnManifest = new File(addon, SdkConstants.FN_MANIFEST_INI);
-
-        if (addOnManifest.isFile()) {
-            Map<String, String> propertyMap = parsePropertyFile(addOnManifest, log);
-
-            if (propertyMap != null) {
-                // look for some specific values in the map.
-                // we require name, vendor, and api
-                String name = propertyMap.get(ADDON_NAME);
-                if (name == null) {
-                    displayAddonManifestError(log, addon.getName(), ADDON_NAME);
-                    return null;
-                }
-
-                String vendor = propertyMap.get(ADDON_VENDOR);
-                if (vendor == null) {
-                    displayAddonManifestError(log, addon.getName(), ADDON_VENDOR);
-                    return null;
-                }
-
-                String api = propertyMap.get(ADDON_API);
-                PlatformTarget baseTarget = null;
-                if (api == null) {
-                    displayAddonManifestError(log, addon.getName(), ADDON_API);
-                    return null;
-                } else {
-                    // Look for a platform that has a matching api level or codename.
-                    for (IAndroidTarget target : targetList) {
-                        if (target.isPlatform() && target.getVersion().equals(api)) {
-                            baseTarget = (PlatformTarget)target;
-                            break;
-                        }
-                    }
-
-                    if (baseTarget == null) {
-                        // Ignore this add-on.
-                        if (log != null) {
-                            log.error(null,
-                                    "Ignoring add-on '%1$s': Unable to find base platform with API level '%2$s'",
-                                    addon.getName(), api);
-                        }
-                        return null;
-                    }
-                }
-
-                // get the optional description
-                String description = propertyMap.get(ADDON_DESCRIPTION);
-
-                // get the add-on revision
-                int revisionValue = 1;
-                String revision = propertyMap.get(ADDON_REVISION);
-                if (revision == null) {
-                    revision = propertyMap.get(ADDON_REVISION_OLD);
-                }
-                if (revision != null) {
-                    try {
-                        revisionValue = Integer.parseInt(revision);
-                    } catch (NumberFormatException e) {
-                        // looks like apiNumber does not parse to a number.
-                        // Ignore this add-on.
-                        if (log != null) {
-                            log.error(null,
-                                    "Ignoring add-on '%1$s': %2$s is not a valid number in %3$s.",
-                                    addon.getName(), ADDON_REVISION, SdkConstants.FN_BUILD_PROP);
-                        }
-                        return null;
-                    }
-                }
-
-                // get the optional libraries
-                String librariesValue = propertyMap.get(ADDON_LIBRARIES);
-                Map<String, String[]> libMap = null;
-
-                if (librariesValue != null) {
-                    librariesValue = librariesValue.trim();
-                    if (librariesValue.length() > 0) {
-                        // split in the string into the libraries name
-                        String[] libraries = librariesValue.split(";");
-                        if (libraries.length > 0) {
-                            libMap = new HashMap<String, String[]>();
-                            for (String libName : libraries) {
-                                libName = libName.trim();
-
-                                // get the library data from the properties
-                                String libData = propertyMap.get(libName);
-
-                                if (libData != null) {
-                                    // split the jar file from the description
-                                    Matcher m = PATTERN_LIB_DATA.matcher(libData);
-                                    if (m.matches()) {
-                                        libMap.put(libName, new String[] {
-                                                m.group(1), m.group(2) });
-                                    } else if (log != null) {
-                                        log.error(null,
-                                                "Ignoring library '%1$s', property value has wrong format\n\t%2$s",
-                                                libName, libData);
-                                    }
-                                } else if (log != null) {
-                                    log.error(null,
-                                            "Ignoring library '%1$s', missing property value",
-                                            libName, libData);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                AddOnTarget target = new AddOnTarget(addon.getAbsolutePath(), name, vendor,
-                        revisionValue, description, libMap, baseTarget);
-
-                // need to parse the skins.
-                String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
-
-                // get the default skin, or take it from the base platform if needed.
-                String defaultSkin = propertyMap.get(ADDON_DEFAULT_SKIN);
-                if (defaultSkin == null) {
-                    if (skins.length == 1) {
-                        defaultSkin = skins[0];
-                    } else {
-                        defaultSkin = baseTarget.getDefaultSkin();
-                    }
-                }
-
-                // get the USB ID (if available)
-                int usbVendorId = convertId(propertyMap.get(ADDON_USB_VENDOR));
-                if (usbVendorId != IAndroidTarget.NO_USB_ID) {
-                    target.setUsbVendorId(usbVendorId);
-                }
-
-                target.setSkins(skins, defaultSkin);
-
-                return target;
-            }
-        } else if (log != null) {
-            log.error(null, "Ignoring add-on '%1$s': %2$s is missing.", addon.getName(),
-                    SdkConstants.FN_MANIFEST_INI);
-        }
-
-        return null;
-    }
-
-    /**
-     * Converts a string representation of an hexadecimal ID into an int.
-     * @param value the string to convert.
-     * @return the int value, or {@link IAndroidTarget#NO_USB_ID} if the convertion failed.
-     */
-    private static int convertId(String value) {
-        if (value != null && value.length() > 0) {
-            if (PATTERN_USB_IDS.matcher(value).matches()) {
-                String v = value.substring(2);
-                try {
-                    return Integer.parseInt(v, 16);
-                } catch (NumberFormatException e) {
-                    // this shouldn't happen since we check the pattern above, but this is safer.
-                    // the method will return 0 below.
-                }
-            }
-        }
-
-        return IAndroidTarget.NO_USB_ID;
-    }
-
-    private static void displayAddonManifestError(ISdkLog log, String addonName, String valueName) {
-        if (log != null) {
-            log.error(null, "Ignoring add-on '%1$s': '%2$s' is missing from %3$s.",
-                    addonName, valueName, SdkConstants.FN_MANIFEST_INI);
-        }
-    }
-
-    /**
-     * Checks the given platform has all the required files, and returns true if they are all
-     * present.
-     * <p/>This checks the presence of the following files: android.jar, framework.aidl, aapt(.exe),
-     * aidl(.exe), dx(.bat), and dx.jar
-     */
-    private static boolean checkPlatformContent(File platform, ISdkLog log) {
-        for (String relativePath : sPlatformContentList) {
-            File f = new File(platform, relativePath);
-            if (f.exists() == false) {
-                log.error(null,
-                        "Ignoring platform '%1$s': %2$s is missing.",
-                        platform.getName(), relativePath);
-                return false;
-            }
-        }
-        return true;
-    }
-
-
-    /**
-     * Parses a property file (using UTF-8 encoding) and returns
-     * @param buildProp the property file to parse
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     * @return the map of (key,value) pairs, or null if the parsing failed.
-     */
-    public static Map<String, String> parsePropertyFile(File buildProp, ISdkLog log) {
-        FileInputStream fis = null;
-        BufferedReader reader = null;
-        try {
-            fis = new FileInputStream(buildProp);
-            reader = new BufferedReader(new InputStreamReader(fis, SdkConstants.INI_CHARSET));
-
-            String line = null;
-            Map<String, String> map = new HashMap<String, String>();
-            while ((line = reader.readLine()) != null) {
-                if (line.length() > 0 && line.charAt(0) != '#') {
-
-                    Matcher m = PATTERN_PROP.matcher(line);
-                    if (m.matches()) {
-                        map.put(m.group(1), m.group(2));
-                    } else {
-                        if (log != null) {
-                            log.warning("Error parsing '%1$s': \"%2$s\" is not a valid syntax",
-                                    buildProp.getAbsolutePath(), line);
-                        }
-                        return null;
-                    }
-                }
-            }
-
-            return map;
-        } catch (FileNotFoundException e) {
-            // this should not happen since we usually test the file existence before
-            // calling the method.
-            // Return null below.
-        } catch (IOException e) {
-            if (log != null) {
-                log.warning("Error parsing '%1$s': %2$s.", buildProp.getAbsolutePath(),
-                        e.getMessage());
-            }
-        } finally {
-            if (reader != null) {
-                try {
-                    reader.close();
-                } catch (IOException e) {
-                    // pass
-                }
-            }
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                    // pass
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Parses the skin folder and builds the skin list.
-     * @param osPath The path of the skin root folder.
-     */
-    private static String[] parseSkinFolder(String osPath) {
-        File skinRootFolder = new File(osPath);
-
-        if (skinRootFolder.isDirectory()) {
-            ArrayList<String> skinList = new ArrayList<String>();
-
-            File[] files = skinRootFolder.listFiles();
-
-            for (File skinFolder : files) {
-                if (skinFolder.isDirectory()) {
-                    // check for layout file
-                    File layout = new File(skinFolder, SdkConstants.FN_SKIN_LAYOUT);
-
-                    if (layout.isFile()) {
-                        // for now we don't parse the content of the layout and
-                        // simply add the directory to the list.
-                        skinList.add(skinFolder.getName());
-                    }
-                }
-            }
-
-            return skinList.toArray(new String[skinList.size()]);
-        }
-
-        return new String[0];
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
deleted file mode 100644
index 36b3b7f..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
+++ /dev/null
@@ -1,1409 +0,0 @@
-/*
- * 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.android.sdklib.internal.avd;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Android Virtual Device Manager to manage AVDs.
- */
-public final class AvdManager {
-
-    /**
-     * Exception thrown when something is wrong with a target path.
-     */
-    private final static class InvalidTargetPathException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        InvalidTargetPathException(String message) {
-            super(message);
-        }
-    }
-
-    public static final String AVD_FOLDER_EXTENSION = ".avd";  //$NON-NLS-1$
-
-    public final static String AVD_INFO_PATH = "path";         //$NON-NLS-1$
-    public final static String AVD_INFO_TARGET = "target";     //$NON-NLS-1$
-
-    /**
-     * AVD/config.ini key name representing the SDK-relative path of the skin folder, if any,
-     * or a 320x480 like constant for a numeric skin size.
-     *
-     * @see #NUMERIC_SKIN_SIZE
-     */
-    public final static String AVD_INI_SKIN_PATH = "skin.path"; //$NON-NLS-1$
-    /**
-     * AVD/config.ini key name representing an UI name for the skin.
-     * This config key is ignored by the emulator. It is only used by the SDK manager or
-     * tools to give a friendlier name to the skin.
-     * If missing, use the {@link #AVD_INI_SKIN_PATH} key instead.
-     */
-    public final static String AVD_INI_SKIN_NAME = "skin.name"; //$NON-NLS-1$
-    /**
-     * AVD/config.ini key name representing the path to the sdcard file.
-     * If missing, the default name "sdcard.img" will be used for the sdcard, if there's such
-     * a file.
-     *
-     * @see #SDCARD_IMG
-     */
-    public final static String AVD_INI_SDCARD_PATH = "sdcard.path"; //$NON-NLS-1$
-    /**
-     * AVD/config.ini key name representing the size of the SD card.
-     * This property is for UI purposes only. It is not used by the emulator.
-     *
-     * @see #SDCARD_SIZE_PATTERN
-     */
-    public final static String AVD_INI_SDCARD_SIZE = "sdcard.size"; //$NON-NLS-1$
-    /**
-     * AVD/config.ini key name representing the first path where the emulator looks
-     * for system images. Typically this is the path to the add-on system image or
-     * the path to the platform system image if there's no add-on.
-     * <p/>
-     * The emulator looks at {@link #AVD_INI_IMAGES_1} before {@link #AVD_INI_IMAGES_2}.
-     */
-    public final static String AVD_INI_IMAGES_1 = "image.sysdir.1"; //$NON-NLS-1$
-    /**
-     * AVD/config.ini key name representing the second path where the emulator looks
-     * for system images. Typically this is the path to the platform system image.
-     *
-     * @see #AVD_INI_IMAGES_1
-     */
-    public final static String AVD_INI_IMAGES_2 = "image.sysdir.2"; //$NON-NLS-1$
-
-    /**
-     * Pattern to match pixel-sized skin "names", e.g. "320x480".
-     */
-    public final static Pattern NUMERIC_SKIN_SIZE = Pattern.compile("([0-9]{2,})x([0-9]{2,})"); //$NON-NLS-1$
-
-    private final static String USERDATA_IMG = "userdata.img"; //$NON-NLS-1$
-    private final static String CONFIG_INI = "config.ini"; //$NON-NLS-1$
-    private final static String SDCARD_IMG = "sdcard.img"; //$NON-NLS-1$
-
-    private final static String INI_EXTENSION = ".ini"; //$NON-NLS-1$
-    private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\" + //$NON-NLS-1$
-            INI_EXTENSION + "$",                                               //$NON-NLS-1$
-            Pattern.CASE_INSENSITIVE);
-
-    private final static Pattern IMAGE_NAME_PATTERN = Pattern.compile("(.+)\\.img$", //$NON-NLS-1$
-            Pattern.CASE_INSENSITIVE);
-
-    /**
-     * Pattern for matching SD Card sizes, e.g. "4K" or "16M".
-     */
-    public final static Pattern SDCARD_SIZE_PATTERN = Pattern.compile("\\d+[MK]"); //$NON-NLS-1$
-
-    /** Regex used to validate characters that compose an AVD name. */
-    public final static Pattern RE_AVD_NAME = Pattern.compile("[a-zA-Z0-9._-]+"); //$NON-NLS-1$
-
-    /** List of valid characters for an AVD name. Used for display purposes. */
-    public final static String CHARS_AVD_NAME = "a-z A-Z 0-9 . _ -"; //$NON-NLS-1$
-
-    public final static String HARDWARE_INI = "hardware.ini"; //$NON-NLS-1$
-
-    /** An immutable structure describing an Android Virtual Device. */
-    public static final class AvdInfo {
-
-        /**
-         * Status for an {@link AvdInfo}. Indicates whether or not this AVD is valid.
-         */
-        public static enum AvdStatus {
-            /** No error */
-            OK,
-            /** Missing 'path' property in the ini file */
-            ERROR_PATH,
-            /** Missing config.ini file in the AVD data folder */
-            ERROR_CONFIG,
-            /** Missing 'target' property in the ini file */
-            ERROR_TARGET_HASH,
-            /** Target was not resolved from its hash */
-            ERROR_TARGET,
-            /** Unable to parse config.ini */
-            ERROR_PROPERTIES,
-            /** System Image folder in config.ini doesn't exist */
-            ERROR_IMAGE_DIR;
-        }
-
-        private final String mName;
-        private final String mPath;
-        private final String mTargetHash;
-        private final IAndroidTarget mTarget;
-        private final Map<String, String> mProperties;
-        private final AvdStatus mStatus;
-
-        /**
-         * Creates a new valid AVD info. Values are immutable.
-         * <p/>
-         * Such an AVD is available and can be used.
-         * The error string is set to null.
-         *
-         * @param name The name of the AVD (for display or reference)
-         * @param path The path to the config.ini file
-         * @param targetHash the target hash
-         * @param target The target. Can be null, if the target was not resolved.
-         * @param properties The property map. Cannot be null.
-         */
-        public AvdInfo(String name, String path, String targetHash, IAndroidTarget target,
-                Map<String, String> properties) {
-            this(name, path, targetHash, target, properties, AvdStatus.OK);
-        }
-
-        /**
-         * Creates a new <em>invalid</em> AVD info. Values are immutable.
-         * <p/>
-         * Such an AVD is not complete and cannot be used.
-         * The error string must be non-null.
-         *
-         * @param name The name of the AVD (for display or reference)
-         * @param path The path to the config.ini file
-         * @param targetHash the target hash
-         * @param target The target. Can be null, if the target was not resolved.
-         * @param properties The property map. Can be null.
-         * @param status The {@link AvdStatus} of this AVD. Cannot be null.
-         */
-        public AvdInfo(String name, String path, String targetHash, IAndroidTarget target,
-                Map<String, String> properties, AvdStatus status) {
-            mName = name;
-            mPath = path;
-            mTargetHash = targetHash;
-            mTarget = target;
-            mProperties = properties == null ? null : Collections.unmodifiableMap(properties);
-            mStatus = status;
-        }
-
-        /** Returns the name of the AVD. */
-        public String getName() {
-            return mName;
-        }
-
-        /** Returns the path of the AVD data directory. */
-        public String getPath() {
-            return mPath;
-        }
-
-        /**
-         * Returns the target hash string.
-         */
-        public String getTargetHash() {
-            return mTargetHash;
-        }
-
-        /** Returns the target of the AVD, or <code>null</code> if it has not been resolved. */
-        public IAndroidTarget getTarget() {
-            return mTarget;
-        }
-
-        /** Returns the {@link AvdStatus} of the receiver. */
-        public AvdStatus getStatus() {
-            return mStatus;
-        }
-
-        /**
-         * Helper method that returns the .ini {@link File} for a given AVD name.
-         * @throws AndroidLocationException if there's a problem getting android root directory.
-         */
-        public static File getIniFile(String name) throws AndroidLocationException {
-            String avdRoot;
-            avdRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD;
-            return new File(avdRoot, name + INI_EXTENSION);
-        }
-
-        /**
-         * Returns the .ini {@link File} for this AVD.
-         * @throws AndroidLocationException if there's a problem getting android root directory.
-         */
-        public File getIniFile() throws AndroidLocationException {
-            return getIniFile(mName);
-        }
-
-        /**
-         * Helper method that returns the Config {@link File} for a given AVD name.
-         */
-        public static File getConfigFile(String path) {
-            return new File(path, CONFIG_INI);
-        }
-
-        /**
-         * Returns the Config {@link File} for this AVD.
-         */
-        public File getConfigFile() {
-            return getConfigFile(mPath);
-        }
-
-        /**
-         * Returns an unmodifiable map of properties for the AVD. This can be null.
-         */
-        public Map<String, String> getProperties() {
-            return mProperties;
-        }
-
-        /**
-         * Returns the error message for the AVD or <code>null</code> if {@link #getStatus()}
-         * returns {@link AvdStatus#OK}
-         */
-        public String getErrorMessage() {
-            try {
-                switch (mStatus) {
-                    case ERROR_PATH:
-                        return String.format("Missing AVD 'path' property in %1$s", getIniFile());
-                    case ERROR_CONFIG:
-                        return String.format("Missing config.ini file in %1$s", mPath);
-                    case ERROR_TARGET_HASH:
-                        return String.format("Missing 'target' property in %1$s", getIniFile());
-                    case ERROR_TARGET:
-                        return String.format("Unknown target '%1$s' in %2$s",
-                                mTargetHash, getIniFile());
-                    case ERROR_PROPERTIES:
-                        return String.format("Failed to parse properties from %1$s",
-                                getConfigFile());
-                    case ERROR_IMAGE_DIR:
-                        return String.format(
-                                "Invalid value in image.sysdir. Run 'android update avd -n %1$s'",
-                                mName);
-                    case OK:
-                        assert false;
-                        return null;
-                }
-            } catch (AndroidLocationException e) {
-                return "Unable to get HOME folder.";
-            }
-
-            return null;
-        }
-    }
-
-    private final ArrayList<AvdInfo> mAllAvdList = new ArrayList<AvdInfo>();
-    private AvdInfo[] mValidAvdList;
-    private AvdInfo[] mBrokenAvdList;
-    private final SdkManager mSdkManager;
-
-    /**
-     * Creates an AVD Manager for a given SDK represented by a {@link SdkManager}.
-     * @param sdkManager The SDK.
-     * @param log The log object to receive the log of the initial loading of the AVDs.
-     *            This log object is not kept by this instance of AvdManager and each
-     *            method takes its own logger. The rationale is that the AvdManager
-     *            might be called from a variety of context, each with different
-     *            logging needs.
-     * @throws AndroidLocationException
-     */
-    public AvdManager(SdkManager sdkManager, ISdkLog log) throws AndroidLocationException {
-        mSdkManager = sdkManager;
-        buildAvdList(mAllAvdList, log);
-    }
-
-    /**
-     * Returns the {@link SdkManager} associated with the {@link AvdManager}.
-     */
-    public SdkManager getSdkManager() {
-        return mSdkManager;
-    }
-
-    /**
-     * Returns all the existing AVDs.
-     * @return a newly allocated array containing all the AVDs.
-     */
-    public AvdInfo[] getAllAvds() {
-        synchronized (mAllAvdList) {
-            return mAllAvdList.toArray(new AvdInfo[mAllAvdList.size()]);
-        }
-    }
-
-    /**
-     * Returns all the valid AVDs.
-     * @return a newly allocated array containing all valid the AVDs.
-     */
-    public AvdInfo[] getValidAvds() {
-        synchronized (mAllAvdList) {
-            if (mValidAvdList == null) {
-                ArrayList<AvdInfo> list = new ArrayList<AvdInfo>();
-                for (AvdInfo avd : mAllAvdList) {
-                    if (avd.getStatus() == AvdStatus.OK) {
-                        list.add(avd);
-                    }
-                }
-
-                mValidAvdList = list.toArray(new AvdInfo[list.size()]);
-            }
-            return mValidAvdList;
-        }
-    }
-
-    /**
-     * Returns all the broken AVDs.
-     * @return a newly allocated array containing all the broken AVDs.
-     */
-    public AvdInfo[] getBrokenAvds() {
-        synchronized (mAllAvdList) {
-            if (mBrokenAvdList == null) {
-                ArrayList<AvdInfo> list = new ArrayList<AvdInfo>();
-                for (AvdInfo avd : mAllAvdList) {
-                    if (avd.getStatus() != AvdStatus.OK) {
-                        list.add(avd);
-                    }
-                }
-                mBrokenAvdList = list.toArray(new AvdInfo[list.size()]);
-            }
-            return mBrokenAvdList;
-        }
-    }
-
-    /**
-     * Returns the {@link AvdInfo} matching the given <var>name</var>.
-     * @param name the name of the AVD to return
-     * @param validAvdOnly if <code>true</code>, only look through the list of valid AVDs.
-     * @return the matching AvdInfo or <code>null</code> if none were found.
-     */
-    public AvdInfo getAvd(String name, boolean validAvdOnly) {
-        if (validAvdOnly) {
-            for (AvdInfo info : getValidAvds()) {
-                if (info.getName().equals(name)) {
-                    return info;
-                }
-            }
-        } else {
-            synchronized (mAllAvdList) {
-                for (AvdInfo info : mAllAvdList) {
-                    if (info.getName().equals(name)) {
-                        return info;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Reloads the AVD list.
-     * @param log the log object to receive action logs. Cannot be null.
-     * @throws AndroidLocationException if there was an error finding the location of the
-     * AVD folder.
-     */
-    public void reloadAvds(ISdkLog log) throws AndroidLocationException {
-        // build the list in a temp list first, in case the method throws an exception.
-        // It's better than deleting the whole list before reading the new one.
-        ArrayList<AvdInfo> allList = new ArrayList<AvdInfo>();
-        buildAvdList(allList, log);
-
-        synchronized (mAllAvdList) {
-            mAllAvdList.clear();
-            mAllAvdList.addAll(allList);
-            mValidAvdList = mBrokenAvdList = null;
-        }
-    }
-
-    /**
-     * Creates a new AVD. It is expected that there is no existing AVD with this name already.
-     *
-     * @param avdFolder the data folder for the AVD. It will be created as needed.
-     * @param name the name of the AVD
-     * @param target the target of the AVD
-     * @param skinName the name of the skin. Can be null. Must have been verified by caller.
-     * @param sdcard the parameter value for the sdCard. Can be null. This is either a path to
-     *        an existing sdcard image or a sdcard size (\d+, \d+K, \dM).
-     * @param hardwareConfig the hardware setup for the AVD. Can be null to use defaults.
-     * @param removePrevious If true remove any previous files.
-     * @param log the log object to receive action logs. Cannot be null.
-     * @return The new {@link AvdInfo} in case of success (which has just been added to the
-     *         internal list) or null in case of failure.
-     */
-    public AvdInfo createAvd(File avdFolder, String name, IAndroidTarget target,
-            String skinName, String sdcard, Map<String,String> hardwareConfig,
-            boolean removePrevious, ISdkLog log) {
-        if (log == null) {
-            throw new IllegalArgumentException("log cannot be null");
-        }
-
-        File iniFile = null;
-        boolean needCleanup = false;
-        try {
-            if (avdFolder.exists()) {
-                if (removePrevious) {
-                    // AVD already exists and removePrevious is set, try to remove the
-                    // directory's content first (but not the directory itself).
-                    recursiveDelete(avdFolder);
-                } else {
-                    // AVD shouldn't already exist if removePrevious is false.
-                    log.error(null,
-                            "Folder %1$s is in the way. Use --force if you want to overwrite.",
-                            avdFolder.getAbsolutePath());
-                    return null;
-                }
-            } else {
-                // create the AVD folder.
-                avdFolder.mkdir();
-            }
-
-            // actually write the ini file
-            iniFile = createAvdIniFile(name, avdFolder, target);
-
-            // writes the userdata.img in it.
-            String imagePath = target.getPath(IAndroidTarget.IMAGES);
-            File userdataSrc = new File(imagePath, USERDATA_IMG);
-
-            if (userdataSrc.exists() == false && target.isPlatform() == false) {
-                imagePath = target.getParent().getPath(IAndroidTarget.IMAGES);
-                userdataSrc = new File(imagePath, USERDATA_IMG);
-            }
-
-            if (userdataSrc.exists() == false) {
-                log.error(null, "Unable to find a '%1$s' file to copy into the AVD folder.",
-                        USERDATA_IMG);
-                needCleanup = true;
-                return null;
-            }
-
-            FileInputStream fis = new FileInputStream(userdataSrc);
-
-            File userdataDest = new File(avdFolder, USERDATA_IMG);
-            FileOutputStream fos = new FileOutputStream(userdataDest);
-
-            byte[] buffer = new byte[4096];
-            int count;
-            while ((count = fis.read(buffer)) != -1) {
-                fos.write(buffer, 0, count);
-            }
-
-            fos.close();
-            fis.close();
-
-            // Config file.
-            HashMap<String, String> values = new HashMap<String, String>();
-
-            if (setImagePathProperties(target, values, log) == false) {
-                needCleanup = true;
-                return null;
-            }
-
-            // Now the skin.
-            if (skinName == null || skinName.length() == 0) {
-                skinName = target.getDefaultSkin();
-            }
-
-            if (NUMERIC_SKIN_SIZE.matcher(skinName).matches()) {
-                // Skin name is an actual screen resolution.
-                // Set skin.name for display purposes in the AVD manager and
-                // set skin.path for use by the emulator.
-                values.put(AVD_INI_SKIN_NAME, skinName);
-                values.put(AVD_INI_SKIN_PATH, skinName);
-            } else {
-                // get the path of the skin (relative to the SDK)
-                // assume skin name is valid
-                String skinPath = getSkinRelativePath(skinName, target, log);
-                if (skinPath == null) {
-                    needCleanup = true;
-                    return null;
-                }
-
-                values.put(AVD_INI_SKIN_PATH, skinPath);
-                values.put(AVD_INI_SKIN_NAME, skinName);
-            }
-
-            if (sdcard != null && sdcard.length() > 0) {
-                File sdcardFile = new File(sdcard);
-                if (sdcardFile.isFile()) {
-                    // sdcard value is an external sdcard, so we put its path into the config.ini
-                    values.put(AVD_INI_SDCARD_PATH, sdcard);
-                } else {
-                    // Sdcard is possibly a size. In that case we create a file called 'sdcard.img'
-                    // in the AVD folder, and do not put any value in config.ini.
-
-                    // First, check that it matches the pattern for sdcard size
-                    Matcher m = SDCARD_SIZE_PATTERN.matcher(sdcard);
-                    if (m.matches()) {
-                        // create the sdcard.
-                        sdcardFile = new File(avdFolder, SDCARD_IMG);
-                        String path = sdcardFile.getAbsolutePath();
-
-                        // execute mksdcard with the proper parameters.
-                        File toolsFolder = new File(mSdkManager.getLocation(),
-                                SdkConstants.FD_TOOLS);
-                        File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName());
-
-                        if (mkSdCard.isFile() == false) {
-                            log.error(null, "'%1$s' is missing from the SDK tools folder.",
-                                    mkSdCard.getName());
-                            needCleanup = true;
-                            return null;
-                        }
-
-                        if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path, log) == false) {
-                            needCleanup = true;
-                            return null; // mksdcard output has already been displayed, no need to
-                                         // output anything else.
-                        }
-
-                        // add a property containing the size of the sdcard for display purpose
-                        // only when the dev does 'android list avd'
-                        values.put(AVD_INI_SDCARD_SIZE, sdcard);
-                    } else {
-                        log.error(null,
-                                "'%1$s' is not recognized as a valid sdcard value.\n" +
-                                "Value should be:\n" +
-                                "1. path to an sdcard.\n" +
-                                "2. size of the sdcard to create: <size>[K|M]",
-                                sdcard);
-                        needCleanup = true;
-                        return null;
-                    }
-                }
-            }
-
-            // add the hardware config to the config file.
-            // priority order is:
-            // - values provided by the user
-            // - values provided by the skin
-            // - values provided by the target (add-on only).
-            // In order to follow this priority, we'll add the lowest priority values first and then
-            // override by higher priority values.
-            // In the case of a platform with override values from the user, the skin value might
-            // already be there, but it's ok.
-
-            HashMap<String, String> finalHardwareValues = new HashMap<String, String>();
-
-            File targetHardwareFile = new File(target.getLocation(), AvdManager.HARDWARE_INI);
-            if (targetHardwareFile.isFile()) {
-                Map<String, String> targetHardwareConfig = SdkManager.parsePropertyFile(
-                        targetHardwareFile, log);
-                if (targetHardwareConfig != null) {
-                    finalHardwareValues.putAll(targetHardwareConfig);
-                    values.putAll(targetHardwareConfig);
-                }
-            }
-
-            // get the hardware properties for this skin
-            File skinFolder = getSkinPath(skinName, target);
-            File skinHardwareFile = new File(skinFolder, AvdManager.HARDWARE_INI);
-            if (skinHardwareFile.isFile()) {
-                Map<String, String> skinHardwareConfig = SdkManager.parsePropertyFile(
-                        skinHardwareFile, log);
-                if (skinHardwareConfig != null) {
-                    finalHardwareValues.putAll(skinHardwareConfig);
-                    values.putAll(skinHardwareConfig);
-                }
-            }
-
-            // finally put the hardware provided by the user.
-            if (hardwareConfig != null) {
-                finalHardwareValues.putAll(hardwareConfig);
-                values.putAll(hardwareConfig);
-            }
-
-            File configIniFile = new File(avdFolder, CONFIG_INI);
-            writeIniFile(configIniFile, values);
-
-            if (target.isPlatform()) {
-                log.printf("Created AVD '%1$s' based on %2$s", name, target.getName());
-            } else {
-                log.printf("Created AVD '%1$s' based on %2$s (%3$s)", name,
-                        target.getName(), target.getVendor());
-            }
-
-            // display the chosen hardware config
-            if (finalHardwareValues.size() > 0) {
-                log.printf(", with the following hardware config:\n");
-                for (Entry<String, String> entry : finalHardwareValues.entrySet()) {
-                    log.printf("%s=%s\n",entry.getKey(), entry.getValue());
-                }
-            } else {
-                log.printf("\n");
-            }
-
-            // create the AvdInfo object, and add it to the list
-            AvdInfo newAvdInfo = new AvdInfo(name,
-                    avdFolder.getAbsolutePath(),
-                    target.hashString(),
-                    target, values);
-
-            AvdInfo oldAvdInfo = getAvd(name, false /*validAvdOnly*/);
-
-            synchronized (mAllAvdList) {
-                if (oldAvdInfo != null && removePrevious) {
-                    mAllAvdList.remove(oldAvdInfo);
-                }
-                mAllAvdList.add(newAvdInfo);
-                mValidAvdList = mBrokenAvdList = null;
-            }
-
-            if (removePrevious &&
-                    newAvdInfo != null &&
-                    oldAvdInfo != null &&
-                    !oldAvdInfo.getPath().equals(newAvdInfo.getPath())) {
-                log.warning("Removing previous AVD directory at %s", oldAvdInfo.getPath());
-                // Remove the old data directory
-                File dir = new File(oldAvdInfo.getPath());
-                recursiveDelete(dir);
-                dir.delete();
-            }
-
-            return newAvdInfo;
-        } catch (AndroidLocationException e) {
-            log.error(e, null);
-        } catch (IOException e) {
-            log.error(e, null);
-        } finally {
-            if (needCleanup) {
-                if (iniFile != null && iniFile.exists()) {
-                    iniFile.delete();
-                }
-
-                recursiveDelete(avdFolder);
-                avdFolder.delete();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the path to the target images folder as a relative path to the SDK, if the folder
-     * is not empty. If the image folder is empty or does not exist, <code>null</code> is returned.
-     * @throws InvalidTargetPathException if the target image folder is not in the current SDK.
-     */
-    private String getImageRelativePath(IAndroidTarget target)
-            throws InvalidTargetPathException {
-        String imageFullPath = target.getPath(IAndroidTarget.IMAGES);
-
-        // make this path relative to the SDK location
-        String sdkLocation = mSdkManager.getLocation();
-        if (imageFullPath.startsWith(sdkLocation) == false) {
-            // this really really should not happen.
-            assert false;
-            throw new InvalidTargetPathException("Target location is not inside the SDK.");
-        }
-
-        File folder = new File(imageFullPath);
-        if (folder.isDirectory()) {
-            String[] list = folder.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
-                    return IMAGE_NAME_PATTERN.matcher(name).matches();
-                }
-            });
-
-            if (list.length > 0) {
-                imageFullPath = imageFullPath.substring(sdkLocation.length());
-                if (imageFullPath.charAt(0) == File.separatorChar) {
-                    imageFullPath = imageFullPath.substring(1);
-                }
-
-                return imageFullPath;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the path to the skin, as a relative path to the SDK.
-     * @param skinName The name of the skin to find. Case-sensitive.
-     * @param target The target where to find the skin.
-     * @param log the log object to receive action logs. Cannot be null.
-     */
-    public String getSkinRelativePath(String skinName, IAndroidTarget target, ISdkLog log) {
-        if (log == null) {
-            throw new IllegalArgumentException("log cannot be null");
-        }
-
-        // first look to see if the skin is in the target
-        File skin = getSkinPath(skinName, target);
-
-        // skin really does not exist!
-        if (skin.exists() == false) {
-            log.error(null, "Skin '%1$s' does not exist.", skinName);
-            return null;
-        }
-
-        // get the skin path
-        String path = skin.getAbsolutePath();
-
-        // make this path relative to the SDK location
-        String sdkLocation = mSdkManager.getLocation();
-        if (path.startsWith(sdkLocation) == false) {
-            // this really really should not happen.
-            log.error(null, "Target location is not inside the SDK.");
-            assert false;
-            return null;
-        }
-
-        path = path.substring(sdkLocation.length());
-        if (path.charAt(0) == File.separatorChar) {
-            path = path.substring(1);
-        }
-        return path;
-    }
-
-    /**
-     * Returns the full absolute OS path to a skin specified by name for a given target.
-     * @param skinName The name of the skin to find. Case-sensitive.
-     * @param target The target where to find the skin.
-     * @return a {@link File} that may or may not actually exist.
-     */
-    public File getSkinPath(String skinName, IAndroidTarget target) {
-        String path = target.getPath(IAndroidTarget.SKINS);
-        File skin = new File(path, skinName);
-
-        if (skin.exists() == false && target.isPlatform() == false) {
-            target = target.getParent();
-
-            path = target.getPath(IAndroidTarget.SKINS);
-            skin = new File(path, skinName);
-        }
-
-        return skin;
-    }
-
-    /**
-     * Creates the ini file for an AVD.
-     *
-     * @param name of the AVD.
-     * @param avdFolder path for the data folder of the AVD.
-     * @param target of the AVD.
-     * @throws AndroidLocationException if there's a problem getting android root directory.
-     * @throws IOException if {@link File#getAbsolutePath()} fails.
-     */
-    private File createAvdIniFile(String name, File avdFolder, IAndroidTarget target)
-            throws AndroidLocationException, IOException {
-        HashMap<String, String> values = new HashMap<String, String>();
-        File iniFile = AvdInfo.getIniFile(name);
-        values.put(AVD_INFO_PATH, avdFolder.getAbsolutePath());
-        values.put(AVD_INFO_TARGET, target.hashString());
-        writeIniFile(iniFile, values);
-
-        return iniFile;
-    }
-
-    /**
-     * Creates the ini file for an AVD.
-     *
-     * @param info of the AVD.
-     * @throws AndroidLocationException if there's a problem getting android root directory.
-     * @throws IOException if {@link File#getAbsolutePath()} fails.
-     */
-    private File createAvdIniFile(AvdInfo info) throws AndroidLocationException, IOException {
-        return createAvdIniFile(info.getName(), new File(info.getPath()), info.getTarget());
-    }
-
-    /**
-     * Actually deletes the files of an existing AVD.
-     * <p/>
-     * This also remove it from the manager's list, The caller does not need to
-     * call {@link #removeAvd(AvdInfo)} afterwards.
-     * <p/>
-     * This method is designed to somehow work with an unavailable AVD, that is an AVD that
-     * could not be loaded due to some error. That means this method still tries to remove
-     * the AVD ini file or its folder if it can be found. An error will be output if any of
-     * these operations fail.
-     *
-     * @param avdInfo the information on the AVD to delete
-     * @param log the log object to receive action logs. Cannot be null.
-     * @return True if the AVD was deleted with no error.
-     */
-    public boolean deleteAvd(AvdInfo avdInfo, ISdkLog log) {
-        try {
-            boolean error = false;
-
-            File f = avdInfo.getIniFile();
-            if (f != null && f.exists()) {
-                log.printf("Deleting file %1$s\n", f.getCanonicalPath());
-                if (!f.delete()) {
-                    log.error(null, "Failed to delete %1$s\n", f.getCanonicalPath());
-                    error = true;
-                }
-            }
-
-            String path = avdInfo.getPath();
-            if (path != null) {
-                f = new File(path);
-                if (f.exists()) {
-                    log.printf("Deleting folder %1$s\n", f.getCanonicalPath());
-                    recursiveDelete(f);
-                    if (!f.delete()) {
-                        log.error(null, "Failed to delete %1$s\n", f.getCanonicalPath());
-                        error = true;
-                    }
-                }
-            }
-
-            removeAvd(avdInfo);
-
-            if (error) {
-                log.printf("\nAVD '%1$s' deleted with errors. See errors above.\n",
-                        avdInfo.getName());
-            } else {
-                log.printf("\nAVD '%1$s' deleted.\n", avdInfo.getName());
-                return true;
-            }
-
-        } catch (AndroidLocationException e) {
-            log.error(e, null);
-        } catch (IOException e) {
-            log.error(e, null);
-        }
-        return false;
-    }
-
-    /**
-     * Moves and/or rename an existing AVD and its files.
-     * This also change it in the manager's list.
-     * <p/>
-     * The caller should make sure the name or path given are valid, do not exist and are
-     * actually different than current values.
-     *
-     * @param avdInfo the information on the AVD to move.
-     * @param newName the new name of the AVD if non null.
-     * @param paramFolderPath the new data folder if non null.
-     * @param log the log object to receive action logs. Cannot be null.
-     * @return True if the move succeeded or there was nothing to do.
-     *         If false, this method will have had already output error in the log.
-     */
-    public boolean moveAvd(AvdInfo avdInfo, String newName, String paramFolderPath, ISdkLog log) {
-
-        try {
-            if (paramFolderPath != null) {
-                File f = new File(avdInfo.getPath());
-                log.warning("Moving '%1$s' to '%2$s'.", avdInfo.getPath(), paramFolderPath);
-                if (!f.renameTo(new File(paramFolderPath))) {
-                    log.error(null, "Failed to move '%1$s' to '%2$s'.",
-                            avdInfo.getPath(), paramFolderPath);
-                    return false;
-                }
-
-                // update AVD info
-                AvdInfo info = new AvdInfo(avdInfo.getName(), paramFolderPath,
-                        avdInfo.getTargetHash(), avdInfo.getTarget(), avdInfo.getProperties());
-                replaceAvd(avdInfo, info);
-
-                // update the ini file
-                createAvdIniFile(info);
-            }
-
-            if (newName != null) {
-                File oldIniFile = avdInfo.getIniFile();
-                File newIniFile = AvdInfo.getIniFile(newName);
-
-                log.warning("Moving '%1$s' to '%2$s'.", oldIniFile.getPath(), newIniFile.getPath());
-                if (!oldIniFile.renameTo(newIniFile)) {
-                    log.error(null, "Failed to move '%1$s' to '%2$s'.",
-                            oldIniFile.getPath(), newIniFile.getPath());
-                    return false;
-                }
-
-                // update AVD info
-                AvdInfo info = new AvdInfo(newName, avdInfo.getPath(),
-                        avdInfo.getTargetHash(), avdInfo.getTarget(), avdInfo.getProperties());
-                replaceAvd(avdInfo, info);
-            }
-
-            log.printf("AVD '%1$s' moved.\n", avdInfo.getName());
-
-        } catch (AndroidLocationException e) {
-            log.error(e, null);
-        } catch (IOException e) {
-            log.error(e, null);
-        }
-
-        // nothing to do or succeeded
-        return true;
-    }
-
-    /**
-     * Helper method to recursively delete a folder's content (but not the folder itself).
-     *
-     * @throws SecurityException like {@link File#delete()} does if file/folder is not writable.
-     */
-    public void recursiveDelete(File folder) {
-        for (File f : folder.listFiles()) {
-            if (f.isDirectory()) {
-                recursiveDelete(folder);
-            }
-            f.delete();
-        }
-    }
-
-    /**
-     * Returns a list of files that are potential AVD ini files.
-     * <p/>
-     * This lists the $HOME/.android/avd/<name>.ini files.
-     * Such files are properties file than then indicate where the AVD folder is located.
-     *
-     * @return A new {@link File} array or null. The array might be empty.
-     * @throws AndroidLocationException if there's a problem getting android root directory.
-     */
-    private File[] buildAvdFilesList() throws AndroidLocationException {
-        // get the Android prefs location.
-        String avdRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD;
-
-        // ensure folder validity.
-        File folder = new File(avdRoot);
-        if (folder.isFile()) {
-            throw new AndroidLocationException(
-                    String.format("%1$s is not a valid folder.", avdRoot));
-        } else if (folder.exists() == false) {
-            // folder is not there, we create it and return
-            folder.mkdirs();
-            return null;
-        }
-
-        File[] avds = folder.listFiles(new FilenameFilter() {
-            public boolean accept(File parent, String name) {
-                if (INI_NAME_PATTERN.matcher(name).matches()) {
-                    // check it's a file and not a folder
-                    boolean isFile = new File(parent, name).isFile();
-                    return isFile;
-                }
-
-                return false;
-            }
-        });
-
-        return avds;
-    }
-
-    /**
-     * Computes the internal list of available AVDs
-     * @param allList the list to contain all the AVDs
-     * @param log the log object to receive action logs. Cannot be null.
-     *
-     * @throws AndroidLocationException if there's a problem getting android root directory.
-     */
-    private void buildAvdList(ArrayList<AvdInfo> allList, ISdkLog log)
-            throws AndroidLocationException {
-        File[] avds = buildAvdFilesList();
-        if (avds != null) {
-            for (File avd : avds) {
-                AvdInfo info = parseAvdInfo(avd, log);
-                if (info != null) {
-                    allList.add(info);
-                }
-            }
-        }
-    }
-
-    /**
-     * Parses an AVD .ini file to create an {@link AvdInfo}.
-     *
-     * @param path The path to the AVD .ini file
-     * @param log the log object to receive action logs. Cannot be null.
-     * @return A new {@link AvdInfo} with an {@link AvdStatus} indicating whether this AVD is
-     *         valid or not.
-     */
-    private AvdInfo parseAvdInfo(File path, ISdkLog log) {
-        Map<String, String> map = SdkManager.parsePropertyFile(path, log);
-
-        String avdPath = map.get(AVD_INFO_PATH);
-        String targetHash = map.get(AVD_INFO_TARGET);
-
-        IAndroidTarget target = null;
-        File configIniFile = null;
-        Map<String, String> properties = null;
-
-        if (targetHash != null) {
-            target = mSdkManager.getTargetFromHashString(targetHash);
-        }
-
-        // load the AVD properties.
-        if (avdPath != null) {
-            configIniFile = new File(avdPath, CONFIG_INI);
-        }
-
-        if (configIniFile != null) {
-            if (!configIniFile.isFile()) {
-                if (log != null) {
-                    log.warning("Missing file '%1$s'.",  configIniFile.getPath());
-                }
-            } else {
-                properties = SdkManager.parsePropertyFile(configIniFile, log);
-            }
-        }
-
-        // get name
-        String name = path.getName();
-        Matcher matcher = INI_NAME_PATTERN.matcher(path.getName());
-        if (matcher.matches()) {
-            name = matcher.group(1);
-        }
-
-        // check the image.sysdir are valid
-        boolean validImageSysdir = true;
-        if (properties != null) {
-            String imageSysDir = properties.get(AVD_INI_IMAGES_1);
-            if (imageSysDir != null) {
-                File f = new File(mSdkManager.getLocation() + File.separator + imageSysDir);
-                if (f.isDirectory() == false) {
-                    validImageSysdir = false;
-                } else {
-                    imageSysDir = properties.get(AVD_INI_IMAGES_2);
-                    if (imageSysDir != null) {
-                        f = new File(mSdkManager.getLocation() + File.separator + imageSysDir);
-                        if (f.isDirectory() == false) {
-                            validImageSysdir = false;
-                        }
-                    }
-                }
-            }
-        }
-
-        AvdStatus status;
-
-        if (avdPath == null) {
-            status = AvdStatus.ERROR_PATH;
-        } else if (configIniFile == null) {
-            status = AvdStatus.ERROR_CONFIG;
-        } else if (targetHash == null) {
-            status = AvdStatus.ERROR_TARGET_HASH;
-        } else if (target == null) {
-            status = AvdStatus.ERROR_TARGET;
-        } else if (properties == null) {
-            status = AvdStatus.ERROR_PROPERTIES;
-        } else if (validImageSysdir == false) {
-            status = AvdStatus.ERROR_IMAGE_DIR;
-        } else {
-            status = AvdStatus.OK;
-        }
-
-        AvdInfo info = new AvdInfo(
-                name,
-                avdPath,
-                targetHash,
-                target,
-                properties,
-                status);
-
-        return info;
-    }
-
-    /**
-     * Writes a .ini file from a set of properties, using UTF-8 encoding.
-     *
-     * @param iniFile The file to generate.
-     * @param values THe properties to place in the ini file.
-     * @throws IOException if {@link FileWriter} fails to open, write or close the file.
-     */
-    private static void writeIniFile(File iniFile, Map<String, String> values)
-            throws IOException {
-        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(iniFile),
-                SdkConstants.INI_CHARSET);
-
-        for (Entry<String, String> entry : values.entrySet()) {
-            writer.write(String.format("%1$s=%2$s\n", entry.getKey(), entry.getValue()));
-        }
-        writer.close();
-    }
-
-    /**
-     * Invokes the tool to create a new SD card image file.
-     *
-     * @param toolLocation The path to the mksdcard tool.
-     * @param size The size of the new SD Card, compatible with {@link #SDCARD_SIZE_PATTERN}.
-     * @param location The path of the new sdcard image file to generate.
-     * @param log the log object to receive action logs. Cannot be null.
-     * @return True if the sdcard could be created.
-     */
-    private boolean createSdCard(String toolLocation, String size, String location, ISdkLog log) {
-        try {
-            String[] command = new String[3];
-            command[0] = toolLocation;
-            command[1] = size;
-            command[2] = location;
-            Process process = Runtime.getRuntime().exec(command);
-
-            ArrayList<String> errorOutput = new ArrayList<String>();
-            ArrayList<String> stdOutput = new ArrayList<String>();
-            int status = grabProcessOutput(process, errorOutput, stdOutput,
-                    true /* waitForReaders */);
-
-            if (status == 0) {
-                return true;
-            } else {
-                for (String error : errorOutput) {
-                    log.error(null, error);
-                }
-            }
-
-        } catch (InterruptedException e) {
-            // pass, print error below
-        } catch (IOException e) {
-            // pass, print error below
-        }
-
-        log.error(null, "Failed to create the SD card.");
-        return false;
-    }
-
-    /**
-     * Gets the stderr/stdout outputs of a process and returns when the process is done.
-     * Both <b>must</b> be read or the process will block on windows.
-     * @param process The process to get the ouput from
-     * @param errorOutput The array to store the stderr output. cannot be null.
-     * @param stdOutput The array to store the stdout output. cannot be null.
-     * @param waitforReaders if true, this will wait for the reader threads.
-     * @return the process return code.
-     * @throws InterruptedException
-     */
-    private int grabProcessOutput(final Process process, final ArrayList<String> errorOutput,
-            final ArrayList<String> stdOutput, boolean waitforReaders)
-            throws InterruptedException {
-        assert errorOutput != null;
-        assert stdOutput != null;
-        // read the lines as they come. if null is returned, it's
-        // because the process finished
-        Thread t1 = new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            errorOutput.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        Thread t2 = new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            stdOutput.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        t1.start();
-        t2.start();
-
-        // it looks like on windows process#waitFor() can return
-        // before the thread have filled the arrays, so we wait for both threads and the
-        // process itself.
-        if (waitforReaders) {
-            try {
-                t1.join();
-            } catch (InterruptedException e) {
-                // nothing to do here
-            }
-            try {
-                t2.join();
-            } catch (InterruptedException e) {
-                // nothing to do here
-            }
-        }
-
-        // get the return code from the process
-        return process.waitFor();
-    }
-
-    /**
-     * Removes an {@link AvdInfo} from the internal list.
-     *
-     * @param avdInfo The {@link AvdInfo} to remove.
-     * @return true if this {@link AvdInfo} was present and has been removed.
-     */
-    public boolean removeAvd(AvdInfo avdInfo) {
-        synchronized (mAllAvdList) {
-            if (mAllAvdList.remove(avdInfo)) {
-                mValidAvdList = mBrokenAvdList = null;
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Updates an AVD with new path to the system image folders.
-     * @param name the name of the AVD to update.
-     * @param log the log object to receive action logs. Cannot be null.
-     * @throws IOException
-     */
-    public void updateAvd(String name, ISdkLog log) throws IOException {
-        // find the AVD to update. It should be be in the broken list.
-        AvdInfo avd = null;
-        synchronized (mAllAvdList) {
-            for (AvdInfo info : mAllAvdList) {
-                if (info.getName().equals(name)) {
-                    avd = info;
-                    break;
-                }
-            }
-        }
-
-        if (avd == null) {
-            // not in the broken list, just return.
-            log.error(null, "There is no Android Virtual Device named '%s'.", name);
-            return;
-        }
-
-        updateAvd(avd, log);
-    }
-
-
-    /**
-     * Updates an AVD with new path to the system image folders.
-     * @param avd the AVD to update.
-     * @param log the log object to receive action logs. Cannot be null.
-     * @throws IOException
-     */
-    public void updateAvd(AvdInfo avd, ISdkLog log) throws IOException {
-        // get the properties. This is a unmodifiable Map.
-        Map<String, String> oldProperties = avd.getProperties();
-
-        // create a new map
-        Map<String, String> properties = new HashMap<String, String>();
-        if (oldProperties != null) {
-            properties.putAll(oldProperties);
-        }
-
-        AvdStatus status;
-
-        // create the path to the new system images.
-        if (setImagePathProperties(avd.getTarget(), properties, log)) {
-            if (properties.containsKey(AVD_INI_IMAGES_1)) {
-                log.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_1,
-                        properties.get(AVD_INI_IMAGES_1));
-            }
-
-            if (properties.containsKey(AVD_INI_IMAGES_2)) {
-                log.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_2,
-                        properties.get(AVD_INI_IMAGES_2));
-            }
-
-            status = AvdStatus.OK;
-        } else {
-            log.error(null, "Unable to find non empty system images folders for %1$s",
-                    avd.getName());
-            //FIXME: display paths to empty image folders?
-            status = AvdStatus.ERROR_IMAGE_DIR;
-        }
-
-        // now write the config file
-        File configIniFile = new File(avd.getPath(), CONFIG_INI);
-        writeIniFile(configIniFile, properties);
-
-        // finally create a new AvdInfo for this unbroken avd and add it to the list.
-        // instead of creating the AvdInfo object directly we reparse it, to detect other possible
-        // errors
-        // FIXME: We may want to create this AvdInfo by reparsing the AVD instead. This could detect other errors.
-        AvdInfo newAvd = new AvdInfo(
-                avd.getName(),
-                avd.getPath(),
-                avd.getTargetHash(),
-                avd.getTarget(),
-                properties,
-                status);
-
-        replaceAvd(avd, newAvd);
-    }
-
-    /**
-     * Sets the paths to the system images in a properties map.
-     * @param target the target in which to find the system images.
-     * @param properties the properties in which to set the paths.
-     * @param log the log object to receive action logs. Cannot be null.
-     * @return true if success, false if some path are missing.
-     */
-    private boolean setImagePathProperties(IAndroidTarget target,
-            Map<String, String> properties,
-            ISdkLog log) {
-        properties.remove(AVD_INI_IMAGES_1);
-        properties.remove(AVD_INI_IMAGES_2);
-
-        try {
-            String property = AVD_INI_IMAGES_1;
-
-            // First the image folders of the target itself
-            String imagePath = getImageRelativePath(target);
-            if (imagePath != null) {
-                properties.put(property, imagePath);
-                property = AVD_INI_IMAGES_2;
-            }
-
-
-            // If the target is an add-on we need to add the Platform image as a backup.
-            IAndroidTarget parent = target.getParent();
-            if (parent != null) {
-                imagePath = getImageRelativePath(parent);
-                if (imagePath != null) {
-                    properties.put(property, imagePath);
-                }
-            }
-
-            // we need at least one path!
-            return properties.containsKey(AVD_INI_IMAGES_1);
-        } catch (InvalidTargetPathException e) {
-            log.error(e, e.getMessage());
-        }
-
-        return false;
-    }
-
-    /**
-     * Replaces an old {@link AvdInfo} with a new one in the lists storing them.
-     * @param oldAvd the {@link AvdInfo} to remove.
-     * @param newAvd the {@link AvdInfo} to add.
-     */
-    private void replaceAvd(AvdInfo oldAvd, AvdInfo newAvd) {
-        synchronized (mAllAvdList) {
-            mAllAvdList.remove(oldAvd);
-            mAllAvdList.add(newAvd);
-            mValidAvdList = mBrokenAvdList = null;
-        }
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/HardwareProperties.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/HardwareProperties.java
deleted file mode 100644
index 77142b1..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/HardwareProperties.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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.android.sdklib.internal.avd;
-
-import com.android.sdklib.ISdkLog;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class HardwareProperties {
-    private final static Pattern PATTERN_PROP = Pattern.compile(
-    "^([a-zA-Z0-9._-]+)\\s*=\\s*(.*)\\s*$");
-
-    private final static String HW_PROP_NAME = "name";
-    private final static String HW_PROP_TYPE = "type";
-    private final static String HW_PROP_DEFAULT = "default";
-    private final static String HW_PROP_ABSTRACT = "abstract";
-    private final static String HW_PROP_DESC = "description";
-
-    private final static String BOOLEAN_YES = "yes";
-    private final static String BOOLEAN_NO = "no";
-    public final static String[] BOOLEAN_VALUES = new String[] { BOOLEAN_YES, BOOLEAN_NO };
-    public final static Pattern DISKSIZE_PATTERN = Pattern.compile("\\d+[MK]B");
-
-    public enum ValueType {
-        INTEGER("integer"),
-        BOOLEAN("boolean"),
-        DISKSIZE("diskSize");
-
-        private String mValue;
-
-        ValueType(String value) {
-            mValue = value;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-
-        public static ValueType getEnum(String value) {
-            for (ValueType type : values()) {
-                if (type.mValue.equals(value)) {
-                    return type;
-                }
-            }
-
-            return null;
-        }
-    }
-
-    public static final class HardwareProperty {
-        private String mName;
-        private ValueType mType;
-        /** the string representation of the default value. can be null. */
-        private String mDefault;
-        private String mAbstract;
-        private String mDescription;
-
-        public String getName() {
-            return mName;
-        }
-
-        public ValueType getType() {
-            return mType;
-        }
-
-        public String getDefault() {
-            return mDefault;
-        }
-
-        public String getAbstract() {
-            return mAbstract;
-        }
-
-        public String getDescription() {
-            return mDescription;
-        }
-    }
-
-    /**
-     * Parses the hardware definition file.
-     * @param file the property file to parse
-     * @param log the ISdkLog object receiving warning/error from the parsing.
-     * @return the map of (key,value) pairs, or null if the parsing failed.
-     */
-    public static Map<String, HardwareProperty> parseHardwareDefinitions(File file, ISdkLog log) {
-        try {
-            FileInputStream fis = new FileInputStream(file);
-            BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
-
-            Map<String, HardwareProperty> map = new HashMap<String, HardwareProperty>();
-
-            String line = null;
-            HardwareProperty prop = null;
-            while ((line = reader.readLine()) != null) {
-                if (line.length() > 0 && line.charAt(0) != '#') {
-                    Matcher m = PATTERN_PROP.matcher(line);
-                    if (m.matches()) {
-                        String valueName = m.group(1);
-                        String value = m.group(2);
-
-                        if (HW_PROP_NAME.equals(valueName)) {
-                            prop = new HardwareProperty();
-                            prop.mName = value;
-                            map.put(prop.mName, prop);
-                        }
-
-                        if (prop == null) {
-                            log.warning("Error parsing '%1$s': missing '%2$s'",
-                                    file.getAbsolutePath(), HW_PROP_NAME);
-                            return null;
-                        }
-
-                        if (HW_PROP_TYPE.equals(valueName)) {
-                            prop.mType = ValueType.getEnum(value);
-                        } else if (HW_PROP_DEFAULT.equals(valueName)) {
-                            prop.mDefault = value;
-                        } else if (HW_PROP_ABSTRACT.equals(valueName)) {
-                            prop.mAbstract = value;
-                        } else if (HW_PROP_DESC.equals(valueName)) {
-                            prop.mDescription = value;
-                        }
-                    } else {
-                        log.warning("Error parsing '%1$s': \"%2$s\" is not a valid syntax",
-                                file.getAbsolutePath(), line);
-                        return null;
-                    }
-                }
-            }
-
-            return map;
-        } catch (FileNotFoundException e) {
-            // this should not happen since we usually test the file existence before
-            // calling the method.
-            // Return null below.
-        } catch (IOException e) {
-            if (log != null) {
-                log.warning("Error parsing '%1$s': %2$s.", file.getAbsolutePath(),
-                        e.getMessage());
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the index of <var>value</var> in {@link #BOOLEAN_VALUES}.
-     */
-    public static int getBooleanValueIndex(String value) {
-        if (BOOLEAN_YES.equals(value)) {
-            return 0;
-        } else if (BOOLEAN_NO.equals(value)) {
-            return 1;
-        }
-
-        return -1;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java
deleted file mode 100644
index 4ba6fa6..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.project;
-
-
-/**
- * Helper class to read and write Apk Configuration into a {@link ProjectProperties} file.
- */
-public class ApkConfigurationHelper {
-    /**
-     * Reads the project settings from a {@link ProjectProperties} file and returns them as a
-     * {@link ApkSettings} object.
-     */
-    public static ApkSettings getSettings(ProjectProperties properties) {
-        ApkSettings apkSettings = new ApkSettings();
-
-        boolean splitByDensity = Boolean.parseBoolean(properties.getProperty(
-                ProjectProperties.PROPERTY_SPLIT_BY_DENSITY));
-        apkSettings.setSplitByDensity(splitByDensity);
-
-
-        return apkSettings;
-    }
-
-    /**
-     * Sets the content of a {@link ApkSettings} into a {@link ProjectProperties}.
-     * @param properties the {@link ProjectProperties} in which to store the settings.
-     * @param settings the project settings to store.
-     */
-    public static void setProperties(ProjectProperties properties, ApkSettings settings) {
-        properties.setProperty(ProjectProperties.PROPERTY_SPLIT_BY_DENSITY,
-                Boolean.toString(settings.isSplitByDpi()));
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkSettings.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkSettings.java
deleted file mode 100644
index c96e223..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkSettings.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.project;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Settings for multiple APK generation.
- */
-public class ApkSettings {
-    private boolean mSplitByDpi = false;
-
-    public ApkSettings() {
-    }
-
-    /**
-     * Returns a map of configuration filters to be used by the -c option of aapt.
-     * <p/>The map stores (key, value) pairs where the keys is a filename modifier and the value
-     * is the parameter to pass to aapt through the -c option.
-     * @return a map, always. It can however be empty.
-     */
-    public Map<String, String> getResourceFilters() {
-        Map<String, String> map = new HashMap<String, String>();
-        if (mSplitByDpi) {
-            map.put("hdpi", "hdpi,nodpi");
-            map.put("mdpi", "mdpi,nodpi");
-            map.put("ldpi", "ldpi,nodpi");
-        }
-
-        return map;
-    }
-
-    /**
-     * Indicates whether APKs should be generate for each dpi level.
-     */
-    public boolean isSplitByDpi() {
-        return mSplitByDpi;
-    }
-
-    public void setSplitByDensity(boolean split) {
-        mSplitByDpi = split;
-    }
-}
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
deleted file mode 100644
index e9e5999..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- * 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.android.sdklib.internal.project;
-
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-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;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Creates the basic files needed to get an Android project up and running.
- *
- * @hide
- */
-public class ProjectCreator {
-
-    /** Package path substitution string used in template files, i.e. "PACKAGE_PATH" */
-    private final static String PH_JAVA_FOLDER = "PACKAGE_PATH";
-    /** Package name substitution string used in template files, i.e. "PACKAGE" */
-    private final static String PH_PACKAGE = "PACKAGE";
-    /** Activity name substitution string used in template files, i.e. "ACTIVITY_NAME".
-     * @deprecated This is only used for older templates. For new ones see
-     * {@link #PH_ACTIVITY_ENTRY_NAME}, and {@link #PH_ACTIVITY_CLASS_NAME}. */
-    private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME";
-    /** Activity name substitution string used in manifest templates, i.e. "ACTIVITY_ENTRY_NAME".*/
-    private final static String PH_ACTIVITY_ENTRY_NAME = "ACTIVITY_ENTRY_NAME";
-    /** Activity name substitution string used in class templates, i.e. "ACTIVITY_CLASS_NAME".*/
-    private final static String PH_ACTIVITY_CLASS_NAME = "ACTIVITY_CLASS_NAME";
-    /** Activity FQ-name substitution string used in class templates, i.e. "ACTIVITY_FQ_NAME".*/
-    private final static String PH_ACTIVITY_FQ_NAME = "ACTIVITY_FQ_NAME";
-    /** Original Activity class name substitution string used in class templates, i.e.
-     * "ACTIVITY_TESTED_CLASS_NAME".*/
-    private final static String PH_ACTIVITY_TESTED_CLASS_NAME = "ACTIVITY_TESTED_CLASS_NAME";
-    /** Project name substitution string used in template files, i.e. "PROJECT_NAME". */
-    private final static String PH_PROJECT_NAME = "PROJECT_NAME";
-    /** Application icon substitution string used in the manifest template */
-    private final static String PH_ICON = "ICON";
-
-    /** Pattern for characters accepted in a project name. Since this will be used as a
-     * directory name, we're being a bit conservative on purpose: dot and space cannot be used. */
-    public static final Pattern RE_PROJECT_NAME = Pattern.compile("[a-zA-Z0-9_]+");
-    /** List of valid characters for a project name. Used for display purposes. */
-    public final static String CHARS_PROJECT_NAME = "a-z A-Z 0-9 _";
-
-    /** Pattern for characters accepted in a package name. A package is list of Java identifier
-     * separated by a dot. We need to have at least one dot (e.g. a two-level package name).
-     * A Java identifier cannot start by a digit. */
-    public static final Pattern RE_PACKAGE_NAME =
-        Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)+");
-    /** List of valid characters for a project name. Used for display purposes. */
-    public final static String CHARS_PACKAGE_NAME = "a-z A-Z 0-9 _";
-
-    /** Pattern for characters accepted in an activity name, which is a Java identifier. */
-    public static final Pattern RE_ACTIVITY_NAME =
-        Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");
-    /** List of valid characters for a project name. Used for display purposes. */
-    public final static String CHARS_ACTIVITY_NAME = "a-z A-Z 0-9 _";
-
-
-    public enum OutputLevel {
-        /** Silent mode. Project creation will only display errors. */
-        SILENT,
-        /** Normal mode. Project creation will display what's being done, display
-         * error but not warnings. */
-        NORMAL,
-        /** Verbose mode. Project creation will display what's being done, errors and warnings. */
-        VERBOSE;
-    }
-
-    /**
-     * Exception thrown when a project creation fails, typically because a template
-     * file cannot be written.
-     */
-    private static class ProjectCreateException extends Exception {
-        /** default UID. This will not be serialized anyway. */
-        private static final long serialVersionUID = 1L;
-
-        @SuppressWarnings("unused")
-        ProjectCreateException(String message) {
-            super(message);
-        }
-
-        ProjectCreateException(Throwable t, String format, Object... args) {
-            super(format != null ? String.format(format, args) : format, t);
-        }
-
-        ProjectCreateException(String format, Object... args) {
-            super(String.format(format, args));
-        }
-    }
-
-    private final OutputLevel mLevel;
-
-    private final ISdkLog mLog;
-    private final String mSdkFolder;
-
-    public ProjectCreator(String sdkFolder, OutputLevel level, ISdkLog log) {
-        mSdkFolder = sdkFolder;
-        mLevel = level;
-        mLog = log;
-    }
-
-    /**
-     * Creates a new project.
-     * <p/>
-     * The caller should have already checked and sanitized the parameters.
-     *
-     * @param folderPath the folder of the project to create.
-     * @param projectName the name of the project. The name must match the
-     *          {@link #RE_PROJECT_NAME} regex.
-     * @param packageName the package of the project. The name must match the
-     *          {@link #RE_PACKAGE_NAME} regex.
-     * @param activityEntry the activity of the project as it will appear in the manifest. Can be
-     *          null if no activity should be created. The name must match the
-     *          {@link #RE_ACTIVITY_NAME} regex.
-     * @param target the project target.
-     * @param pathToMainProject if non-null the project will be setup to test a main project
-     * located at the given path.
-     */
-    public void createProject(String folderPath, String projectName,
-            String packageName, String activityEntry, IAndroidTarget target,
-            String pathToMainProject) {
-
-        // create project folder if it does not exist
-        File projectFolder = new File(folderPath);
-        if (!projectFolder.exists()) {
-
-            boolean created = false;
-            Throwable t = null;
-            try {
-                created = projectFolder.mkdirs();
-            } catch (Exception e) {
-                t = e;
-            }
-
-            if (created) {
-                println("Created project directory: %1$s", projectFolder);
-            } else {
-                mLog.error(t, "Could not create directory: %1$s", projectFolder);
-                return;
-            }
-        } else {
-            Exception e = null;
-            String error = null;
-            try {
-                String[] content = projectFolder.list();
-                if (content == null) {
-                    error = "Project folder '%1$s' is not a directory.";
-                } else if (content.length != 0) {
-                    error = "Project folder '%1$s' is not empty. Please consider using '%2$s update' instead.";
-                }
-            } catch (Exception e1) {
-                e = e1;
-            }
-
-            if (e != null || error != null) {
-                mLog.error(e, error, projectFolder, SdkConstants.androidCmdName());
-            }
-        }
-
-        try {
-            boolean isTestProject = pathToMainProject != null;
-
-            // first create the project properties.
-
-            // location of the SDK goes in localProperty
-            ProjectProperties localProperties = ProjectProperties.create(folderPath,
-                    PropertyType.LOCAL);
-            localProperties.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder);
-            localProperties.save();
-
-            // target goes in default properties
-            ProjectProperties defaultProperties = ProjectProperties.create(folderPath,
-                    PropertyType.DEFAULT);
-            defaultProperties.setAndroidTarget(target);
-            defaultProperties.save();
-
-            // create a build.properties file with just the application package
-            ProjectProperties buildProperties = ProjectProperties.create(folderPath,
-                    PropertyType.BUILD);
-
-            // only put application.package for older target where the rules file didn't.
-            // grab it through xpath
-            if (target.getVersion().getApiLevel() < 4) {
-                buildProperties.setProperty(ProjectProperties.PROPERTY_APP_PACKAGE, packageName);
-            }
-
-            if (isTestProject) {
-                buildProperties.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT,
-                        pathToMainProject);
-            }
-
-            buildProperties.save();
-
-            // create the map for place-holders of values to replace in the templates
-            final HashMap<String, String> keywords = new HashMap<String, String>();
-
-            // create the required folders.
-            // compute src folder path
-            final String packagePath =
-                stripString(packageName.replace(".", File.separator),
-                        File.separatorChar);
-
-            // put this path in the place-holder map for project files that needs to list
-            // files manually.
-            keywords.put(PH_JAVA_FOLDER, packagePath);
-            keywords.put(PH_PACKAGE, packageName);
-
-
-            // compute some activity related information
-            String fqActivityName = null, activityPath = null, activityClassName = null;
-            String originalActivityEntry = activityEntry;
-            String originalActivityClassName = null;
-            if (activityEntry != null) {
-                if (isTestProject) {
-                    // append Test so that it doesn't collide with the main project activity.
-                    activityEntry += "Test";
-
-                    // get the classname from the original activity entry.
-                    int pos = originalActivityEntry.lastIndexOf('.');
-                    if (pos != -1) {
-                        originalActivityClassName = originalActivityEntry.substring(pos + 1);
-                    } else {
-                        originalActivityClassName = originalActivityEntry;
-                    }
-                }
-
-                // get the fully qualified name of the activity
-                fqActivityName = AndroidManifest.combinePackageAndClassName(packageName,
-                        activityEntry);
-
-                // get the activity path (replace the . to /)
-                activityPath = stripString(fqActivityName.replace(".", File.separator),
-                        File.separatorChar);
-
-                // remove the last segment, so that we only have the path to the activity, but
-                // not the activity filename itself.
-                activityPath = activityPath.substring(0,
-                        activityPath.lastIndexOf(File.separatorChar));
-
-                // finally, get the class name for the activity
-                activityClassName = fqActivityName.substring(fqActivityName.lastIndexOf('.') + 1);
-            }
-
-            // at this point we have the following for the activity:
-            // activityEntry: this is the manifest entry. For instance .MyActivity
-            // fqActivityName: full-qualified class name: com.foo.MyActivity
-            // activityClassName: only the classname: MyActivity
-            // originalActivityClassName: the classname of the activity being tested (if applicable)
-
-            // Add whatever activity info is needed in the place-holder map.
-            // Older templates only expect ACTIVITY_NAME to be the same (and unmodified for tests).
-            if (target.getVersion().getApiLevel() < 4) { // legacy
-                if (originalActivityEntry != null) {
-                    keywords.put(PH_ACTIVITY_NAME, originalActivityEntry);
-                }
-            } else {
-                // newer templates make a difference between the manifest entries, classnames,
-                // as well as the main and test classes.
-                if (activityEntry != null) {
-                    keywords.put(PH_ACTIVITY_ENTRY_NAME, activityEntry);
-                    keywords.put(PH_ACTIVITY_CLASS_NAME, activityClassName);
-                    keywords.put(PH_ACTIVITY_FQ_NAME, fqActivityName);
-                    if (originalActivityClassName != null) {
-                        keywords.put(PH_ACTIVITY_TESTED_CLASS_NAME, originalActivityClassName);
-                    }
-                }
-            }
-
-            // Take the project name from the command line if there's one
-            if (projectName != null) {
-                keywords.put(PH_PROJECT_NAME, projectName);
-            } else {
-                if (activityClassName != null) {
-                    // Use the activity class name as project name
-                    keywords.put(PH_PROJECT_NAME, activityClassName);
-                } else {
-                    // We need a project name. Just pick up the basename of the project
-                    // directory.
-                    projectName = projectFolder.getName();
-                    keywords.put(PH_PROJECT_NAME, projectName);
-                }
-            }
-
-            // create the source folder for the activity
-            if (activityClassName != null) {
-                String srcActivityFolderPath = SdkConstants.FD_SOURCES + File.separator + activityPath;
-                File sourceFolder = createDirs(projectFolder, srcActivityFolderPath);
-
-                String javaTemplate = isTestProject ? "java_tests_file.template"
-                        : "java_file.template";
-                String activityFileName = activityClassName + ".java";
-
-                installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
-                        keywords, target);
-            } else {
-                // we should at least create 'src'
-                createDirs(projectFolder, SdkConstants.FD_SOURCES);
-            }
-
-            // create other useful folders
-            File resourceFolder = createDirs(projectFolder, SdkConstants.FD_RESOURCES);
-            createDirs(projectFolder, SdkConstants.FD_OUTPUT);
-            createDirs(projectFolder, SdkConstants.FD_NATIVE_LIBS);
-
-            if (isTestProject == false) {
-                /* Make res files only for non test projects */
-                File valueFolder = createDirs(resourceFolder, SdkConstants.FD_VALUES);
-                installTemplate("strings.template", new File(valueFolder, "strings.xml"),
-                        keywords, target);
-
-                File layoutFolder = createDirs(resourceFolder, SdkConstants.FD_LAYOUT);
-                installTemplate("layout.template", new File(layoutFolder, "main.xml"),
-                        keywords, target);
-
-                // create the icons
-                if (installIcons(resourceFolder, target)) {
-                    keywords.put(PH_ICON, "android:icon=\"@drawable/icon\"");
-                } else {
-                    keywords.put(PH_ICON, "");
-                }
-            }
-
-            /* Make AndroidManifest.xml and build.xml files */
-            String manifestTemplate = "AndroidManifest.template";
-            if (isTestProject) {
-                manifestTemplate = "AndroidManifest.tests.template";
-            }
-
-            installTemplate(manifestTemplate,
-                    new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML),
-                    keywords, target);
-
-            installTemplate("build.template",
-                    new File(projectFolder, SdkConstants.FN_BUILD_XML),
-                    keywords);
-        } catch (ProjectCreateException e) {
-            mLog.error(e, null);
-        } catch (IOException e) {
-            mLog.error(e, null);
-        }
-    }
-
-    /**
-     * Updates an existing project.
-     * <p/>
-     * Workflow:
-     * <ul>
-     * <li> Check AndroidManifest.xml is present (required)
-     * <li> Check there's a default.properties with a target *or* --target was specified
-     * <li> Update default.prop if --target was specified
-     * <li> Refresh/create "sdk" in local.properties
-     * <li> Build.xml: create if not present or no <androidinit(\w|/>) in it
-     * </ul>
-     *
-     * @param folderPath the folder of the project to update. This folder must exist.
-     * @param target the project target. Can be null.
-     * @param projectName The project name from --name. Can be null.
-     */
-    public void updateProject(String folderPath, IAndroidTarget target, String projectName) {
-        // since this is an update, check the folder does point to a project
-        File androidManifest = checkProjectFolder(folderPath);
-        if (androidManifest == null) {
-            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);
-        if (props == null || props.getProperty(ProjectProperties.PROPERTY_TARGET) == null) {
-            if (target == null) {
-                mLog.error(null,
-                    "There is no %1$s file in '%2$s'. Please provide a --target to the '%3$s update' command.",
-                    PropertyType.DEFAULT.getFilename(),
-                    folderPath,
-                    SdkConstants.androidCmdName());
-                return;
-            }
-        }
-
-        // Update default.prop if --target was specified
-        if (target != null) {
-            // we already attempted to load the file earlier, if that failed, create it.
-            if (props == null) {
-                props = ProjectProperties.create(folderPath, PropertyType.DEFAULT);
-            }
-
-            // set or replace the target
-            props.setAndroidTarget(target);
-            try {
-                props.save();
-                println("Updated %1$s", PropertyType.DEFAULT.getFilename());
-            } catch (IOException e) {
-                mLog.error(e, "Failed to write %1$s file in '%2$s'",
-                        PropertyType.DEFAULT.getFilename(),
-                        folderPath);
-                return;
-            }
-        }
-
-        // Refresh/create "sdk" in local.properties
-        // because the file may already exists and contain other values (like apk config),
-        // we first try to load it.
-        props = ProjectProperties.load(folderPath, PropertyType.LOCAL);
-        if (props == null) {
-            props = ProjectProperties.create(folderPath, PropertyType.LOCAL);
-        }
-
-        // set or replace the sdk location.
-        props.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder);
-        try {
-            props.save();
-            println("Updated %1$s", PropertyType.LOCAL.getFilename());
-        } catch (IOException e) {
-            mLog.error(e, "Failed to write %1$s file in '%2$s'",
-                    PropertyType.LOCAL.getFilename(),
-                    folderPath);
-            return;
-        }
-
-        // Build.xml: create if not present or no <androidinit/> in it
-        File buildXml = new File(projectFolder, SdkConstants.FN_BUILD_XML);
-        boolean needsBuildXml = projectName != null || !buildXml.exists();
-        if (!needsBuildXml) {
-            // Look for for a classname="com.android.ant.SetupTask" attribute
-            needsBuildXml = !checkFileContainsRegexp(buildXml,
-                    "classname=\"com.android.ant.SetupTask\"");  //$NON-NLS-1$
-        }
-        if (!needsBuildXml) {
-            // Note that "<setup" must be followed by either a whitespace, a "/" (for the
-            // XML /> closing tag) or an end-of-line. This way we know the XML tag is really this
-            // one and later we will be able to use an "androidinit2" tag or such as necessary.
-            needsBuildXml = !checkFileContainsRegexp(buildXml, "<setup(?:\\s|/|$)");  //$NON-NLS-1$
-        }
-        if (needsBuildXml) {
-            println("File %1$s is too old and needs to be updated.", SdkConstants.FN_BUILD_XML);
-        }
-
-        if (needsBuildXml) {
-            // create the map for place-holders of values to replace in the templates
-            final HashMap<String, String> keywords = new HashMap<String, String>();
-
-            // Take the project name from the command line if there's one
-            if (projectName != null) {
-                keywords.put(PH_PROJECT_NAME, projectName);
-            } else {
-                extractPackageFromManifest(androidManifest, keywords);
-                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, activity);
-                } else {
-                    // We need a project name. Just pick up the basename of the project
-                    // directory.
-                    projectName = projectFolder.getName();
-                    keywords.put(PH_PROJECT_NAME, projectName);
-                }
-            }
-
-            if (mLevel == OutputLevel.VERBOSE) {
-                println("Regenerating %1$s with project name %2$s",
-                        SdkConstants.FN_BUILD_XML,
-                        keywords.get(PH_PROJECT_NAME));
-            }
-
-            try {
-                installTemplate("build.template",
-                        new File(projectFolder, SdkConstants.FN_BUILD_XML),
-                        keywords);
-            } catch (ProjectCreateException e) {
-                mLog.error(e, null);
-            }
-        }
-    }
-
-    /**
-     * 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) {
-        Pattern p = Pattern.compile(regexp);
-
-        try {
-            BufferedReader in = new BufferedReader(new FileReader(file));
-            String line;
-
-            while ((line = in.readLine()) != null) {
-                if (p.matcher(line).find()) {
-                    return true;
-                }
-            }
-
-            in.close();
-        } catch (Exception e) {
-            // ignore
-        }
-
-        return false;
-    }
-
-    /**
-     * 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_ENTRY_NAME}.
-     * When no activity is found, this key is not created.
-     *
-     * @param manifestFile The AndroidManifest.xml file
-     * @param outKeywords  Place where to put the out parameters: package and activity names.
-     * @return True if the package/activity was parsed and updated in the keyword dictionary.
-     */
-    private boolean extractPackageFromManifest(File manifestFile,
-            Map<String, String> outKeywords) {
-        try {
-            XPath xpath = AndroidXPathFactory.newXPath();
-
-            InputSource source = new InputSource(new FileReader(manifestFile));
-            String packageName = xpath.evaluate("/manifest/@package", source);
-
-            source = new InputSource(new FileReader(manifestFile));
-
-            // Select the "android:name" attribute of all <activity> nodes but only if they
-            // contain a sub-node <intent-filter><action> with an "android:name" attribute which
-            // is 'android.intent.action.MAIN' and an <intent-filter><category> with an
-            // "android:name" attribute which is 'android.intent.category.LAUNCHER'
-            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", AndroidXPathFactory.DEFAULT_NS_PREFIX);
-
-            NodeList activityNames = (NodeList) xpath.evaluate(expression, source,
-                    XPathConstants.NODESET);
-
-            // If we get here, both XPath expressions were valid so we're most likely dealing
-            // with an actual AndroidManifest.xml file. The nodes may not have the requested
-            // attributes though, if which case we should warn.
-
-            if (packageName == null || packageName.length() == 0) {
-                mLog.error(null,
-                        "Missing <manifest package=\"...\"> in '%1$s'",
-                        manifestFile.getName());
-                return false;
-            }
-
-            // Get the first activity that matched earlier. If there is no activity,
-            // activityName is set to an empty string and the generated "combined" name
-            // will be in the form "package." (with a dot at the end).
-            String activityName = "";
-            if (activityNames.getLength() > 0) {
-                activityName = activityNames.item(0).getNodeValue();
-            }
-
-            if (mLevel == OutputLevel.VERBOSE && activityNames.getLength() > 1) {
-                println("WARNING: There is more than one activity defined in '%1$s'.\n" +
-                        "Only the first one will be used. If this is not appropriate, you need\n" +
-                        "to specify one of these values manually instead:",
-                        manifestFile.getName());
-
-                for (int i = 0; i < activityNames.getLength(); i++) {
-                    String name = activityNames.item(i).getNodeValue();
-                    name = combinePackageActivityNames(packageName, name);
-                    println("- %1$s", name);
-                }
-            }
-
-            if (activityName.length() == 0) {
-                mLog.warning("Missing <activity %1$s:name=\"...\"> in '%2$s'.\n" +
-                        "No activity will be generated.",
-                        AndroidXPathFactory.DEFAULT_NS_PREFIX, manifestFile.getName());
-            } else {
-                outKeywords.put(PH_ACTIVITY_ENTRY_NAME, activityName);
-            }
-
-            outKeywords.put(PH_PACKAGE, packageName);
-            return true;
-
-        } catch (IOException e) {
-            mLog.error(e, "Failed to read %1$s", manifestFile.getName());
-        } catch (XPathExpressionException e) {
-            Throwable t = e.getCause();
-            mLog.error(t == null ? e : t,
-                    "Failed to parse %1$s",
-                    manifestFile.getName());
-        }
-
-        return false;
-    }
-
-    private String combinePackageActivityNames(String packageName, String activityName) {
-        // Activity Name can have 3 forms:
-        // - ".Name" means this is a class name in the given package name.
-        //    The full FQCN is thus packageName + ".Name"
-        // - "Name" is an older variant of the former. Full FQCN is packageName + "." + "Name"
-        // - "com.blah.Name" is a full FQCN. Ignore packageName and use activityName as-is.
-        //   To be valid, the package name should have at least two components. This is checked
-        //   later during the creation of the build.xml file, so we just need to detect there's
-        //   a dot but not at pos==0.
-
-        int pos = activityName.indexOf('.');
-        if (pos == 0) {
-            return packageName + activityName;
-        } else if (pos > 0) {
-            return activityName;
-        } else {
-            return packageName + "." + activityName;
-        }
-    }
-
-    /**
-     * Installs a new file that is based on a template file provided by a given target.
-     * Each match of each key from the place-holder map in the template will be replaced with its
-     * corresponding value in the created file.
-     *
-     * @param templateName the name of to the template file
-     * @param destFile the path to the destination file, relative to the project
-     * @param placeholderMap a map of (place-holder, value) to create the file from the template.
-     * @param target the Target of the project that will be providing the template.
-     * @throws ProjectCreateException
-     */
-    private void installTemplate(String templateName, File destFile,
-            Map<String, String> placeholderMap, IAndroidTarget target)
-            throws ProjectCreateException {
-        // query the target for its template directory
-        String templateFolder = target.getPath(IAndroidTarget.TEMPLATES);
-        final String sourcePath = templateFolder + File.separator + templateName;
-
-        installFullPathTemplate(sourcePath, destFile, placeholderMap);
-    }
-
-    /**
-     * Installs a new file that is based on a template file provided by the tools folder.
-     * Each match of each key from the place-holder map in the template will be replaced with its
-     * corresponding value in the created file.
-     *
-     * @param templateName the name of to the template file
-     * @param destFile the path to the destination file, relative to the project
-     * @param placeholderMap a map of (place-holder, value) to create the file from the template.
-     * @throws ProjectCreateException
-     */
-    private void installTemplate(String templateName, File destFile,
-            Map<String, String> placeholderMap)
-            throws ProjectCreateException {
-        // query the target for its template directory
-        String templateFolder = mSdkFolder + File.separator + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER;
-        final String sourcePath = templateFolder + File.separator + templateName;
-
-        installFullPathTemplate(sourcePath, destFile, placeholderMap);
-    }
-
-    /**
-     * Installs a new file that is based on a template.
-     * Each match of each key from the place-holder map in the template will be replaced with its
-     * corresponding value in the created file.
-     *
-     * @param sourcePath the full path to the source template file
-     * @param destFile the destination file
-     * @param placeholderMap a map of (place-holder, value) to create the file from the template.
-     * @throws ProjectCreateException
-     */
-    private void installFullPathTemplate(String sourcePath, File destFile,
-            Map<String, String> placeholderMap) throws ProjectCreateException {
-
-        boolean existed = destFile.exists();
-
-        try {
-            BufferedWriter out = new BufferedWriter(new FileWriter(destFile));
-            BufferedReader in = new BufferedReader(new FileReader(sourcePath));
-            String line;
-
-            while ((line = in.readLine()) != null) {
-                if (placeholderMap != null) {
-                    for (String key : placeholderMap.keySet()) {
-                        line = line.replace(key, placeholderMap.get(key));
-                    }
-                }
-
-                out.write(line);
-                out.newLine();
-            }
-
-            out.close();
-            in.close();
-        } catch (Exception e) {
-            throw new ProjectCreateException(e, "Could not access %1$s: %2$s",
-                    destFile, e.getMessage());
-        }
-
-        println("%1$s file %2$s",
-                existed ? "Updated" : "Added",
-                destFile);
-    }
-
-    /**
-     * Installs the project icons.
-     * @param resourceFolder the resource folder
-     * @param target the target of the project.
-     * @return true if any icon was installed.
-     */
-    private boolean installIcons(File resourceFolder, IAndroidTarget target)
-            throws ProjectCreateException {
-        // query the target for its template directory
-        String templateFolder = target.getPath(IAndroidTarget.TEMPLATES);
-
-        boolean installedIcon = false;
-
-        installedIcon |= installIcon(templateFolder, "icon_hdpi.png", resourceFolder, "drawable-hdpi");
-        installedIcon |= installIcon(templateFolder, "icon_mdpi.png", resourceFolder, "drawable-mdpi");
-        installedIcon |= installIcon(templateFolder, "icon_ldpi.png", resourceFolder, "drawable-ldpi");
-
-        return installedIcon;
-    }
-
-    /**
-     * Installs an Icon in the project.
-     * @return true if the icon was installed.
-     */
-    private boolean installIcon(String templateFolder, String iconName, File resourceFolder,
-            String folderName) throws ProjectCreateException {
-        File icon = new File(templateFolder, iconName);
-        if (icon.exists()) {
-            File drawable = createDirs(resourceFolder, folderName);
-            installBinaryFile(icon, new File(drawable, "icon.png"));
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Installs a binary file
-     * @param source the source file to copy
-     * @param destination the destination file to write
-     */
-    private void installBinaryFile(File source, File destination) {
-        byte[] buffer = new byte[8192];
-
-        FileInputStream fis = null;
-        FileOutputStream fos = null;
-        try {
-            fis = new FileInputStream(source);
-            fos = new FileOutputStream(destination);
-
-            int read;
-            while ((read = fis.read(buffer)) != -1) {
-                fos.write(buffer, 0, read);
-            }
-
-        } catch (FileNotFoundException e) {
-            // shouldn't happen since we check before.
-        } catch (IOException e) {
-            new ProjectCreateException(e, "Failed to read binary file: %1$s",
-                    source.getAbsolutePath());
-        } finally {
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-        }
-        
-    }
-
-    /**
-     * Prints a message unless silence is enabled.
-     * <p/>
-     * This is just a convenience wrapper around {@link ISdkLog#printf(String, Object...)} from
-     * {@link #mLog} after testing if ouput level is {@link OutputLevel#VERBOSE}.
-     *
-     * @param format Format for String.format
-     * @param args Arguments for String.format
-     */
-    private void println(String format, Object... args) {
-        if (mLevel != OutputLevel.SILENT) {
-            if (!format.endsWith("\n")) {
-                format += "\n";
-            }
-            mLog.printf(format, args);
-        }
-    }
-
-    /**
-     * Creates a new folder, along with any parent folders that do not exists.
-     *
-     * @param parent the parent folder
-     * @param name the name of the directory to create.
-     * @throws ProjectCreateException
-     */
-    private File createDirs(File parent, String name) throws ProjectCreateException {
-        final File newFolder = new File(parent, name);
-        boolean existedBefore = true;
-
-        if (!newFolder.exists()) {
-            if (!newFolder.mkdirs()) {
-                throw new ProjectCreateException("Could not create directory: %1$s", newFolder);
-            }
-            existedBefore = false;
-        }
-
-        if (newFolder.isDirectory()) {
-            if (!newFolder.canWrite()) {
-                throw new ProjectCreateException("Path is not writable: %1$s", newFolder);
-            }
-        } else {
-            throw new ProjectCreateException("Path is not a directory: %1$s", newFolder);
-        }
-
-        if (!existedBefore) {
-            try {
-                println("Created directory %1$s", newFolder.getCanonicalPath());
-            } catch (IOException e) {
-                throw new ProjectCreateException(
-                        "Could not determine canonical path of created directory", e);
-            }
-        }
-
-        return newFolder;
-    }
-
-    /**
-     * Strips the string of beginning and trailing characters (multiple
-     * characters will be stripped, example stripString("..test...", '.')
-     * results in "test";
-     *
-     * @param s the string to strip
-     * @param strip the character to strip from beginning and end
-     * @return the stripped string or the empty string if everything is stripped.
-     */
-    private static String stripString(String s, char strip) {
-        final int sLen = s.length();
-        int newStart = 0, newEnd = sLen - 1;
-
-        while (newStart < sLen && s.charAt(newStart) == strip) {
-          newStart++;
-        }
-        while (newEnd >= 0 && s.charAt(newEnd) == strip) {
-          newEnd--;
-        }
-
-        /*
-         * newEnd contains a char we want, and substring takes end as being
-         * exclusive
-         */
-        newEnd++;
-
-        if (newStart >= sLen || newEnd < 0) {
-            return "";
-        }
-
-        return s.substring(newStart, newEnd);
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
deleted file mode 100644
index 6e29e5a..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * 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.android.sdklib.internal.project;
-
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Class to load and save project properties for both ADT and Ant-based build.
- *
- */
-public final class ProjectProperties {
-    /** The property name for the project target */
-    public final static String PROPERTY_TARGET = "target";
-
-    public final static String PROPERTY_SDK = "sdk.dir";
-    // LEGACY - compatibility with 1.6 and before
-    public final static String PROPERTY_SDK_LEGACY = "sdk-location";
-
-    public final static String PROPERTY_APP_PACKAGE = "application.package";
-    // LEGACY - compatibility with 1.6 and before
-    public final static String PROPERTY_APP_PACKAGE_LEGACY = "application-package";
-
-    public final static String PROPERTY_SPLIT_BY_DENSITY = "split.density";
-
-    public final static String PROPERTY_TESTED_PROJECT = "tested.project.dir";
-
-    public static enum PropertyType {
-        BUILD("build.properties", BUILD_HEADER),
-        DEFAULT("default.properties", DEFAULT_HEADER),
-        LOCAL("local.properties", LOCAL_HEADER);
-
-        private final String mFilename;
-        private final String mHeader;
-
-        PropertyType(String filename, String header) {
-            mFilename = filename;
-            mHeader = header;
-        }
-
-        public String getFilename() {
-            return mFilename;
-        }
-    }
-
-    private final static String LOCAL_HEADER =
-//           1-------10--------20--------30--------40--------50--------60--------70--------80
-            "# This file is automatically generated by Android Tools.\n" +
-            "# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" +
-            "# \n" +
-            "# This file must *NOT* be checked in Version Control Systems,\n" +
-            "# as it contains information specific to your local configuration.\n" +
-            "\n";
-
-    private final static String DEFAULT_HEADER =
-//          1-------10--------20--------30--------40--------50--------60--------70--------80
-           "# This file is automatically generated by Android Tools.\n" +
-           "# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" +
-           "# \n" +
-           "# This file must be checked in Version Control Systems.\n" +
-           "# \n" +
-           "# To customize properties used by the Ant build system use,\n" +
-           "# \"build.properties\", and override values to adapt the script to your\n" +
-           "# project structure.\n" +
-           "\n";
-
-    private final static String BUILD_HEADER =
-//          1-------10--------20--------30--------40--------50--------60--------70--------80
-           "# This file is used to override default values used by the Ant build system.\n" +
-           "# \n" +
-           "# This file must be checked in Version Control Systems, as it is\n" +
-           "# integral to the build system of your project.\n" +
-           "\n" +
-           "# This file is only used by the Ant script.\n" +
-           "\n" +
-           "# You can use this to override default values such as\n" +
-           "#  'source.dir' for the location of your java source folder and\n" +
-           "#  'out.dir' for the location of your output folder.\n" +
-           "\n" +
-           "# You can also use it define how the release builds are signed by declaring\n" +
-           "# the following properties:\n" +
-           "#  'key.store' for the location of your keystore and\n" +
-           "#  'key.alias' for the name of the key to use.\n" +
-           "# The password will be asked during the build when you use the 'release' target.\n" +
-           "\n";
-
-    private final static Map<String, String> COMMENT_MAP = new HashMap<String, String>();
-    static {
-//               1-------10--------20--------30--------40--------50--------60--------70--------80
-        COMMENT_MAP.put(PROPERTY_TARGET,
-                "# Project target.\n");
-        COMMENT_MAP.put(PROPERTY_SPLIT_BY_DENSITY,
-                "# Indicates whether an apk should be generated for each density.\n");
-        COMMENT_MAP.put(PROPERTY_SDK,
-                "# location of the SDK. This is only used by Ant\n" +
-                "# For customization when using a Version Control System, please read the\n" +
-                "# header note.\n");
-        COMMENT_MAP.put(PROPERTY_APP_PACKAGE,
-                "# The name of your application package as defined in the manifest.\n" +
-                "# Used by the 'uninstall' rule.\n");
-    }
-
-    private final String mProjectFolderOsPath;
-    private final Map<String, String> mProperties;
-    private final PropertyType mType;
-
-    /**
-     * Loads a project properties file and return a {@link ProjectProperties} object
-     * containing the properties
-     *
-     * @param projectFolderOsPath the project folder.
-     * @param type One the possible {@link PropertyType}s.
-     */
-    public static ProjectProperties load(String projectFolderOsPath, PropertyType type) {
-        File projectFolder = new File(projectFolderOsPath);
-        if (projectFolder.isDirectory()) {
-            File defaultFile = new File(projectFolder, type.mFilename);
-            if (defaultFile.isFile()) {
-                Map<String, String> map = SdkManager.parsePropertyFile(defaultFile, null /* log */);
-                if (map != null) {
-                    return new ProjectProperties(projectFolderOsPath, map, type);
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Merges all properties from the given file into the current properties.
-     * <p/>
-     * This emulates the Ant behavior: existing properties are <em>not</em> overriden.
-     * Only new undefined properties become defined.
-     * <p/>
-     * Typical usage:
-     * <ul>
-     * <li>Create a ProjectProperties with {@link PropertyType#BUILD}
-     * <li>Merge in values using {@link PropertyType#DEFAULT}
-     * <li>The result is that this contains all the properties from default plus those
-     *     overridden by the build.properties file.
-     * </ul>
-     *
-     * @param type One the possible {@link PropertyType}s.
-     * @return this object, for chaining.
-     */
-    public ProjectProperties merge(PropertyType type) {
-        File projectFolder = new File(mProjectFolderOsPath);
-        if (projectFolder.isDirectory()) {
-            File defaultFile = new File(projectFolder, type.mFilename);
-            if (defaultFile.isFile()) {
-                Map<String, String> map = SdkManager.parsePropertyFile(defaultFile, null /* log */);
-                if (map != null) {
-                    for(Entry<String, String> entry : map.entrySet()) {
-                        String key = entry.getKey();
-                        String value = entry.getValue();
-                        if (!mProperties.containsKey(key) && value != null) {
-                            mProperties.put(key, value);
-                        }
-                    }
-                }
-            }
-        }
-        return this;
-    }
-
-    /**
-     * Creates a new project properties object, with no properties.
-     * <p/>The file is not created until {@link #save()} is called.
-     * @param projectFolderOsPath the project folder.
-     * @param type
-     */
-    public static ProjectProperties create(String projectFolderOsPath, PropertyType type) {
-        // create and return a ProjectProperties with an empty map.
-        return new ProjectProperties(projectFolderOsPath, new HashMap<String, String>(), type);
-    }
-
-    /**
-     * Sets a new properties. If a property with the same name already exists, it is replaced.
-     * @param name the name of the property.
-     * @param value the value of the property.
-     */
-    public void setProperty(String name, String value) {
-        mProperties.put(name, value);
-    }
-
-    /**
-     * Sets the target property to the given {@link IAndroidTarget} object.
-     * @param target the Android target.
-     */
-    public void setAndroidTarget(IAndroidTarget target) {
-        assert mType == PropertyType.DEFAULT;
-        mProperties.put(PROPERTY_TARGET, target.hashString());
-    }
-
-    /**
-     * Returns the value of a property.
-     * @param name the name of the property.
-     * @return the property value or null if the property is not set.
-     */
-    public String getProperty(String name) {
-        return mProperties.get(name);
-    }
-
-    /**
-     * Removes a property and returns its previous value (or null if the property did not exist).
-     * @param name the name of the property to remove.
-     */
-    public String removeProperty(String name) {
-        return mProperties.remove(name);
-    }
-
-    /**
-     * Saves the property file, using UTF-8 encoding.
-     * @throws IOException
-     */
-    public void save() throws IOException {
-        File toSave = new File(mProjectFolderOsPath, mType.mFilename);
-
-        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(toSave),
-                SdkConstants.INI_CHARSET);
-
-        // write the header
-        writer.write(mType.mHeader);
-
-        // write the properties.
-        for (Entry<String, String> entry : mProperties.entrySet()) {
-            String comment = COMMENT_MAP.get(entry.getKey());
-            if (comment != null) {
-                writer.write(comment);
-            }
-            String value = entry.getValue();
-            if (value != null) {
-                value = value.replaceAll("\\\\", "\\\\\\\\");
-                writer.write(String.format("%s=%s\n", entry.getKey(), value));
-            }
-        }
-
-        // close the file to flush
-        writer.close();
-    }
-
-    /**
-     * Private constructor.
-     * <p/>
-     * Use {@link #load(String, PropertyType)} or {@link #create(String, PropertyType)}
-     * to instantiate.
-     */
-    private ProjectProperties(String projectFolderOsPath, Map<String, String> map,
-            PropertyType type) {
-        mProjectFolderOsPath = projectFolderOsPath;
-        mProperties = map;
-        mType = type;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java
deleted file mode 100755
index 0dec3bb..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Represents an add-on XML node in an SDK repository.
- */
-public class AddonPackage extends Package implements IPackageVersion {
-
-    private static final String PROP_NAME      = "Addon.Name";      //$NON-NLS-1$
-    private static final String PROP_VENDOR    = "Addon.Vendor";    //$NON-NLS-1$
-
-    private final String mVendor;
-    private final String mName;
-    private final AndroidVersion mVersion;
-
-    /** An add-on library. */
-    public static class Lib {
-        private final String mName;
-        private final String mDescription;
-
-        public Lib(String name, String description) {
-            mName = name;
-            mDescription = description;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public String getDescription() {
-            return mDescription;
-        }
-    }
-
-    private final Lib[] mLibs;
-
-    /**
-     * Creates a new add-on package from the attributes and elements of the given XML node.
-     * <p/>
-     * This constructor should throw an exception if the package cannot be created.
-     */
-    AddonPackage(RepoSource source, Node packageNode, Map<String,String> licenses) {
-        super(source, packageNode, licenses);
-        mVendor   = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_VENDOR);
-        mName     = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_NAME);
-        int apiLevel = XmlParserUtils.getXmlInt   (packageNode, SdkRepository.NODE_API_LEVEL, 0);
-        String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_CODENAME);
-        if (codeName.length() == 0) {
-            codeName = null;
-        }
-        mVersion = new AndroidVersion(apiLevel, codeName);
-
-        mLibs = parseLibs(XmlParserUtils.getFirstChild(packageNode, SdkRepository.NODE_LIBS));
-    }
-
-    /**
-     * Creates a new platform package based on an actual {@link IAndroidTarget} (which
-     * {@link IAndroidTarget#isPlatform()} false) from the {@link SdkManager}.
-     * This is used to list local SDK folders in which case there is one archive which
-     * URL is the actual target location.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    AddonPackage(IAndroidTarget target, Properties props) {
-        super(  null,                       //source
-                props,                      //properties
-                target.getRevision(),       //revision
-                null,                       //license
-                target.getDescription(),    //description
-                null,                       //descUrl
-                Os.getCurrentOs(),          //archiveOs
-                Arch.getCurrentArch(),      //archiveArch
-                target.getLocation()        //archiveOsPath
-                );
-
-        mVersion = target.getVersion();
-        mName     = target.getName();
-        mVendor   = target.getVendor();
-
-        IOptionalLibrary[] optLibs = target.getOptionalLibraries();
-        if (optLibs == null || optLibs.length == 0) {
-            mLibs = new Lib[0];
-        } else {
-            mLibs = new Lib[optLibs.length];
-            for (int i = 0; i < optLibs.length; i++) {
-                mLibs[i] = new Lib(optLibs[i].getName(), optLibs[i].getDescription());
-            }
-        }
-    }
-
-    /**
-     * Save the properties of the current packages in the given {@link Properties} object.
-     * These properties will later be given to a constructor that takes a {@link Properties} object.
-     */
-    @Override
-    void saveProperties(Properties props) {
-        super.saveProperties(props);
-
-        mVersion.saveProperties(props);
-        if (mName != null) {
-            props.setProperty(PROP_NAME, mName);
-        }
-        if (mVendor != null) {
-            props.setProperty(PROP_VENDOR, mVendor);
-        }
-    }
-
-    /**
-     * Parses a <libs> element.
-     */
-    private Lib[] parseLibs(Node libsNode) {
-        ArrayList<Lib> libs = new ArrayList<Lib>();
-
-        if (libsNode != null) {
-            String nsUri = libsNode.getNamespaceURI();
-            for(Node child = libsNode.getFirstChild();
-                child != null;
-                child = child.getNextSibling()) {
-
-                if (child.getNodeType() == Node.ELEMENT_NODE &&
-                        nsUri.equals(child.getNamespaceURI()) &&
-                        SdkRepository.NODE_LIB.equals(child.getLocalName())) {
-                    libs.add(parseLib(child));
-                }
-            }
-        }
-
-        return libs.toArray(new Lib[libs.size()]);
-    }
-
-    /**
-     * Parses a <lib> element from a <libs> container.
-     */
-    private Lib parseLib(Node libNode) {
-        return new Lib(XmlParserUtils.getXmlString(libNode, SdkRepository.NODE_NAME),
-                       XmlParserUtils.getXmlString(libNode, SdkRepository.NODE_DESCRIPTION));
-    }
-
-    /** Returns the vendor, a string, for add-on packages. */
-    public String getVendor() {
-        return mVendor;
-    }
-
-    /** Returns the name, a string, for add-on packages or for libraries. */
-    public String getName() {
-        return mName;
-    }
-
-    /** Returns the version, for platform, add-on and doc packages. */
-    public AndroidVersion getVersion() {
-        return mVersion;
-    }
-
-    /** Returns the libs defined in this add-on. Can be an empty array but not null. */
-    public Lib[] getLibs() {
-        return mLibs;
-    }
-
-    /** Returns a short description for an {@link IDescription}. */
-    @Override
-    public String getShortDescription() {
-        return String.format("%1$s by %2$s, Android API %3$s, revision %4$s",
-                getName(),
-                getVendor(),
-                mVersion.getApiString(),
-                getRevision());
-    }
-
-    /**
-     * Returns a long description for an {@link IDescription}.
-     *
-     * The long description is whatever the XML contains for the &lt;description&gt; field,
-     * or the short description if the former is empty.
-     */
-    @Override
-    public String getLongDescription() {
-        String s = getDescription();
-        if (s == null || s.length() == 0) {
-            s = getShortDescription();
-        }
-
-        if (s.indexOf("revision") == -1) {
-            s += String.format("\nRevision %1$d", getRevision());
-        }
-
-        s += String.format("\nRequires SDK Platform Android API %1$s",
-                mVersion.getApiString());
-        return s;
-    }
-
-    /**
-     * Computes a potential installation folder if an archive of this package were
-     * to be installed right away in the given SDK root.
-     * <p/>
-     * An add-on package is typically installed in SDK/add-ons/"addon-name"-"api-level".
-     * The name needs to be sanitized to be acceptable as a directory name.
-     * However if we can find a different directory under SDK/add-ons that already
-     * has this add-ons installed, we'll use that one.
-     *
-     * @param osSdkRoot The OS path of the SDK root folder.
-     * @param suggestedDir A suggestion for the installation folder name, based on the root
-     *                     folder used in the zip archive.
-     * @param sdkManager An existing SDK manager to list current platforms and addons.
-     * @return A new {@link File} corresponding to the directory to use to install this package.
-     */
-    @Override
-    public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
-        File addons = new File(osSdkRoot, SdkConstants.FD_ADDONS);
-
-        // First find if this add-on is already installed. If so, reuse the same directory.
-        for (IAndroidTarget target : sdkManager.getTargets()) {
-            if (!target.isPlatform() &&
-                    target.getVersion().equals(mVersion) &&
-                    target.getName().equals(getName()) &&
-                    target.getVendor().equals(getVendor())) {
-                return new File(target.getLocation());
-            }
-        }
-
-        // Otherwise, see about reusing the suggestedDir. It must not be already used or
-        // add some index to it, or we try to make up one.
-        String name = suggestedDir;
-
-        if (suggestedDir == null || suggestedDir.length() == 0) {
-            name = String.format("addon-%s-%s-%s", getName(), getVendor(), //$NON-NLS-1$
-                    mVersion.getApiString());
-            name = name.toLowerCase();
-            name = name.replaceAll("[^a-z0-9_-]+", "_");      //$NON-NLS-1$ //$NON-NLS-2$
-            name = name.replaceAll("_+", "_");                //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        for (int i = 0; i < 100; i++) {
-            String name2 = i == 0 ? name : String.format("%s-%d", name, i); //$NON-NLS-1$
-            File folder = new File(addons, name2);
-            if (!folder.exists()) {
-                return folder;
-            }
-        }
-
-        // We shouldn't really get here. I mean, seriously, we tried hard enough.
-        return null;
-    }
-
-    @Override
-    public boolean sameItemAs(Package pkg) {
-        if (pkg instanceof AddonPackage) {
-            AddonPackage newPkg = (AddonPackage)pkg;
-
-            // check they are the same add-on.
-            return getName().equals(newPkg.getName()) &&
-                    getVendor().equals(newPkg.getVendor()) &&
-                    getVersion().equals(newPkg.getVersion());
-        }
-
-        return false;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java
deleted file mode 100755
index 18774ea..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java
+++ /dev/null
@@ -1,1073 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-
-import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
-import org.apache.commons.compress.archivers.zip.ZipFile;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Enumeration;
-import java.util.Properties;
-
-
-/**
- * A {@link Archive} is the base class for "something" that can be downloaded from
- * the SDK repository -- subclasses include {@link PlatformPackage}, {@link AddonPackage},
- * {@link DocPackage} and {@link ToolPackage}.
- * <p/>
- * A package has some attributes (revision, description) and a list of archives
- * which represent the downloadable bits.
- * <p/>
- * Packages are contained in offered by a {@link RepoSource} (a download site).
- */
-public class Archive implements IDescription {
-
-    public static final int NUM_MONITOR_INC = 100;
-    private static final String PROP_OS   = "Archive.Os";       //$NON-NLS-1$
-    private static final String PROP_ARCH = "Archive.Arch";     //$NON-NLS-1$
-
-    /** The checksum type. */
-    public enum ChecksumType {
-        /** A SHA1 checksum, represented as a 40-hex string. */
-        SHA1("SHA-1");  //$NON-NLS-1$
-
-        private final String mAlgorithmName;
-
-        /**
-         * Constructs a {@link ChecksumType} with the algorigth name
-         * suitable for {@link MessageDigest#getInstance(String)}.
-         * <p/>
-         * These names are officially documented at
-         * http://java.sun.com/javase/6/docs/technotes/guides/security/StandardNames.html#MessageDigest
-         */
-        private ChecksumType(String algorithmName) {
-            mAlgorithmName = algorithmName;
-        }
-
-        /**
-         * Returns a new {@link MessageDigest} instance for this checksum type.
-         * @throws NoSuchAlgorithmException if this algorithm is not available.
-         */
-        public MessageDigest getMessageDigest() throws NoSuchAlgorithmException {
-            return MessageDigest.getInstance(mAlgorithmName);
-        }
-    }
-
-    /** The OS that this archive can be downloaded on. */
-    public enum Os {
-        ANY("Any"),
-        LINUX("Linux"),
-        MACOSX("MacOS X"),
-        WINDOWS("Windows");
-
-        private final String mUiName;
-
-        private Os(String uiName) {
-            mUiName = uiName;
-        }
-
-        /** Returns the UI name of the OS. */
-        public String getUiName() {
-            return mUiName;
-        }
-
-        /** Returns the XML name of the OS. */
-        public String getXmlName() {
-            return toString().toLowerCase();
-        }
-
-        /**
-         * Returns the current OS as one of the {@link Os} enum values or null.
-         */
-        public static Os getCurrentOs() {
-            String os = System.getProperty("os.name");          //$NON-NLS-1$
-            if (os.startsWith("Mac")) {                         //$NON-NLS-1$
-                return Os.MACOSX;
-
-            } else if (os.startsWith("Windows")) {              //$NON-NLS-1$
-                return Os.WINDOWS;
-
-            } else if (os.startsWith("Linux")) {                //$NON-NLS-1$
-                return Os.LINUX;
-            }
-
-            return null;
-        }
-
-        /** Returns true if this OS is compatible with the current one. */
-        public boolean isCompatible() {
-            if (this == ANY) {
-                return true;
-            }
-
-            Os os = getCurrentOs();
-            return this == os;
-        }
-    }
-
-    /** The Architecture that this archive can be downloaded on. */
-    public enum Arch {
-        ANY("Any"),
-        PPC("PowerPC"),
-        X86("x86"),
-        X86_64("x86_64");
-
-        private final String mUiName;
-
-        private Arch(String uiName) {
-            mUiName = uiName;
-        }
-
-        /** Returns the UI name of the architecture. */
-        public String getUiName() {
-            return mUiName;
-        }
-
-        /** Returns the XML name of the architecture. */
-        public String getXmlName() {
-            return toString().toLowerCase();
-        }
-
-        /**
-         * Returns the current architecture as one of the {@link Arch} enum values or null.
-         */
-        public static Arch getCurrentArch() {
-            // Values listed from http://lopica.sourceforge.net/os.html
-            String arch = System.getProperty("os.arch");
-
-            if (arch.equalsIgnoreCase("x86_64") || arch.equalsIgnoreCase("amd64")) {
-                return Arch.X86_64;
-
-            } else if (arch.equalsIgnoreCase("x86")
-                    || arch.equalsIgnoreCase("i386")
-                    || arch.equalsIgnoreCase("i686")) {
-                return Arch.X86;
-
-            } else if (arch.equalsIgnoreCase("ppc") || arch.equalsIgnoreCase("PowerPC")) {
-                return Arch.PPC;
-            }
-
-            return null;
-        }
-
-        /** Returns true if this architecture is compatible with the current one. */
-        public boolean isCompatible() {
-            if (this == ANY) {
-                return true;
-            }
-
-            Arch arch = getCurrentArch();
-            return this == arch;
-        }
-    }
-
-    private final Os     mOs;
-    private final Arch   mArch;
-    private final String mUrl;
-    private final long   mSize;
-    private final String mChecksum;
-    private final ChecksumType mChecksumType = ChecksumType.SHA1;
-    private final Package mPackage;
-    private final String mLocalOsPath;
-    private final boolean mIsLocal;
-
-    /**
-     * Creates a new remote archive.
-     */
-    Archive(Package pkg, Os os, Arch arch, String url, long size, String checksum) {
-        mPackage = pkg;
-        mOs = os;
-        mArch = arch;
-        mUrl = url;
-        mLocalOsPath = null;
-        mSize = size;
-        mChecksum = checksum;
-        mIsLocal = false;
-    }
-
-    /**
-     * Creates a new local archive.
-     * Uses the properties from props first, if possible. Props can be null.
-     */
-    Archive(Package pkg, Properties props, Os os, Arch arch, String localOsPath) {
-        mPackage = pkg;
-
-        mOs   = props == null ? os   : Os.valueOf(  props.getProperty(PROP_OS,   os.toString()));
-        mArch = props == null ? arch : Arch.valueOf(props.getProperty(PROP_ARCH, arch.toString()));
-
-        mUrl = null;
-        mLocalOsPath = localOsPath;
-        mSize = 0;
-        mChecksum = "";
-        mIsLocal = true;
-    }
-
-    /**
-     * Save the properties of the current archive in the give {@link Properties} object.
-     * These properties will later be give the constructor that takes a {@link Properties} object.
-     */
-    void saveProperties(Properties props) {
-        props.setProperty(PROP_OS,   mOs.toString());
-        props.setProperty(PROP_ARCH, mArch.toString());
-    }
-
-    /**
-     * Returns true if this is a locally installed archive.
-     * Returns false if this is a remote archive that needs to be downloaded.
-     */
-    public boolean isLocal() {
-        return mIsLocal;
-    }
-
-    /**
-     * Returns the package that created and owns this archive.
-     * It should generally not be null.
-     */
-    public Package getParentPackage() {
-        return mPackage;
-    }
-
-    /**
-     * Returns the archive size, an int > 0.
-     * Size will be 0 if this a local installed folder of unknown size.
-     */
-    public long getSize() {
-        return mSize;
-    }
-
-    /**
-     * Returns the SHA1 archive checksum, as a 40-char hex.
-     * Can be empty but not null for local installed folders.
-     */
-    public String getChecksum() {
-        return mChecksum;
-    }
-
-    /**
-     * Returns the checksum type, always {@link ChecksumType#SHA1} right now.
-     */
-    public ChecksumType getChecksumType() {
-        return mChecksumType;
-    }
-
-    /**
-     * Returns the download archive URL, either absolute or relative to the repository xml.
-     * Always return null for a local installed folder.
-     * @see #getLocalOsPath()
-     */
-    public String getUrl() {
-        return mUrl;
-    }
-
-    /**
-     * Returns the local OS folder where a local archive is installed.
-     * Always return null for remote archives.
-     * @see #getUrl()
-     */
-    public String getLocalOsPath() {
-        return mLocalOsPath;
-    }
-
-    /**
-     * Returns the archive {@link Os} enum.
-     * Can be null for a local installed folder on an unknown OS.
-     */
-    public Os getOs() {
-        return mOs;
-    }
-
-    /**
-     * Returns the archive {@link Arch} enum.
-     * Can be null for a local installed folder on an unknown architecture.
-     */
-    public Arch getArch() {
-        return mArch;
-    }
-
-    /**
-     * Generates a description for this archive of the OS/Arch supported by this archive.
-     */
-    public String getOsDescription() {
-        String os;
-        if (mOs == null) {
-            os = "unknown OS";
-        } else if (mOs == Os.ANY) {
-            os = "any OS";
-        } else {
-            os = mOs.getUiName();
-        }
-
-        String arch = "";                               //$NON-NLS-1$
-        if (mArch != null && mArch != Arch.ANY) {
-            arch = mArch.getUiName();
-        }
-
-        return String.format("%1$s%2$s%3$s",
-                os,
-                arch.length() > 0 ? " " : "",           //$NON-NLS-2$
-                arch);
-    }
-
-    /**
-     * Generates a short description for this archive.
-     */
-    public String getShortDescription() {
-        return String.format("Archive for %1$s", getOsDescription());
-    }
-
-    /**
-     * Generates a longer description for this archive.
-     */
-    public String getLongDescription() {
-        return String.format("%1$s\nSize: %2$d MiB\nSHA1: %3$s",
-                getShortDescription(),
-                Math.round(getSize() / (1024*1024)),
-                getChecksum());
-    }
-
-    /**
-     * Returns true if this archive can be installed on the current platform.
-     */
-    public boolean isCompatible() {
-        return getOs().isCompatible() && getArch().isCompatible();
-    }
-
-    /**
-     * Delete the archive folder if this is a local archive.
-     */
-    public void deleteLocal() {
-        if (isLocal()) {
-            deleteFileOrFolder(new File(getLocalOsPath()));
-        }
-    }
-
-    /**
-     * Install this {@link Archive}s.
-     * The archive will be skipped if it is incompatible.
-     *
-     * @return True if the archive was installed, false otherwise.
-     */
-    public boolean install(String osSdkRoot,
-            boolean forceHttp,
-            SdkManager sdkManager,
-            ITaskMonitor monitor) {
-
-        Package pkg = getParentPackage();
-
-        File archiveFile = null;
-        String name = pkg.getShortDescription();
-
-        if (pkg instanceof ExtraPackage && !((ExtraPackage) pkg).isPathValid()) {
-            monitor.setResult("Skipping %1$s: %2$s is not a valid install path.",
-                    name,
-                    ((ExtraPackage) pkg).getPath());
-            return false;
-        }
-
-        if (isLocal()) {
-            // This should never happen.
-            monitor.setResult("Skipping already installed archive: %1$s for %2$s",
-                    name,
-                    getOsDescription());
-            return false;
-        }
-
-        if (!isCompatible()) {
-            monitor.setResult("Skipping incompatible archive: %1$s for %2$s",
-                    name,
-                    getOsDescription());
-            return false;
-        }
-
-        archiveFile = downloadFile(osSdkRoot, monitor, forceHttp);
-        if (archiveFile != null) {
-            if (unarchive(osSdkRoot, archiveFile, sdkManager, monitor)) {
-                monitor.setResult("Installed %1$s", name);
-                // Delete the temp archive if it exists, only on success
-                deleteFileOrFolder(archiveFile);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Downloads an archive and returns the temp file with it.
-     * Caller is responsible with deleting the temp file when done.
-     */
-    private File downloadFile(String osSdkRoot, ITaskMonitor monitor, boolean forceHttp) {
-
-        String name = getParentPackage().getShortDescription();
-        String desc = String.format("Downloading %1$s", name);
-        monitor.setDescription(desc);
-        monitor.setResult(desc);
-
-        String link = getUrl();
-        if (!link.startsWith("http://")                          //$NON-NLS-1$
-                && !link.startsWith("https://")                  //$NON-NLS-1$
-                && !link.startsWith("ftp://")) {                 //$NON-NLS-1$
-            // Make the URL absolute by prepending the source
-            Package pkg = getParentPackage();
-            RepoSource src = pkg.getParentSource();
-            if (src == null) {
-                monitor.setResult("Internal error: no source for archive %1$s", name);
-                return null;
-            }
-
-            // take the URL to the repository.xml and remove the last component
-            // to get the base
-            String repoXml = src.getUrl();
-            int pos = repoXml.lastIndexOf('/');
-            String base = repoXml.substring(0, pos + 1);
-
-            link = base + link;
-        }
-
-        if (forceHttp) {
-            link = link.replaceAll("https://", "http://");  //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        // Get the basename of the file we're downloading, i.e. the last component
-        // of the URL
-        int pos = link.lastIndexOf('/');
-        String base = link.substring(pos + 1);
-
-        // Rather than create a real temp file in the system, we simply use our
-        // temp folder (in the SDK base folder) and use the archive name for the
-        // download. This allows us to reuse or continue downloads.
-
-        File tmpFolder = getTempFolder(osSdkRoot);
-        if (!tmpFolder.isDirectory()) {
-            if (tmpFolder.isFile()) {
-                deleteFileOrFolder(tmpFolder);
-            }
-            if (!tmpFolder.mkdirs()) {
-                monitor.setResult("Failed to create directory %1$s", tmpFolder.getPath());
-                return null;
-            }
-        }
-        File tmpFile = new File(tmpFolder, base);
-
-        // if the file exists, check if its checksum & size. Use it if complete
-        if (tmpFile.exists()) {
-            if (tmpFile.length() == getSize() &&
-                    fileChecksum(tmpFile, monitor).equalsIgnoreCase(getChecksum())) {
-                // File is good, let's use it.
-                return tmpFile;
-            }
-
-            // Existing file is either of different size or content.
-            // TODO: continue download when we support continue mode.
-            // Right now, let's simply remove the file and start over.
-            deleteFileOrFolder(tmpFile);
-        }
-
-        if (fetchUrl(tmpFile, link, desc, monitor)) {
-            // Fetching was successful, let's use this file.
-            return tmpFile;
-        } else {
-            // Delete the temp file if we aborted the download
-            // TODO: disable this when we want to support partial downloads!
-            deleteFileOrFolder(tmpFile);
-            return null;
-        }
-    }
-
-    /**
-     * Computes the SHA-1 checksum of the content of the given file.
-     * Returns an empty string on error (rather than null).
-     */
-    private String fileChecksum(File tmpFile, ITaskMonitor monitor) {
-        InputStream is = null;
-        try {
-            is = new FileInputStream(tmpFile);
-
-            MessageDigest digester = getChecksumType().getMessageDigest();
-
-            byte[] buf = new byte[65536];
-            int n;
-
-            while ((n = is.read(buf)) >= 0) {
-                if (n > 0) {
-                    digester.update(buf, 0, n);
-                }
-            }
-
-            return getDigestChecksum(digester);
-
-        } catch (FileNotFoundException e) {
-            // The FNF message is just the URL. Make it a bit more useful.
-            monitor.setResult("File not found: %1$s", e.getMessage());
-
-        } catch (Exception e) {
-            monitor.setResult(e.getMessage());
-
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    // pass
-                }
-            }
-        }
-
-        return "";  //$NON-NLS-1$
-    }
-
-    /**
-     * Returns the SHA-1 from a {@link MessageDigest} as an hex string
-     * that can be compared with {@link #getChecksum()}.
-     */
-    private String getDigestChecksum(MessageDigest digester) {
-        int n;
-        // Create an hex string from the digest
-        byte[] digest = digester.digest();
-        n = digest.length;
-        String hex = "0123456789abcdef";                     //$NON-NLS-1$
-        char[] hexDigest = new char[n * 2];
-        for (int i = 0; i < n; i++) {
-            int b = digest[i] & 0x0FF;
-            hexDigest[i*2 + 0] = hex.charAt(b >>> 4);
-            hexDigest[i*2 + 1] = hex.charAt(b & 0x0f);
-        }
-
-        return new String(hexDigest);
-    }
-
-    /**
-     * Actually performs the download.
-     * Also computes the SHA1 of the file on the fly.
-     * <p/>
-     * Success is defined as downloading as many bytes as was expected and having the same
-     * SHA1 as expected. Returns true on success or false if any of those checks fail.
-     * <p/>
-     * Increments the monitor by {@link #NUM_MONITOR_INC}.
-     */
-    private boolean fetchUrl(File tmpFile,
-            String urlString,
-            String description,
-            ITaskMonitor monitor) {
-        URL url;
-
-        description += " (%1$d%%, %2$.0f KiB/s, %3$d %4$s left)";
-
-        FileOutputStream os = null;
-        InputStream is = null;
-        try {
-            url = new URL(urlString);
-            is = url.openStream();
-            os = new FileOutputStream(tmpFile);
-
-            MessageDigest digester = getChecksumType().getMessageDigest();
-
-            byte[] buf = new byte[65536];
-            int n;
-
-            long total = 0;
-            long size = getSize();
-            long inc = size / NUM_MONITOR_INC;
-            long next_inc = inc;
-
-            long startMs = System.currentTimeMillis();
-            long nextMs = startMs + 2000;  // start update after 2 seconds
-
-            while ((n = is.read(buf)) >= 0) {
-                if (n > 0) {
-                    os.write(buf, 0, n);
-                    digester.update(buf, 0, n);
-                }
-
-                long timeMs = System.currentTimeMillis();
-
-                total += n;
-                if (total >= next_inc) {
-                    monitor.incProgress(1);
-                    next_inc += inc;
-                }
-
-                if (timeMs > nextMs) {
-                    long delta = timeMs - startMs;
-                    if (total > 0 && delta > 0) {
-                        // percent left to download
-                        int percent = (int) (100 * total / size);
-                        // speed in KiB/s
-                        float speed = (float)total / (float)delta * (1000.f / 1024.f);
-                        // time left to download the rest at the current KiB/s rate
-                        int timeLeft = (speed > 1e-3) ?
-                                               (int)(((size - total) / 1024.0f) / speed) :
-                                               0;
-                        String timeUnit = "seconds";
-                        if (timeLeft > 120) {
-                            timeUnit = "minutes";
-                            timeLeft /= 60;
-                        }
-
-                        monitor.setDescription(description, percent, speed, timeLeft, timeUnit);
-                    }
-                    nextMs = timeMs + 1000;  // update every second
-                }
-
-                if (monitor.isCancelRequested()) {
-                    monitor.setResult("Download aborted by user at %1$d bytes.", total);
-                    return false;
-                }
-
-            }
-
-            if (total != size) {
-                monitor.setResult("Download finished with wrong size. Expected %1$d bytes, got %2$d bytes.",
-                        size, total);
-                return false;
-            }
-
-            // Create an hex string from the digest
-            String actual   = getDigestChecksum(digester);
-            String expected = getChecksum();
-            if (!actual.equalsIgnoreCase(expected)) {
-                monitor.setResult("Download finished with wrong checksum. Expected %1$s, got %2$s.",
-                        expected, actual);
-                return false;
-            }
-
-            return true;
-
-        } catch (FileNotFoundException e) {
-            // The FNF message is just the URL. Make it a bit more useful.
-            monitor.setResult("File not found: %1$s", e.getMessage());
-
-        } catch (Exception e) {
-            monitor.setResult(e.getMessage());
-
-        } finally {
-            if (os != null) {
-                try {
-                    os.close();
-                } catch (IOException e) {
-                    // pass
-                }
-            }
-
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    // pass
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Install the given archive in the given folder.
-     */
-    private boolean unarchive(String osSdkRoot,
-            File archiveFile,
-            SdkManager sdkManager,
-            ITaskMonitor monitor) {
-        String pkgName = getParentPackage().getShortDescription();
-        String pkgDesc = String.format("Installing %1$s", pkgName);
-        monitor.setDescription(pkgDesc);
-        monitor.setResult(pkgDesc);
-
-        // We always unzip in a temp folder which name depends on the package type
-        // (e.g. addon, tools, etc.) and then move the folder to the destination folder.
-        // If the destination folder exists, it will be renamed and deleted at the very
-        // end if everything succeeded.
-
-        String pkgKind = getParentPackage().getClass().getSimpleName();
-
-        File destFolder = null;
-        File unzipDestFolder = null;
-        File renamedDestFolder = null;
-
-        try {
-            // Find a new temp folder that doesn't exist yet
-            unzipDestFolder = createTempFolder(osSdkRoot, pkgKind, "new");  //$NON-NLS-1$
-
-            if (unzipDestFolder == null) {
-                // this should not seriously happen.
-                monitor.setResult("Failed to find a temp directory in %1$s.", osSdkRoot);
-                return false;
-            }
-
-            if (!unzipDestFolder.mkdirs()) {
-                monitor.setResult("Failed to create directory %1$s", unzipDestFolder.getPath());
-                return false;
-            }
-
-            String[] zipRootFolder = new String[] { null };
-            if (!unzipFolder(archiveFile, getSize(),
-                    unzipDestFolder, pkgDesc,
-                    zipRootFolder, monitor)) {
-                return false;
-            }
-
-            if (!generateSourceProperties(unzipDestFolder)) {
-                return false;
-            }
-
-            // Compute destination directory
-            destFolder = getParentPackage().getInstallFolder(
-                    osSdkRoot, zipRootFolder[0], sdkManager);
-
-            if (destFolder == null) {
-                // this should not seriously happen.
-                monitor.setResult("Failed to compute installation directory for %1$s.", pkgName);
-                return false;
-            }
-
-            // Swap the old folder by the new one.
-            // We have 2 "folder rename" (aka moves) to do.
-            // They must both succeed in the right order.
-            boolean move1done = false;
-            boolean move2done = false;
-            while (!move1done || !move2done) {
-                File renameFailedForDir = null;
-
-                // Case where the dest dir already exists
-                if (!move1done) {
-                    if (destFolder.isDirectory()) {
-                        // Create a new temp/old dir
-                        if (renamedDestFolder == null) {
-                            renamedDestFolder = createTempFolder(osSdkRoot, pkgKind, "old");  //$NON-NLS-1$
-                        }
-                        if (renamedDestFolder == null) {
-                            // this should not seriously happen.
-                            monitor.setResult("Failed to find a temp directory in %1$s.", osSdkRoot);
-                            return false;
-                        }
-
-                        // try to move the current dest dir to the temp/old one
-                        if (!destFolder.renameTo(renamedDestFolder)) {
-                            monitor.setResult("Failed to rename directory %1$s to %2$s.",
-                                    destFolder.getPath(), renamedDestFolder.getPath());
-                            renameFailedForDir = destFolder;
-                        }
-                    }
-
-                    move1done = (renameFailedForDir == null);
-                }
-
-                // Case where there's no dest dir or we successfully moved it to temp/old
-                // We not try to move the temp/unzip to the dest dir
-                if (move1done && !move2done) {
-                    if (renameFailedForDir == null && !unzipDestFolder.renameTo(destFolder)) {
-                        monitor.setResult("Failed to rename directory %1$s to %2$s",
-                                unzipDestFolder.getPath(), destFolder.getPath());
-                        renameFailedForDir = unzipDestFolder;
-                    }
-
-                    move2done = (renameFailedForDir == null);
-                }
-
-                if (renameFailedForDir != null) {
-                    if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) {
-
-                        String msg = String.format(
-                                "-= Warning ! =-\n" +
-                                "A folder failed to be renamed or moved. On Windows this " +
-                                "typically means that a program is using that folder (for example " +
-                                "Windows Explorer or your anti-virus software.)\n" +
-                                "Please momentarily deactivate your anti-virus software.\n" +
-                                "Please also close any running programs that may be accessing " +
-                                "the directory '%1$s'.\n" +
-                                "When ready, press YES to try again.",
-                                renameFailedForDir.getPath());
-
-                        if (monitor.displayPrompt("SDK Manager: failed to install", msg)) {
-                            // loop, trying to rename the temp dir into the destination
-                            continue;
-                        }
-
-                    }
-                    return false;
-                }
-                break;
-            }
-
-            unzipDestFolder = null;
-            return true;
-
-        } finally {
-            // Cleanup if the unzip folder is still set.
-            deleteFileOrFolder(renamedDestFolder);
-            deleteFileOrFolder(unzipDestFolder);
-        }
-    }
-
-    /**
-     * Unzips a zip file into the given destination directory.
-     *
-     * The archive file MUST have a unique "root" folder. This root folder is skipped when
-     * unarchiving. However we return that root folder name to the caller, as it can be used
-     * as a template to know what destination directory to use in the Add-on case.
-     */
-    @SuppressWarnings("unchecked")
-    private boolean unzipFolder(File archiveFile,
-            long compressedSize,
-            File unzipDestFolder,
-            String description,
-            String[] outZipRootFolder,
-            ITaskMonitor monitor) {
-
-        description += " (%1$d%%)";
-
-        ZipFile zipFile = null;
-        try {
-            zipFile = new ZipFile(archiveFile);
-
-            // figure if we'll need to set the unix permission
-            boolean usingUnixPerm = SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN ||
-                    SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_LINUX;
-
-            // To advance the percent and the progress bar, we don't know the number of
-            // items left to unzip. However we know the size of the archive and the size of
-            // each uncompressed item. The zip file format overhead is negligible so that's
-            // a good approximation.
-            long incStep = compressedSize / NUM_MONITOR_INC;
-            long incTotal = 0;
-            long incCurr = 0;
-            int lastPercent = 0;
-
-            byte[] buf = new byte[65536];
-
-            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
-            while (entries.hasMoreElements()) {
-                ZipArchiveEntry entry = entries.nextElement();
-
-                String name = entry.getName();
-
-                // ZipFile entries should have forward slashes, but not all Zip
-                // implementations can be expected to do that.
-                name = name.replace('\\', '/');
-
-                // Zip entries are always packages in a top-level directory
-                // (e.g. docs/index.html). However we want to use our top-level
-                // directory so we drop the first segment of the path name.
-                int pos = name.indexOf('/');
-                if (pos < 0 || pos == name.length() - 1) {
-                    continue;
-                } else {
-                    if (outZipRootFolder[0] == null && pos > 0) {
-                        outZipRootFolder[0] = name.substring(0, pos);
-                    }
-                    name = name.substring(pos + 1);
-                }
-
-                File destFile = new File(unzipDestFolder, name);
-
-                if (name.endsWith("/")) {  //$NON-NLS-1$
-                    // Create directory if it doesn't exist yet. This allows us to create
-                    // empty directories.
-                    if (!destFile.isDirectory() && !destFile.mkdirs()) {
-                        monitor.setResult("Failed to create temp directory %1$s",
-                                destFile.getPath());
-                        return false;
-                    }
-                    continue;
-                } else if (name.indexOf('/') != -1) {
-                    // Otherwise it's a file in a sub-directory.
-                    // Make sure the parent directory has been created.
-                    File parentDir = destFile.getParentFile();
-                    if (!parentDir.isDirectory()) {
-                        if (!parentDir.mkdirs()) {
-                            monitor.setResult("Failed to create temp directory %1$s",
-                                    parentDir.getPath());
-                            return false;
-                        }
-                    }
-                }
-
-                FileOutputStream fos = null;
-                try {
-                    fos = new FileOutputStream(destFile);
-                    int n;
-                    InputStream entryContent = zipFile.getInputStream(entry);
-                    while ((n = entryContent.read(buf)) != -1) {
-                        if (n > 0) {
-                            fos.write(buf, 0, n);
-                        }
-                    }
-                } finally {
-                    if (fos != null) {
-                        fos.close();
-                    }
-                }
-
-                // if needed set the permissions.
-                if (usingUnixPerm && destFile.isFile()) {
-                    // get the mode and test if it contains the executable bit
-                    int mode = entry.getUnixMode();
-                    if ((mode & 0111) != 0) {
-                        setExecutablePermission(destFile);
-                    }
-                }
-
-                // Increment progress bar to match. We update only between files.
-                for(incTotal += entry.getCompressedSize(); incCurr < incTotal; incCurr += incStep) {
-                    monitor.incProgress(1);
-                }
-
-                int percent = (int) (100 * incTotal / compressedSize);
-                if (percent != lastPercent) {
-                    monitor.setDescription(description, percent);
-                    lastPercent = percent;
-                }
-
-                if (monitor.isCancelRequested()) {
-                    return false;
-                }
-            }
-
-            return true;
-
-        } catch (IOException e) {
-            monitor.setResult("Unzip failed: %1$s", e.getMessage());
-
-        } finally {
-            if (zipFile != null) {
-                try {
-                    zipFile.close();
-                } catch (IOException e) {
-                    // pass
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Creates a temp folder in the form of osBasePath/temp/prefix.suffixNNN.
-     * <p/>
-     * This operation is not atomic so there's no guarantee the folder can't get
-     * created in between. This is however unlikely and the caller can assume the
-     * returned folder does not exist yet.
-     * <p/>
-     * Returns null if no such folder can be found (e.g. if all candidates exist,
-     * which is rather unlikely) or if the base temp folder cannot be created.
-     */
-    private File createTempFolder(String osBasePath, String prefix, String suffix) {
-        File baseTempFolder = getTempFolder(osBasePath);
-
-        if (!baseTempFolder.isDirectory()) {
-            if (baseTempFolder.isFile()) {
-                deleteFileOrFolder(baseTempFolder);
-            }
-            if (!baseTempFolder.mkdirs()) {
-                return null;
-            }
-        }
-
-        for (int i = 1; i < 100; i++) {
-            File folder = new File(baseTempFolder,
-                    String.format("%1$s.%2$s%3$02d", prefix, suffix, i));  //$NON-NLS-1$
-            if (!folder.exists()) {
-                return folder;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the temp folder used by the SDK Manager.
-     * This folder is always at osBasePath/temp.
-     */
-    private File getTempFolder(String osBasePath) {
-        File baseTempFolder = new File(osBasePath, "temp");     //$NON-NLS-1$
-        return baseTempFolder;
-    }
-
-    /**
-     * Deletes a file or a directory.
-     * Directories are deleted recursively.
-     * The argument can be null.
-     */
-    private void deleteFileOrFolder(File fileOrFolder) {
-        if (fileOrFolder != null) {
-            if (fileOrFolder.isDirectory()) {
-                // Must delete content recursively first
-                for (File item : fileOrFolder.listFiles()) {
-                    deleteFileOrFolder(item);
-                }
-            }
-            if (!fileOrFolder.delete()) {
-                fileOrFolder.deleteOnExit();
-            }
-        }
-    }
-
-    /**
-     * Generates a source.properties in the destination folder that contains all the infos
-     * relevant to this archive, this package and the source so that we can reload them
-     * locally later.
-     */
-    private boolean generateSourceProperties(File unzipDestFolder) {
-        Properties props = new Properties();
-
-        saveProperties(props);
-        mPackage.saveProperties(props);
-
-        FileOutputStream fos = null;
-        try {
-            File f = new File(unzipDestFolder, LocalSdkParser.SOURCE_PROPERTIES);
-
-            fos = new FileOutputStream(f);
-
-            props.store( fos, "## Android Tool: Source of this archive.");  //$NON-NLS-1$
-
-            return true;
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Sets the executable Unix permission (0777) on a file or folder.
-     * @param file The file to set permissions on.
-     * @throws IOException If an I/O error occurs
-     */
-    private void setExecutablePermission(File file) throws IOException {
-        Runtime.getRuntime().exec(new String[] {
-           "chmod", "777", file.getAbsolutePath()
-        });
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java
deleted file mode 100755
index edc4276..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Represents a doc XML node in an SDK repository.
- */
-public class DocPackage extends Package implements IPackageVersion {
-
-    private final AndroidVersion mVersion;
-
-    /**
-     * Creates a new doc package from the attributes and elements of the given XML node.
-     * <p/>
-     * This constructor should throw an exception if the package cannot be created.
-     */
-    DocPackage(RepoSource source, Node packageNode, Map<String,String> licenses) {
-        super(source, packageNode, licenses);
-
-        int apiLevel = XmlParserUtils.getXmlInt   (packageNode, SdkRepository.NODE_API_LEVEL, 0);
-        String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_CODENAME);
-        if (codeName.length() == 0) {
-            codeName = null;
-        }
-        mVersion = new AndroidVersion(apiLevel, codeName);
-    }
-
-    /**
-     * Manually create a new package with one archive and the given attributes.
-     * This is used to create packages from local directories in which case there must be
-     * one archive which URL is the actual target location.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    DocPackage(RepoSource source,
-            Properties props,
-            int apiLevel,
-            String codename,
-            int revision,
-            String license,
-            String description,
-            String descUrl,
-            Os archiveOs,
-            Arch archiveArch,
-            String archiveOsPath) {
-        super(source,
-                props,
-                revision,
-                license,
-                description,
-                descUrl,
-                archiveOs,
-                archiveArch,
-                archiveOsPath);
-        mVersion = new AndroidVersion(props, apiLevel, codename);
-    }
-
-    /**
-     * Save the properties of the current packages in the given {@link Properties} object.
-     * These properties will later be give the constructor that takes a {@link Properties} object.
-     */
-    @Override
-    void saveProperties(Properties props) {
-        super.saveProperties(props);
-
-        mVersion.saveProperties(props);
-    }
-
-    /** Returns the version, for platform, add-on and doc packages.
-     *  Can be 0 if this is a local package of unknown api-level. */
-    public AndroidVersion getVersion() {
-        return mVersion;
-    }
-
-    /** Returns a short description for an {@link IDescription}. */
-    @Override
-    public String getShortDescription() {
-        if (mVersion.isPreview()) {
-            return String.format("Documentation for Android '%1$s' Preview SDK, revision %2$s",
-                    mVersion.getCodename(),
-                    getRevision());
-        } else {
-            return String.format("Documentation for Android SDK, API %1$d, revision %2$s",
-                    mVersion.getApiLevel(),
-                    getRevision());
-        }
-    }
-
-    /**
-     * Returns a long description for an {@link IDescription}.
-     *
-     * The long description is whatever the XML contains for the &lt;description&gt; field,
-     * or the short description if the former is empty.
-     */
-    @Override
-    public String getLongDescription() {
-        String s = getDescription();
-        if (s == null || s.length() == 0) {
-            s = getShortDescription();
-        }
-
-        if (s.indexOf("revision") == -1) {
-            s += String.format("\nRevision %1$d", getRevision());
-        }
-
-        return s;
-    }
-
-    /**
-     * Computes a potential installation folder if an archive of this package were
-     * to be installed right away in the given SDK root.
-     * <p/>
-     * A "doc" package should always be located in SDK/docs.
-     *
-     * @param osSdkRoot The OS path of the SDK root folder.
-     * @param suggestedDir A suggestion for the installation folder name, based on the root
-     *                     folder used in the zip archive.
-     * @param sdkManager An existing SDK manager to list current platforms and addons.
-     * @return A new {@link File} corresponding to the directory to use to install this package.
-     */
-    @Override
-    public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
-        return new File(osSdkRoot, SdkConstants.FD_DOCS);
-    }
-
-    @Override
-    public boolean sameItemAs(Package pkg) {
-        // only one doc package so any doc package is the same item.
-        return pkg instanceof DocPackage;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * The comparison between doc packages is a bit more complex so we override the default
-     * implementation.
-     * <p/>
-     * Docs are upgrade if they have a higher api, or a similar api but a higher revision.
-     * <p/>
-     * What makes this more complex is handling codename.
-     */
-    @Override
-    public UpdateInfo canBeUpdatedBy(Package replacementPackage) {
-        if (replacementPackage == null) {
-            return UpdateInfo.INCOMPATIBLE;
-        }
-
-        // check they are the same item.
-        if (sameItemAs(replacementPackage) == false) {
-            return UpdateInfo.INCOMPATIBLE;
-        }
-
-        DocPackage replacementDoc = (DocPackage)replacementPackage;
-
-        AndroidVersion replacementVersion = replacementDoc.getVersion();
-
-        // the new doc is an update if the api level is higher (no matter the codename on either)
-        if (replacementVersion.getApiLevel() > mVersion.getApiLevel()) {
-            return UpdateInfo.UPDATE;
-        }
-
-        // Check if they're the same exact (api and codename)
-        if (replacementVersion.equals(mVersion)) {
-            // exact same version, so check the revision level
-            if (replacementPackage.getRevision() > this.getRevision()) {
-                return UpdateInfo.UPDATE;
-            }
-        } else {
-            // not the same version? we check if they have the same api level and the new one
-            // is a preview, in which case it's also an update (since preview have the api level
-            // of the _previous_ version.)
-            if (replacementVersion.getApiLevel() == mVersion.getApiLevel() &&
-                    replacementVersion.isPreview()) {
-                return UpdateInfo.UPDATE;
-            }
-        }
-
-        // not an upgrade but not incompatible either.
-        return UpdateInfo.NOT_UPDATE;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java
deleted file mode 100755
index 7f3d0e7..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Represents a extra XML node in an SDK repository.
- */
-public class ExtraPackage extends MinToolsPackage {
-
-    private static final String PROP_PATH          = "Extra.Path";         //$NON-NLS-1$
-
-    /**
-     * The install folder name. It must be a single-segment path.
-     * The paths "add-ons", "platforms", "tools" and "docs" are reserved and cannot be used.
-     * This limitation cannot be written in the XML Schema and must be enforced here by using
-     * the method {@link #isPathValid()} *before* installing the package.
-     */
-    private final String mPath;
-
-    /**
-     * Creates a new tool package from the attributes and elements of the given XML node.
-     * <p/>
-     * This constructor should throw an exception if the package cannot be created.
-     */
-    ExtraPackage(RepoSource source, Node packageNode, Map<String,String> licenses) {
-        super(source, packageNode, licenses);
-
-        mPath = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_PATH);
-    }
-
-    /**
-     * Manually create a new package with one archive and the given attributes or properties.
-     * This is used to create packages from local directories in which case there must be
-     * one archive which URL is the actual target location.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    ExtraPackage(RepoSource source,
-            Properties props,
-            String path,
-            int revision,
-            String license,
-            String description,
-            String descUrl,
-            Os archiveOs,
-            Arch archiveArch,
-            String archiveOsPath) {
-        super(source,
-                props,
-                revision,
-                license,
-                description,
-                descUrl,
-                archiveOs,
-                archiveArch,
-                archiveOsPath);
-
-        // The path argument comes before whatever could be in the properties
-        mPath = path != null ? path : getProperty(props, PROP_PATH, path);
-    }
-
-    /**
-     * Save the properties of the current packages in the given {@link Properties} object.
-     * These properties will later be give the constructor that takes a {@link Properties} object.
-     */
-    @Override
-    void saveProperties(Properties props) {
-        super.saveProperties(props);
-
-        props.setProperty(PROP_PATH, mPath);
-
-        if (getMinToolsRevision() != MIN_TOOLS_REV_NOT_SPECIFIED) {
-            props.setProperty(PROP_MIN_TOOLS_REV, Integer.toString(getMinToolsRevision()));
-        }
-    }
-
-    /**
-     * Static helper to check if a given path is acceptable for an "extra" package.
-     */
-    public boolean isPathValid() {
-        if (SdkConstants.FD_ADDONS.equals(mPath) ||
-                SdkConstants.FD_PLATFORMS.equals(mPath) ||
-                SdkConstants.FD_TOOLS.equals(mPath) ||
-                SdkConstants.FD_DOCS.equals(mPath)) {
-            return false;
-        }
-        return mPath != null && mPath.indexOf('/') == -1 && mPath.indexOf('\\') == -1;
-    }
-
-    /**
-     * The install folder name. It must be a single-segment path.
-     * The paths "add-ons", "platforms", "tools" and "docs" are reserved and cannot be used.
-     * This limitation cannot be written in the XML Schema and must be enforced here by using
-     * the method {@link #isPathValid()} *before* installing the package.
-     */
-    public String getPath() {
-        return mPath;
-    }
-
-    /** Returns a short description for an {@link IDescription}. */
-    @Override
-    public String getShortDescription() {
-        String name = getPath();
-        if (name != null) {
-            // Uniformize all spaces in the name and upper case words.
-
-            name = name.replaceAll("[ _\t\f-]+", " ");     //$NON-NLS-1$ //$NON-NLS-2$
-
-            // Look at all lower case characters in range [1..n-1] and replace them by an upper
-            // case if they are preceded by a space. Also upper cases the first character of the
-            // string.
-            boolean changed = false;
-            char[] chars = name.toCharArray();
-            for (int n = chars.length - 1, i = 0; i < n; i++) {
-                if (Character.isLowerCase(chars[i]) && (i == 0 || chars[i - 1] == ' ')) {
-                    chars[i] = Character.toUpperCase(chars[i]);
-                    changed = true;
-                }
-            }
-            if (changed) {
-                name = new String(chars);
-            }
-        }
-
-        String s = String.format("%1$s package, revision %2$d",
-                name,
-                getRevision());
-
-        return s;
-    }
-
-    /**
-     * Returns a long description for an {@link IDescription}.
-     *
-     * The long description is whatever the XML contains for the &lt;description&gt; field,
-     * or the short description if the former is empty.
-     */
-    @Override
-    public String getLongDescription() {
-        String s = getDescription();
-        if (s == null || s.length() == 0) {
-            s = String.format("Extra %1$s package", getPath());
-        }
-
-        if (s.indexOf("revision") == -1) {
-            s += String.format("\nRevision %1$d", getRevision());
-        }
-
-        if (getMinToolsRevision() != MIN_TOOLS_REV_NOT_SPECIFIED) {
-            s += String.format("\nRequires tools revision %1$d", getMinToolsRevision());
-        }
-
-        return s;
-    }
-
-    /**
-     * Computes a potential installation folder if an archive of this package were
-     * to be installed right away in the given SDK root.
-     * <p/>
-     * A "tool" package should always be located in SDK/tools.
-     *
-     * @param osSdkRoot The OS path of the SDK root folder.
-     * @param suggestedDir A suggestion for the installation folder name, based on the root
-     *                     folder used in the zip archive.
-     * @param sdkManager An existing SDK manager to list current platforms and addons.
-     * @return A new {@link File} corresponding to the directory to use to install this package.
-     */
-    @Override
-    public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
-        return new File(osSdkRoot, getPath());
-    }
-
-    @Override
-    public boolean sameItemAs(Package pkg) {
-        // Extra packages are similar if they have the same path.
-        return pkg instanceof ExtraPackage && ((ExtraPackage)pkg).mPath.equals(mPath);
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IDescription.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IDescription.java
deleted file mode 100755
index 7af92e2..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-/**
- * Interface for elements that can provide a description of themselves.
- */
-public interface IDescription {
-
-    /**
-     * Returns a description of the given element. Cannot be null.
-     * <p/>
-     * A description is a multi-line of text, typically much more
-     * elaborate than what {@link #toString()} would provide.
-     */
-    public abstract String getShortDescription();
-
-    /**
-     * Returns a description of the given element. Cannot be null.
-     * <p/>
-     * A description is a multi-line of text, typically much more
-     * elaborate than what {@link #toString()} would provide.
-     */
-    public abstract String getLongDescription();
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IPackageVersion.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IPackageVersion.java
deleted file mode 100755
index 46d7b5d..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IPackageVersion.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.AndroidVersion;
-
-/**
- * Interface for packages that provide an {@link AndroidVersion}.
- */
-public interface IPackageVersion {
-
-    /**
-     * Returns the version, for platform, add-on and doc packages.
-     * Can be 0 if this is a local package of unknown api-level.
-     */
-    public abstract AndroidVersion getVersion();
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java
deleted file mode 100755
index 9178460..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-
-/**
- * A task that executes and can update a monitor to display its status.
- * The task will generally be run in a separate thread.
- */
-public interface ITask {
-    public abstract void run(ITaskMonitor monitor);
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java
deleted file mode 100755
index 540825c..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-/**
- * A factory that can start and run new {@link ITask}s.
- */
-public interface ITaskFactory {
-
-    public abstract void start(String title, ITask task);
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java
deleted file mode 100755
index e08e27c..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-
-/**
- * A monitor interface for a {@link ITask}.
- * <p/>
- * Depending on the task factory that created the task, there might not be any UI
- * or it might not implement all the methods, in which case calling them would be
- * a no-op but is guaranteed not to crash.
- * <p/>
- * If the task runs in a non-UI worker thread, the task factory implementation
- * will take care of the update the UI in the correct thread. The task itself
- * must not have to deal with it.
- */
-public interface ITaskMonitor {
-
-    /**
-     * Sets the description in the current task dialog.
-     * This method can be invoked from a non-UI thread.
-     */
-    public void setDescription(String descriptionFormat, Object...args);
-
-    /**
-     * Sets the result text in the current task dialog.
-     * This method can be invoked from a non-UI thread.
-     */
-    public void setResult(String resultFormat, Object...args);
-
-    /**
-     * Sets the max value of the progress bar.
-     * This method can be invoked from a non-UI thread.
-     *
-     * This method MUST be invoked once before using {@link #incProgress(int)} or
-     * {@link #getProgress()} or {@link #createSubMonitor(int)}. Callers are
-     * discouraged from using more than once -- implementations can either discard
-     * the next calls or behave incoherently.
-     */
-    public void setProgressMax(int max);
-
-    /**
-     * Increments the current value of the progress bar.
-     * This method can be invoked from a non-UI thread.
-     *
-     * Callers MUST use setProgressMax before using this method.
-     */
-    public void incProgress(int delta);
-
-    /**
-     * Returns the current value of the progress bar,
-     * between 0 and up to {@link #setProgressMax(int)} - 1.
-     *
-     * Callers MUST use setProgressMax before using this method.
-     */
-    public int getProgress();
-
-    /**
-     * Returns true if the user requested to cancel the operation.
-     * It is up to the task thread to pool this and exit as soon
-     * as possible.
-     */
-    public boolean isCancelRequested();
-
-    /**
-     * Creates a sub-monitor that will use up to tickCount on the progress bar.
-     * tickCount must be 1 or more.
-     */
-    public ITaskMonitor createSubMonitor(int tickCount);
-
-    /**
-     * Display a yes/no question dialog box.
-     *
-     * Implementations MUST allow this to be called from any thread, e.g. by
-     * making sure the dialog is opened synchronously in the ui thread.
-     *
-     * @param title The title of the dialog box
-     * @param message The error message
-     * @return true if YES was clicked.
-     */
-    public boolean displayPrompt(final String title, final String message);
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java
deleted file mode 100755
index 23ec892..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-/**
- * Scans a local SDK to find which packages are currently installed.
- */
-public class LocalSdkParser {
-
-    static final String SOURCE_PROPERTIES = "source.properties";  //$NON-NLS-1$
-    private Package[] mPackages;
-
-    public LocalSdkParser() {
-        // pass
-    }
-
-    /**
-     * Returns the packages found by the last call to
-     * {@link #parseSdk(String, SdkManager, ISdkLog)}.
-     * <p/>
-     * This returns initially returns null.
-     * Once the parseSdk() method has been called, this returns a possibly empty but non-null array.
-     */
-    public Package[] getPackages() {
-        return mPackages;
-    }
-
-    /**
-     * Clear the internal packages list. After this call, {@link #getPackages()} will return
-     * null till {@link #parseSdk(String, SdkManager, ISdkLog)} is called.
-     */
-    public void clearPackages() {
-        mPackages = null;
-    }
-
-    /**
-     * Scan the give SDK to find all the packages already installed at this location.
-     * <p/>
-     * Store the packages internally. You can use {@link #getPackages()} to retrieve them
-     * at any time later.
-     *
-     * @param osSdkRoot The path to the SDK folder.
-     * @param sdkManager An existing SDK manager to list current platforms and addons.
-     * @param log An SDK logger object.
-     * @return The packages found. Can be retrieved later using {@link #getPackages()}.
-     */
-    public Package[] parseSdk(String osSdkRoot, SdkManager sdkManager, ISdkLog log) {
-        ArrayList<Package> packages = new ArrayList<Package>();
-        HashSet<File> visited = new HashSet<File>();
-
-        File dir = new File(osSdkRoot, SdkConstants.FD_DOCS);
-        Package pkg = scanDoc(dir, log);
-        if (pkg != null) {
-            packages.add(pkg);
-            visited.add(dir);
-        }
-
-        dir = new File(osSdkRoot, SdkConstants.FD_TOOLS);
-        pkg = scanTools(dir, log);
-        if (pkg != null) {
-            packages.add(pkg);
-            visited.add(dir);
-        }
-
-        // for platforms and add-ons, rely on the SdkManager parser
-        for(IAndroidTarget target : sdkManager.getTargets()) {
-
-            Properties props = parseProperties(new File(target.getLocation(), SOURCE_PROPERTIES));
-
-            try {
-                if (target.isPlatform()) {
-                    pkg = new PlatformPackage(target, props);
-                } else {
-                    pkg = new AddonPackage(target, props);
-                }
-            } catch (Exception e) {
-                log.error(e, null);
-            }
-
-            if (pkg != null) {
-                packages.add(pkg);
-                visited.add(new File(target.getLocation()));
-            }
-        }
-
-        scanExtra(osSdkRoot, visited, packages, log);
-
-        mPackages = packages.toArray(new Package[packages.size()]);
-        return mPackages;
-    }
-
-    /**
-     * Find any other directory what we haven't successfully visited and
-     * assume they contain extra packages.
-     * @param log
-     */
-    private void scanExtra(String osSdkRoot,
-            HashSet<File> visited,
-            ArrayList<Package> packages,
-            ISdkLog log) {
-        File root = new File(osSdkRoot);
-        for (File dir : root.listFiles()) {
-            if (dir.isDirectory() && !visited.contains(dir)) {
-
-                Properties props = parseProperties(new File(dir, SOURCE_PROPERTIES));
-                if (props != null) {
-                    try {
-                        ExtraPackage pkg = new ExtraPackage(
-                                null,                       //source
-                                props,                      //properties
-                                dir.getName(),              //path
-                                0,                          //revision
-                                null,                       //license
-                                "Tools",                    //description
-                                null,                       //descUrl
-                                Os.getCurrentOs(),          //archiveOs
-                                Arch.getCurrentArch(),      //archiveArch
-                                dir.getPath()               //archiveOsPath
-                                );
-
-                        // We only accept this as an extra package if it has a valid local path.
-                        if (pkg.isPathValid()) {
-                            packages.add(pkg);
-                        }
-                    } catch (Exception e) {
-                        log.error(e, null);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Try to find a tools package at the given location.
-     * Returns null if not found.
-     */
-    private Package scanTools(File toolFolder, ISdkLog log) {
-        // Can we find some properties?
-        Properties props = parseProperties(new File(toolFolder, SOURCE_PROPERTIES));
-
-        // We're not going to check that all tools are present. At the very least
-        // we should expect to find adb, android and an emulator adapted to the current OS.
-        Set<String> names = new HashSet<String>();
-        for (File file : toolFolder.listFiles()) {
-            names.add(file.getName());
-        }
-        if (!names.contains(SdkConstants.FN_ADB) ||
-                !names.contains(SdkConstants.androidCmdName()) ||
-                !names.contains(SdkConstants.FN_EMULATOR)) {
-            return null;
-        }
-
-        // Create are package. use the properties if we found any.
-        try {
-            ToolPackage pkg = new ToolPackage(
-                    null,                       //source
-                    props,                      //properties
-                    0,                          //revision
-                    null,                       //license
-                    "Tools",                    //description
-                    null,                       //descUrl
-                    Os.getCurrentOs(),          //archiveOs
-                    Arch.getCurrentArch(),      //archiveArch
-                    toolFolder.getPath()        //archiveOsPath
-                    );
-
-            return pkg;
-        } catch (Exception e) {
-            log.error(e, null);
-        }
-        return null;
-    }
-
-    /**
-     * Try to find a docs package at the given location.
-     * Returns null if not found.
-     */
-    private Package scanDoc(File docFolder, ISdkLog log) {
-        // Can we find some properties?
-        Properties props = parseProperties(new File(docFolder, SOURCE_PROPERTIES));
-
-        // To start with, a doc folder should have an "index.html" to be acceptable.
-        // We don't actually check the content of the file.
-        if (new File(docFolder, "index.html").isFile()) {
-            try {
-                DocPackage pkg = new DocPackage(
-                        null,                       //source
-                        props,                      //properties
-                        0,                          //apiLevel
-                        null,                       //codename
-                        0,                          //revision
-                        null,                       //license
-                        null,                       //description
-                        null,                       //descUrl
-                        Os.getCurrentOs(),          //archiveOs
-                        Arch.getCurrentArch(),      //archiveArch
-                        docFolder.getPath()         //archiveOsPath
-                        );
-
-                return pkg;
-            } catch (Exception e) {
-                log.error(e, null);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Parses the given file as properties file if it exists.
-     * Returns null if the file does not exist, cannot be parsed or has no properties.
-     */
-    private Properties parseProperties(File propsFile) {
-        FileInputStream fis = null;
-        try {
-            if (propsFile.exists()) {
-                fis = new FileInputStream(propsFile);
-
-                Properties props = new Properties();
-                props.load(fis);
-
-                // To be valid, there must be at least one property in it.
-                if (props.size() > 0) {
-                    return props;
-                }
-            }
-
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-        return null;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/MinToolsPackage.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/MinToolsPackage.java
deleted file mode 100755
index d5892f3..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/MinToolsPackage.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Node;
-
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Represents an XML node in an SDK repository that has a min-tools-rev requirement.
- * This is either a {@link PlatformPackage} or an {@link ExtraPackage}.
- */
-public abstract class MinToolsPackage extends Package {
-
-    protected static final String PROP_MIN_TOOLS_REV = "Platform.MinToolsRev";  //$NON-NLS-1$
-
-    /**
-     * The minimal revision of the tools package required by this extra package, if > 0,
-     * or {@link #MIN_TOOLS_REV_NOT_SPECIFIED} if there is no such requirement.
-     */
-    private final int mMinToolsRevision;
-
-    /**
-     * The value of {@link #mMinToolsRevision} when the {@link SdkRepository#NODE_MIN_TOOLS_REV}
-     * was not specified in the XML source.
-     */
-    public static final int MIN_TOOLS_REV_NOT_SPECIFIED = 0;
-
-    /**
-     * Creates a new package from the attributes and elements of the given XML node.
-     * <p/>
-     * This constructor should throw an exception if the package cannot be created.
-     */
-    MinToolsPackage(RepoSource source, Node packageNode, Map<String,String> licenses) {
-        super(source, packageNode, licenses);
-
-        mMinToolsRevision = XmlParserUtils.getXmlInt(packageNode, SdkRepository.NODE_MIN_TOOLS_REV,
-                MIN_TOOLS_REV_NOT_SPECIFIED);
-    }
-
-    /**
-     * Manually create a new package with one archive and the given attributes.
-     * This is used to create packages from local directories in which case there must be
-     * one archive which URL is the actual target location.
-     * <p/>
-     * Properties from props are used first when possible, e.g. if props is non null.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    public MinToolsPackage(
-            RepoSource source,
-            Properties props,
-            int revision,
-            String license,
-            String description,
-            String descUrl,
-            Os archiveOs,
-            Arch archiveArch,
-            String archiveOsPath) {
-        super(source, props, revision, license, description, descUrl,
-                archiveOs, archiveArch, archiveOsPath);
-
-        mMinToolsRevision = Integer.parseInt(getProperty(props, PROP_MIN_TOOLS_REV,
-                Integer.toString(MIN_TOOLS_REV_NOT_SPECIFIED)));
-    }
-
-    /**
-     * The minimal revision of the tools package required by this extra package, if > 0,
-     * or {@link #MIN_TOOLS_REV_NOT_SPECIFIED} if there is no such requirement.
-     */
-    public int getMinToolsRevision() {
-        return mMinToolsRevision;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java
deleted file mode 100755
index b43acc7..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * A {@link Package} is the base class for "something" that can be downloaded from
- * the SDK repository -- subclasses include {@link PlatformPackage}, {@link AddonPackage},
- * {@link DocPackage} and {@link ToolPackage}.
- * <p/>
- * A package has some attributes (revision, description) and a list of archives
- * which represent the downloadable bits.
- * <p/>
- * Packages are contained by a {@link RepoSource} (a download site).
- * <p/>
- * Derived classes must implement the {@link IDescription} methods.
- */
-public abstract class Package implements IDescription {
-
-    private static final String PROP_REVISION     = "Pkg.Revision";     //$NON-NLS-1$
-    private static final String PROP_LICENSE      = "Pkg.License";      //$NON-NLS-1$
-    private static final String PROP_DESC         = "Pkg.Desc";         //$NON-NLS-1$
-    private static final String PROP_DESC_URL     = "Pkg.DescUrl";      //$NON-NLS-1$
-    private static final String PROP_RELEASE_NOTE = "Pkg.RelNote";      //$NON-NLS-1$
-    private static final String PROP_RELEASE_URL  = "Pkg.RelNoteUrl";   //$NON-NLS-1$
-    private static final String PROP_SOURCE_URL   = "Pkg.SourceUrl";    //$NON-NLS-1$
-    private static final String PROP_USER_SOURCE  = "Pkg.UserSrc";      //$NON-NLS-1$
-    private final int mRevision;
-    private final String mLicense;
-    private final String mDescription;
-    private final String mDescUrl;
-    private final String mReleaseNote;
-    private final String mReleaseUrl;
-    private final Archive[] mArchives;
-    private final RepoSource mSource;
-
-    /**
-     * Enum for the result of {@link Package#canBeUpdatedBy(Package)}. This used so that we can
-     * differentiate between a package that is totally incompatible, and one that is the same item
-     * but just not an update.
-     * @see #canBeUpdatedBy(Package)
-     */
-    public static enum UpdateInfo {
-        /** Means that the 2 packages are not the same thing */
-        INCOMPATIBLE,
-        /** Means that the 2 packages are the same thing but one does not upgrade the other */
-        NOT_UPDATE,
-        /** Means that the 2 packages are the same thing, and one is the upgrade of the other */
-        UPDATE;
-    }
-
-    /**
-     * Creates a new package from the attributes and elements of the given XML node.
-     * <p/>
-     * This constructor should throw an exception if the package cannot be created.
-     */
-    Package(RepoSource source, Node packageNode, Map<String,String> licenses) {
-        mSource = source;
-        mRevision    = XmlParserUtils.getXmlInt   (packageNode, SdkRepository.NODE_REVISION, 0);
-        mDescription = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_DESCRIPTION);
-        mDescUrl     = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_DESC_URL);
-        mReleaseNote = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_RELEASE_NOTE);
-        mReleaseUrl  = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_RELEASE_URL);
-
-        mLicense  = parseLicense(packageNode, licenses);
-        mArchives = parseArchives(XmlParserUtils.getFirstChild(
-                                  packageNode, SdkRepository.NODE_ARCHIVES));
-    }
-
-    /**
-     * Manually create a new package with one archive and the given attributes.
-     * This is used to create packages from local directories in which case there must be
-     * one archive which URL is the actual target location.
-     * <p/>
-     * Properties from props are used first when possible, e.g. if props is non null.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    public Package(
-            RepoSource source,
-            Properties props,
-            int revision,
-            String license,
-            String description,
-            String descUrl,
-            Os archiveOs,
-            Arch archiveArch,
-            String archiveOsPath) {
-
-        if (description == null) {
-            description = "";
-        }
-        if (descUrl == null) {
-            descUrl = "";
-        }
-
-        mRevision = Integer.parseInt(getProperty(props, PROP_REVISION, Integer.toString(revision)));
-        mLicense     = getProperty(props, PROP_LICENSE,      license);
-        mDescription = getProperty(props, PROP_DESC,         description);
-        mDescUrl     = getProperty(props, PROP_DESC_URL,     descUrl);
-        mReleaseNote = getProperty(props, PROP_RELEASE_NOTE, "");
-        mReleaseUrl  = getProperty(props, PROP_RELEASE_URL,  "");
-
-        // If source is null and we can find a source URL in the properties, generate
-        // a dummy source just to store the URL. This allows us to easily remember where
-        // a package comes from.
-        String srcUrl = getProperty(props, PROP_SOURCE_URL, null);
-        if (props != null && source == null && srcUrl != null) {
-            boolean isUser = Boolean.parseBoolean(props.getProperty(PROP_USER_SOURCE,
-                                                                    Boolean.TRUE.toString()));
-            source = new RepoSource(srcUrl, isUser);
-        }
-        mSource = source;
-
-        mArchives = new Archive[1];
-        mArchives[0] = new Archive(this,
-                props,
-                archiveOs,
-                archiveArch,
-                archiveOsPath);
-    }
-
-    /**
-     * Utility method that returns a property from a {@link Properties} object.
-     * Returns the default value if props is null or if the property is not defined.
-     */
-    protected String getProperty(Properties props, String propKey, String defaultValue) {
-        if (props == null) {
-            return defaultValue;
-        }
-        return props.getProperty(propKey, defaultValue);
-    }
-
-    /**
-     * Save the properties of the current packages in the given {@link Properties} object.
-     * These properties will later be give the constructor that takes a {@link Properties} object.
-     */
-    void saveProperties(Properties props) {
-        props.setProperty(PROP_REVISION, Integer.toString(mRevision));
-        if (mLicense != null && mLicense.length() > 0) {
-            props.setProperty(PROP_LICENSE, mLicense);
-        }
-
-        if (mDescription != null && mDescription.length() > 0) {
-            props.setProperty(PROP_DESC, mDescription);
-        }
-        if (mDescUrl != null && mDescUrl.length() > 0) {
-            props.setProperty(PROP_DESC_URL, mDescUrl);
-        }
-
-        if (mReleaseNote != null && mReleaseNote.length() > 0) {
-            props.setProperty(PROP_RELEASE_NOTE, mReleaseNote);
-        }
-        if (mReleaseUrl != null && mReleaseUrl.length() > 0) {
-            props.setProperty(PROP_RELEASE_URL, mReleaseUrl);
-        }
-
-        if (mSource != null) {
-            props.setProperty(PROP_SOURCE_URL,  mSource.getUrl());
-            props.setProperty(PROP_USER_SOURCE, Boolean.toString(mSource.isUserSource()));
-        }
-    }
-
-    /**
-     * Parses the uses-licence node of this package, if any, and returns the license
-     * definition if there's one. Returns null if there's no uses-license element or no
-     * license of this name defined.
-     */
-    private String parseLicense(Node packageNode, Map<String, String> licenses) {
-        Node usesLicense = XmlParserUtils.getFirstChild(
-                                            packageNode, SdkRepository.NODE_USES_LICENSE);
-        if (usesLicense != null) {
-            Node ref = usesLicense.getAttributes().getNamedItem(SdkRepository.ATTR_REF);
-            if (ref != null) {
-                String licenseRef = ref.getNodeValue();
-                return licenses.get(licenseRef);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Parses an XML node to process the <archives> element.
-     */
-    private Archive[] parseArchives(Node archivesNode) {
-        ArrayList<Archive> archives = new ArrayList<Archive>();
-
-        if (archivesNode != null) {
-            String nsUri = archivesNode.getNamespaceURI();
-            for(Node child = archivesNode.getFirstChild();
-                child != null;
-                child = child.getNextSibling()) {
-
-                if (child.getNodeType() == Node.ELEMENT_NODE &&
-                        nsUri.equals(child.getNamespaceURI()) &&
-                        SdkRepository.NODE_ARCHIVE.equals(child.getLocalName())) {
-                    archives.add(parseArchive(child));
-                }
-            }
-        }
-
-        return archives.toArray(new Archive[archives.size()]);
-    }
-
-    /**
-     * Parses one <archive> element from an <archives> container.
-     */
-    private Archive parseArchive(Node archiveNode) {
-        Archive a = new Archive(
-                    this,
-                    (Os)   XmlParserUtils.getEnumAttribute(archiveNode, SdkRepository.ATTR_OS,
-                            Os.values(), null),
-                    (Arch) XmlParserUtils.getEnumAttribute(archiveNode, SdkRepository.ATTR_ARCH,
-                            Arch.values(), Arch.ANY),
-                    XmlParserUtils.getXmlString(archiveNode, SdkRepository.NODE_URL),
-                    XmlParserUtils.getXmlLong  (archiveNode, SdkRepository.NODE_SIZE, 0),
-                    XmlParserUtils.getXmlString(archiveNode, SdkRepository.NODE_CHECKSUM)
-                );
-
-        return a;
-    }
-
-    /**
-     * Returns the source that created (and owns) this package. Can be null.
-     */
-    public RepoSource getParentSource() {
-        return mSource;
-    }
-
-    /**
-     * Returns the revision, an int > 0, for all packages (platform, add-on, tool, doc).
-     * Can be 0 if this is a local package of unknown revision.
-     */
-    public int getRevision() {
-        return mRevision;
-    }
-
-    /**
-     * Returns the optional description for all packages (platform, add-on, tool, doc) or
-     * for a lib. It is null if the element has not been specified in the repository XML.
-     */
-    public String getLicense() {
-        return mLicense;
-    }
-
-    /**
-     * Returns the optional description for all packages (platform, add-on, tool, doc) or
-     * for a lib. Can be empty but not null.
-     */
-    public String getDescription() {
-        return mDescription;
-    }
-
-    /**
-     * Returns the optional description URL for all packages (platform, add-on, tool, doc).
-     * Can be empty but not null.
-     */
-    public String getDescUrl() {
-        return mDescUrl;
-    }
-
-    /**
-     * Returns the optional release note for all packages (platform, add-on, tool, doc) or
-     * for a lib. Can be empty but not null.
-     */
-    public String getReleaseNote() {
-        return mReleaseNote;
-    }
-
-    /**
-     * Returns the optional release note URL for all packages (platform, add-on, tool, doc).
-     * Can be empty but not null.
-     */
-    public String getReleaseNoteUrl() {
-        return mReleaseUrl;
-    }
-
-    /**
-     * Returns the archives defined in this package.
-     * Can be an empty array but not null.
-     */
-    public Archive[] getArchives() {
-        return mArchives;
-    }
-
-    /**
-     * Returns whether the {@link Package} has at least one {@link Archive} compatible with
-     * the host platform.
-     */
-    public boolean hasCompatibleArchive() {
-        for (Archive archive : mArchives) {
-            if (archive.isCompatible()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns a short description for an {@link IDescription}.
-     * Can be empty but not null.
-     */
-    public abstract String getShortDescription();
-
-    /**
-     * Returns a long description for an {@link IDescription}.
-     * Can be empty but not null.
-     */
-    public String getLongDescription() {
-        StringBuilder sb = new StringBuilder();
-
-        String s = getDescription();
-        if (s != null) {
-            sb.append(s);
-        }
-        if (sb.length() > 0) {
-            sb.append("\n");
-        }
-
-        sb.append(String.format("Revision %1$d", getRevision()));
-
-        s = getDescUrl();
-        if (s != null && s.length() > 0) {
-            sb.append(String.format("\n\nMore information at %1$s", s));
-        }
-
-        s = getReleaseNote();
-        if (s != null && s.length() > 0) {
-            sb.append("\n\nRelease note:\n").append(s);
-        }
-
-        s = getReleaseNoteUrl();
-        if (s != null && s.length() > 0) {
-            sb.append("\nRelease note URL: ").append(s);
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Computes a potential installation folder if an archive of this package were
-     * to be installed right away in the given SDK root.
-     * <p/>
-     * Some types of packages install in a fix location, for example docs and tools.
-     * In this case the returned folder may already exist with a different archive installed
-     * at the desired location.
-     * For other packages types, such as add-on or platform, the folder name is only partially
-     * relevant to determine the content and thus a real check will be done to provide an
-     * existing or new folder depending on the current content of the SDK.
-     *
-     * @param osSdkRoot The OS path of the SDK root folder.
-     * @param suggestedDir A suggestion for the installation folder name, based on the root
-     *                     folder used in the zip archive.
-     * @param sdkManager An existing SDK manager to list current platforms and addons.
-     * @return A new {@link File} corresponding to the directory to use to install this package.
-     */
-    public abstract File getInstallFolder(
-            String osSdkRoot, String suggestedDir, SdkManager sdkManager);
-
-    /**
-     * Returns whether the give package represents the same item as the current package.
-     * <p/>
-     * Two packages are considered the same if they represent the same thing, except for the
-     * revision number.
-     * @param pkg the package to compare
-     * @return true if the item
-     */
-    public abstract boolean sameItemAs(Package pkg);
-
-    /**
-     * Computes whether the given package is a suitable update for the current package.
-     * <p/>
-     * An update is just that: a new package that supersedes the current one. If the new
-     * package does not represent the same item or if it has the same or lower revision as the
-     * current one, it's not an update.
-     *
-     * @param replacementPackage The potential replacement package.
-     * @return One of the {@link UpdateInfo} values.
-     *
-     * @see #sameItemAs(Package)
-     */
-    public UpdateInfo canBeUpdatedBy(Package replacementPackage) {
-        if (replacementPackage == null) {
-            return UpdateInfo.INCOMPATIBLE;
-        }
-
-        // check they are the same item.
-        if (sameItemAs(replacementPackage) == false) {
-            return UpdateInfo.INCOMPATIBLE;
-        }
-
-        // check revision number
-        if (replacementPackage.getRevision() > this.getRevision()) {
-            return UpdateInfo.UPDATE;
-        }
-
-        // not an upgrade but not incompatible either.
-        return UpdateInfo.NOT_UPDATE;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java
deleted file mode 100755
index c8d79a0..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Represents a platform XML node in an SDK repository.
- */
-public class PlatformPackage extends MinToolsPackage implements IPackageVersion {
-
-    protected static final String PROP_VERSION       = "Platform.Version";      //$NON-NLS-1$
-
-    /** The package version, for platform, add-on and doc packages. */
-    private final AndroidVersion mVersion;
-
-    /** The version, a string, for platform packages. */
-    private final String mVersionName;
-
-    /**
-     * Creates a new platform package from the attributes and elements of the given XML node.
-     * <p/>
-     * This constructor should throw an exception if the package cannot be created.
-     */
-    PlatformPackage(RepoSource source, Node packageNode, Map<String,String> licenses) {
-        super(source, packageNode, licenses);
-
-        mVersionName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_VERSION);
-        int apiLevel = XmlParserUtils.getXmlInt   (packageNode, SdkRepository.NODE_API_LEVEL, 0);
-        String codeName = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_CODENAME);
-        if (codeName.length() == 0) {
-            codeName = null;
-        }
-        mVersion = new AndroidVersion(apiLevel, codeName);
-    }
-
-    /**
-     * Creates a new platform package based on an actual {@link IAndroidTarget} (which
-     * must have {@link IAndroidTarget#isPlatform()} true) from the {@link SdkManager}.
-     * This is used to list local SDK folders in which case there is one archive which
-     * URL is the actual target location.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    PlatformPackage(IAndroidTarget target, Properties props) {
-        super(  null,                       //source
-                props,                      //properties
-                target.getRevision(),       //revision
-                null,                       //license
-                target.getDescription(),    //description
-                null,                       //descUrl
-                Os.getCurrentOs(),          //archiveOs
-                Arch.getCurrentArch(),      //archiveArch
-                target.getLocation()        //archiveOsPath
-                );
-
-        mVersion = target.getVersion();
-        mVersionName  = target.getVersionName();
-    }
-
-    /**
-     * Save the properties of the current packages in the given {@link Properties} object.
-     * These properties will later be given to a constructor that takes a {@link Properties} object.
-     */
-    @Override
-    void saveProperties(Properties props) {
-        super.saveProperties(props);
-
-        mVersion.saveProperties(props);
-
-        if (mVersionName != null) {
-            props.setProperty(PROP_VERSION, mVersionName);
-        }
-
-        if (getMinToolsRevision() != MIN_TOOLS_REV_NOT_SPECIFIED) {
-            props.setProperty(PROP_MIN_TOOLS_REV, Integer.toString(getMinToolsRevision()));
-        }
-    }
-
-    /** Returns the version, a string, for platform packages. */
-    public String getVersionName() {
-        return mVersionName;
-    }
-
-    /** Returns the package version, for platform, add-on and doc packages. */
-    public AndroidVersion getVersion() {
-        return mVersion;
-    }
-
-    /** Returns a short description for an {@link IDescription}. */
-    @Override
-    public String getShortDescription() {
-        String s;
-
-        if (mVersion.isPreview()) {
-            s = String.format("SDK Platform Android %1$s Preview, revision %2$s",
-                    getVersionName(),
-                    getRevision());
-        } else {
-            s = String.format("SDK Platform Android %1$s, API %2$d, revision %3$s",
-                getVersionName(),
-                mVersion.getApiLevel(),
-                getRevision());
-        }
-
-        return s;
-    }
-
-    /**
-     * Returns a long description for an {@link IDescription}.
-     *
-     * The long description is whatever the XML contains for the &lt;description&gt; field,
-     * or the short description if the former is empty.
-     */
-    @Override
-    public String getLongDescription() {
-        String s = getDescription();
-        if (s == null || s.length() == 0) {
-            s = getShortDescription();
-        }
-
-        if (s.indexOf("revision") == -1) {
-            s += String.format("\nRevision %1$d", getRevision());
-        }
-
-        return s;
-    }
-
-    /**
-     * Computes a potential installation folder if an archive of this package were
-     * to be installed right away in the given SDK root.
-     * <p/>
-     * A platform package is typically installed in SDK/platforms/android-"version".
-     * However if we can find a different directory under SDK/platform that already
-     * has this platform version installed, we'll use that one.
-     *
-     * @param osSdkRoot The OS path of the SDK root folder.
-     * @param suggestedDir A suggestion for the installation folder name, based on the root
-     *                     folder used in the zip archive.
-     * @param sdkManager An existing SDK manager to list current platforms and addons.
-     * @return A new {@link File} corresponding to the directory to use to install this package.
-     */
-    @Override
-    public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
-
-        // First find if this platform is already installed. If so, reuse the same directory.
-        for (IAndroidTarget target : sdkManager.getTargets()) {
-            if (target.isPlatform() &&
-                    target.getVersion().equals(mVersion) &&
-                    target.getVersionName().equals(getVersionName())) {
-                return new File(target.getLocation());
-            }
-        }
-
-        File platforms = new File(osSdkRoot, SdkConstants.FD_PLATFORMS);
-        File folder = new File(platforms, String.format("android-%s", getVersionName())); //$NON-NLS-1$
-
-        return folder;
-    }
-
-    @Override
-    public boolean sameItemAs(Package pkg) {
-        if (pkg instanceof PlatformPackage) {
-            PlatformPackage newPkg = (PlatformPackage)pkg;
-
-            // check they are the same platform.
-            return newPkg.getVersion().equals(this.getVersion());
-        }
-
-        return false;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java
deleted file mode 100755
index b5a7c8d..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import java.io.ByteArrayInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.regex.Pattern;
-
-import javax.net.ssl.SSLKeyException;
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-
-/**
- * An sdk-repository source, i.e. a download site.
- * It may be a full repository or an add-on only repository.
- * A repository describes one or {@link Package}s available for download.
- */
-public class RepoSource implements IDescription {
-
-    private String mUrl;
-    private final boolean mUserSource;
-
-    private Package[] mPackages;
-    private String mDescription;
-    private String mFetchError;
-
-    /**
-     * Constructs a new source for the given repository URL.
-     * @param url The source URL. Cannot be null. If the URL ends with a /, the default
-     *            repository.xml filename will be appended automatically.
-     * @param userSource True if this a user source (add-ons & packages only.)
-     */
-    public RepoSource(String url, boolean userSource) {
-
-        // if the URL ends with a /, it must be "directory" resource,
-        // in which case we automatically add the default file that will
-        // looked for. This way it will be obvious to the user which
-        // resource we are actually trying to fetch.
-        if (url.endsWith("/")) {  //$NON-NLS-1$
-            url += SdkRepository.URL_DEFAULT_XML_FILE;
-        }
-
-        mUrl = url;
-        mUserSource = userSource;
-        setDefaultDescription();
-    }
-
-    /**
-     * Two repo source are equal if they have the same userSource flag and the same URL.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof RepoSource) {
-            RepoSource rs = (RepoSource) obj;
-            return  rs.isUserSource() == this.isUserSource() && rs.getUrl().equals(this.getUrl());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mUrl.hashCode() ^ Boolean.valueOf(mUserSource).hashCode();
-    }
-
-    /** Returns true if this is a user source. We only load addon and extra packages
-     * from a user source and ignore the rest. */
-    public boolean isUserSource() {
-        return mUserSource;
-    }
-
-    /** Returns the URL of the repository.xml file for this source. */
-    public String getUrl() {
-        return mUrl;
-    }
-
-    /**
-     * Returns the list of known packages found by the last call to load().
-     * This is null when the source hasn't been loaded yet.
-     */
-    public Package[] getPackages() {
-        return mPackages;
-    }
-
-    /**
-     * Clear the internal packages list. After this call, {@link #getPackages()} will return
-     * null till load() is called.
-     */
-    public void clearPackages() {
-        mPackages = null;
-    }
-
-    public String getShortDescription() {
-        return mUrl;
-    }
-
-    public String getLongDescription() {
-        return mDescription == null ? "" : mDescription;  //$NON-NLS-1$
-    }
-
-    /**
-     * Returns the last fetch error description.
-     * If there was no error, returns null.
-     */
-    public String getFetchError() {
-        return mFetchError;
-    }
-
-    /**
-     * Tries to fetch the repository index for the given URL.
-     */
-    public void load(ITaskMonitor monitor, boolean forceHttp) {
-
-        monitor.setProgressMax(4);
-
-        setDefaultDescription();
-
-        String url = mUrl;
-        if (forceHttp) {
-            url = url.replaceAll("https://", "http://");  //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        monitor.setDescription("Fetching %1$s", url);
-        monitor.incProgress(1);
-
-        mFetchError = null;
-        Exception[] exception = new Exception[] { null };
-        ByteArrayInputStream xml = fetchUrl(url, exception);
-        Document validatedDoc = null;
-        String validatedUri = null;
-        if (xml != null) {
-            monitor.setDescription("Validate XML");
-            String uri = validateXml(xml, url, monitor);
-            if (uri != null) {
-                validatedDoc = getDocument(xml, monitor);
-                validatedUri = uri;
-            } else {
-                validatedDoc = findAlternateToolsXml(xml);
-                validatedUri = SdkRepository.NS_SDK_REPOSITORY;
-            }
-        }
-
-        // If we failed the first time and the URL doesn't explicitly end with
-        // our filename, make another tentative after changing the URL.
-        if (validatedDoc == null && !url.endsWith(SdkRepository.URL_DEFAULT_XML_FILE)) {
-            if (!url.endsWith("/")) {       //$NON-NLS-1$
-                url += "/";                 //$NON-NLS-1$
-            }
-            url += SdkRepository.URL_DEFAULT_XML_FILE;
-
-            xml = fetchUrl(url, exception);
-            if (xml != null) {
-                String uri = validateXml(xml, url, monitor);
-                if (uri != null) {
-                    validatedDoc = getDocument(xml, monitor);
-                    validatedUri = uri;
-                } else {
-                    validatedDoc = findAlternateToolsXml(xml);
-                    validatedUri = SdkRepository.NS_SDK_REPOSITORY;
-                }
-            }
-
-            if (validatedDoc != null) {
-                // If the second tentative succeeded, indicate it in the console
-                // with the URL that worked.
-                monitor.setResult("Repository found at %1$s", url);
-
-                // Keep the modified URL
-                mUrl = url;
-            }
-        }
-
-        // If any exception was handled during the URL fetch, display it now.
-        if (exception[0] != null) {
-            mFetchError = "Failed to fetch URL";
-
-            String reason = null;
-            if (exception[0] instanceof FileNotFoundException) {
-                // FNF has no useful getMessage, so we need to special handle it.
-                reason = "File not found";
-                mFetchError += ": " + reason;
-            } else if (exception[0] instanceof SSLKeyException) {
-                // That's a common error and we have a pref for it.
-                reason = "HTTPS SSL error. You might want to force download through HTTP in the settings.";
-                mFetchError += ": HTTPS SSL error";
-            } else if (exception[0].getMessage() != null) {
-                reason = exception[0].getMessage();
-            } else {
-                // We don't know what's wrong. Let's give the exception class at least.
-                reason = String.format("Unknown (%1$s)", exception[0].getClass().getName());
-            }
-
-            monitor.setResult("Failed to fetch URL %1$s, reason: %2$s", url, reason);
-        }
-
-        // Stop here if we failed to validate the XML. We don't want to load it.
-        if (validatedDoc == null) {
-            return;
-        }
-
-        monitor.incProgress(1);
-
-        if (xml != null) {
-            monitor.setDescription("Parse XML");
-            monitor.incProgress(1);
-            parsePackages(validatedDoc, validatedUri, monitor);
-            if (mPackages == null || mPackages.length == 0) {
-                mDescription += "\nNo packages found.";
-            } else if (mPackages.length == 1) {
-                mDescription += "\nOne package found.";
-            } else {
-                mDescription += String.format("\n%1$d packages found.", mPackages.length);
-            }
-        }
-
-        // done
-        monitor.incProgress(1);
-    }
-
-    private void setDefaultDescription() {
-        if (mUserSource) {
-            mDescription = String.format("Add-on Source: %1$s", mUrl);
-        } else {
-            mDescription = String.format("SDK Source: %1$s", mUrl);
-        }
-    }
-
-    /**
-     * Fetches the document at the given URL and returns it as a string.
-     * Returns null if anything wrong happens and write errors to the monitor.
-     *
-     * References:
-     * Java URL Connection: http://java.sun.com/docs/books/tutorial/networking/urls/readingWriting.html
-     * Java URL Reader: http://java.sun.com/docs/books/tutorial/networking/urls/readingURL.html
-     * Java set Proxy: http://java.sun.com/docs/books/tutorial/networking/urls/_setProxy.html
-     */
-    private ByteArrayInputStream fetchUrl(String urlString, Exception[] outException) {
-        URL url;
-        try {
-            url = new URL(urlString);
-
-            InputStream is = null;
-
-            int inc = 65536;
-            int curr = 0;
-            byte[] result = new byte[inc];
-
-            try {
-                is = url.openStream();
-
-                int n;
-                while ((n = is.read(result, curr, result.length - curr)) != -1) {
-                    curr += n;
-                    if (curr == result.length) {
-                        byte[] temp = new byte[curr + inc];
-                        System.arraycopy(result, 0, temp, 0, curr);
-                        result = temp;
-                    }
-                }
-
-                return new ByteArrayInputStream(result, 0, curr);
-
-            } finally {
-                if (is != null) {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
-                        // pass
-                    }
-                }
-            }
-
-        } catch (Exception e) {
-            outException[0] = e;
-        }
-
-        return null;
-    }
-
-    /**
-     * Validates this XML against one of the possible SDK Repository schema, starting
-     * by the most recent one.
-     * If the XML was correctly validated, returns the schema that worked.
-     * If no schema validated the XML, returns null.
-     */
-    private String validateXml(ByteArrayInputStream xml, String url, ITaskMonitor monitor) {
-
-        String lastError = null;
-        String extraError = null;
-        for (int version = SdkRepository.NS_LATEST_VERSION; version >= 1; version--) {
-            try {
-                Validator validator = getValidator(version);
-
-                if (validator == null) {
-                    lastError = "XML verification failed for %1$s.\nNo suitable XML Schema Validator could be found in your Java environment. Please consider updating your version of Java.";
-                    continue;
-                }
-
-                xml.reset();
-                // Validation throws a bunch of possible Exceptions on failure.
-                validator.validate(new StreamSource(xml));
-                return SdkRepository.getSchemaUri(version);
-
-            } catch (Exception e) {
-                lastError = "XML verification failed for %1$s.\nError: %2$s";
-                extraError = e.getMessage();
-                if (extraError == null) {
-                    extraError = e.getClass().getName();
-                }
-            }
-        }
-
-        if (lastError != null) {
-            monitor.setResult(lastError, url, extraError);
-        }
-        return null;
-    }
-
-    /**
-     * The purpose of this method is to support forward evolution of our schema.
-     * <p/>
-     * At this point, we know that xml does not point to any schema that this version of
-     * the tool know how to process, so it's not one of the possible 1..N versions of our
-     * XSD schema.
-     * <p/>
-     * We thus try to interpret the byte stream as a possible XML stream. It may not be
-     * one at all in the first place. If it looks anything line an XML schema, we try to
-     * find its &lt;tool&gt; elements. If we find any, we recreate a suitable document
-     * that conforms to what we expect from our XSD schema with only those elements.
-     * To be valid, the &lt;tool&gt; element must have at least one &lt;archive&gt;
-     * compatible with this platform.
-     *
-     * If we don't find anything suitable, we drop the whole thing.
-     *
-     * @param xml The input XML stream. Can be null.
-     * @return Either a new XML document conforming to our schema with at least one &lt;tool&gt;
-     *         element or null.
-     */
-    protected Document findAlternateToolsXml(InputStream xml) {
-        // Note: protected for unit-test access
-
-        if (xml == null) {
-            return null;
-        }
-
-        // Reset the stream if it supports that operation.
-        // At runtime we use a ByteArrayInputStream which can be reset; however for unit tests
-        // we use a FileInputStream that doesn't support resetting and is read-once.
-        try {
-            xml.reset();
-        } catch (IOException e1) {
-            // ignore if not supported
-        }
-
-        // Get an XML document
-
-        Document oldDoc = null;
-        Document newDoc = null;
-        try {
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            factory.setIgnoringComments(false);
-            factory.setValidating(false);
-
-            // Parse the old document using a non namespace aware builder
-            factory.setNamespaceAware(false);
-            DocumentBuilder builder = factory.newDocumentBuilder();
-            oldDoc = builder.parse(xml);
-
-            // Prepare a new document using a namespace aware builder
-            factory.setNamespaceAware(true);
-            builder = factory.newDocumentBuilder();
-            newDoc = builder.newDocument();
-
-        } catch (Exception e) {
-            // Failed to get builder factor
-            // Failed to create XML document builder
-            // Failed to parse XML document
-            // Failed to read XML document
-        }
-
-        if (oldDoc == null || newDoc == null) {
-            return null;
-        }
-
-
-        // Check the root element is an xsd-schema with at least the following properties:
-        // <sdk:sdk-repository
-        //    xmlns:sdk="http://schemas.android.com/sdk/android/repository/$N">
-        //
-        // Note that we don't have namespace support enabled, we just do it manually.
-
-        Pattern nsPattern = Pattern.compile(SdkRepository.NS_SDK_REPOSITORY_PATTERN);
-
-        Node oldRoot = null;
-        String prefix = null;
-        for (Node child = oldDoc.getFirstChild(); child != null; child = child.getNextSibling()) {
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                prefix = null;
-                String name = child.getNodeName();
-                int pos = name.indexOf(':');
-                if (pos > 0 && pos < name.length() - 1) {
-                    prefix = name.substring(0, pos);
-                    name = name.substring(pos + 1);
-                }
-                if (SdkRepository.NODE_SDK_REPOSITORY.equals(name)) {
-                    NamedNodeMap attrs = child.getAttributes();
-                    String xmlns = "xmlns";                                         //$NON-NLS-1$
-                    if (prefix != null) {
-                        xmlns += ":" + prefix;                                      //$NON-NLS-1$
-                    }
-                    Node attr = attrs.getNamedItem(xmlns);
-                    if (attr != null) {
-                        String uri = attr.getNodeValue();
-                        if (uri != null && nsPattern.matcher(uri).matches()) {
-                            oldRoot = child;
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        // we must have found the root node, and it must have an XML namespace prefix.
-        if (oldRoot == null || prefix == null || prefix.length() == 0) {
-            return null;
-        }
-
-        final String ns = SdkRepository.NS_SDK_REPOSITORY;
-        Element newRoot = newDoc.createElementNS(ns, SdkRepository.NODE_SDK_REPOSITORY);
-        newRoot.setPrefix(prefix);
-        newDoc.appendChild(newRoot);
-        int numTool = 0;
-
-        // Find an inner <tool> node and extract its required parameters
-
-        Node tool = null;
-        while ((tool = findChild(oldRoot, tool, prefix, SdkRepository.NODE_TOOL)) != null) {
-            // To be valid, the tool element must have:
-            // - a <revision> element with a number
-            // - an optional <uses-license> node, which we'll skip right now.
-            //   (if we add it later, we must find the license declaration element too)
-            // - an <archives> element with one or more <archive> elements inside
-            // - one of the <archive> elements must have an "os" and "arch" attributes
-            //   compatible with the current platform. Only keep the first such element found.
-            // - the <archive> element must contain a <size>, a <checksum> and a <url>.
-
-            try {
-                Node revision = findChild(tool, null, prefix, SdkRepository.NODE_REVISION);
-                Node archives = findChild(tool, null, prefix, SdkRepository.NODE_ARCHIVES);
-
-                if (revision == null || archives == null) {
-                    continue;
-                }
-
-                int rev = 0;
-                try {
-                    String content = revision.getTextContent();
-                    content = content.trim();
-                    rev = Integer.parseInt(content);
-                    if (rev < 1) {
-                        continue;
-                    }
-                } catch (NumberFormatException ignore) {
-                    continue;
-                }
-
-                Element newTool = newDoc.createElementNS(ns, SdkRepository.NODE_TOOL);
-                newTool.setPrefix(prefix);
-                appendChild(newTool, ns, prefix,
-                        SdkRepository.NODE_REVISION, Integer.toString(rev));
-                Element newArchives = appendChild(newTool, ns, prefix,
-                                                  SdkRepository.NODE_ARCHIVES, null);
-                int numArchives = 0;
-
-                Node archive = null;
-                while ((archive = findChild(archives,
-                                            archive,
-                                            prefix,
-                                            SdkRepository.NODE_ARCHIVE)) != null) {
-                    try {
-                        Os os = (Os) XmlParserUtils.getEnumAttribute(archive,
-                                SdkRepository.ATTR_OS,
-                                Os.values(),
-                                null /*default*/);
-                        Arch arch = (Arch) XmlParserUtils.getEnumAttribute(archive,
-                                SdkRepository.ATTR_ARCH,
-                                Arch.values(),
-                                Arch.ANY);
-                        if (os == null || !os.isCompatible() ||
-                                arch == null || !arch.isCompatible()) {
-                            continue;
-                        }
-
-                        Node node = findChild(archive, null, prefix, SdkRepository.NODE_URL);
-                        String url = node == null ? null : node.getTextContent().trim();
-                        if (url == null || url.length() == 0) {
-                            continue;
-                        }
-
-                        node = findChild(archive, null, prefix, SdkRepository.NODE_SIZE);
-                        long size = 0;
-                        try {
-                            size = Long.parseLong(node.getTextContent());
-                        } catch (Exception e) {
-                            // pass
-                        }
-                        if (size < 1) {
-                            continue;
-                        }
-
-                        node = findChild(archive, null, prefix, SdkRepository.NODE_CHECKSUM);
-                        // double check that the checksum element contains a type=sha1 attribute
-                        if (node == null) {
-                            continue;
-                        }
-                        NamedNodeMap attrs = node.getAttributes();
-                        Node typeNode = attrs.getNamedItem(SdkRepository.ATTR_TYPE);
-                        if (typeNode == null ||
-                                !SdkRepository.ATTR_TYPE.equals(typeNode.getNodeName()) ||
-                                !SdkRepository.SHA1_TYPE.equals(typeNode.getNodeValue())) {
-                            continue;
-                        }
-                        String sha1 = node == null ? null : node.getTextContent().trim();
-                        if (sha1 == null || sha1.length() != SdkRepository.SHA1_CHECKSUM_LEN) {
-                            continue;
-                        }
-
-                        // Use that archive for the new tool element
-                        Element ar = appendChild(newArchives, ns, prefix,
-                                                 SdkRepository.NODE_ARCHIVE, null);
-                        ar.setAttributeNS(ns, SdkRepository.ATTR_OS, os.getXmlName());
-                        ar.setAttributeNS(ns, SdkRepository.ATTR_ARCH, arch.getXmlName());
-
-                        appendChild(ar, ns, prefix, SdkRepository.NODE_URL, url);
-                        appendChild(ar, ns, prefix, SdkRepository.NODE_SIZE, Long.toString(size));
-                        Element cs = appendChild(ar, ns, prefix, SdkRepository.NODE_CHECKSUM, sha1);
-                        cs.setAttributeNS(ns, SdkRepository.ATTR_TYPE, SdkRepository.SHA1_TYPE);
-
-                        numArchives++;
-
-                    } catch (Exception ignore1) {
-                        // pass
-                    }
-                } // while <archive>
-
-                if (numArchives > 0) {
-                    newRoot.appendChild(newTool);
-                    numTool++;
-                }
-            } catch (Exception ignore2) {
-                // pass
-            }
-        } // while <tool>
-
-        return numTool > 0 ? newDoc : null;
-    }
-
-    /**
-     * Helper method used by {@link #findAlternateToolsXml(InputStream)} to find a given
-     * element child in a root XML node.
-     */
-    private Node findChild(Node rootNode, Node after, String prefix, String nodeName) {
-        nodeName = prefix + ":" + nodeName;
-        Node child = after == null ? rootNode.getFirstChild() : after.getNextSibling();
-        for(; child != null; child = child.getNextSibling()) {
-            if (child.getNodeType() == Node.ELEMENT_NODE && nodeName.equals(child.getNodeName())) {
-                return child;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Helper method used by {@link #findAlternateToolsXml(InputStream)} to create a new
-     * XML element into a parent element.
-     */
-    private Element appendChild(Element rootNode, String namespaceUri,
-            String prefix, String nodeName,
-            String nodeValue) {
-        Element node = rootNode.getOwnerDocument().createElementNS(namespaceUri, nodeName);
-        node.setPrefix(prefix);
-        if (nodeValue != null) {
-            node.setTextContent(nodeValue);
-        }
-        rootNode.appendChild(node);
-        return node;
-    }
-
-
-    /**
-     * Helper method that returns a validator for our XSD, or null if the current Java
-     * implementation can't process XSD schemas.
-     *
-     * @param version The version of the XML Schema.
-     *        See {@link SdkRepository#getXsdStream(int)}
-     */
-    private Validator getValidator(int version) throws SAXException {
-        InputStream xsdStream = SdkRepository.getXsdStream(version);
-        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-
-        if (factory == null) {
-            return null;
-        }
-
-        // This may throw a SAX Exception if the schema itself is not a valid XSD
-        Schema schema = factory.newSchema(new StreamSource(xsdStream));
-
-        Validator validator = schema == null ? null : schema.newValidator();
-
-        return validator;
-    }
-
-
-    /**
-     * Parse all packages defined in the SDK Repository XML and creates
-     * a new mPackages array with them.
-     */
-    protected boolean parsePackages(Document doc, String nsUri, ITaskMonitor monitor) {
-        // protected for unit-test acces
-
-        assert doc != null;
-
-        Node root = getFirstChild(doc, nsUri, SdkRepository.NODE_SDK_REPOSITORY);
-        if (root != null) {
-
-            ArrayList<Package> packages = new ArrayList<Package>();
-
-            // Parse license definitions
-            HashMap<String, String> licenses = new HashMap<String, String>();
-            for (Node child = root.getFirstChild();
-                 child != null;
-                 child = child.getNextSibling()) {
-                if (child.getNodeType() == Node.ELEMENT_NODE &&
-                        nsUri.equals(child.getNamespaceURI()) &&
-                        child.getLocalName().equals(SdkRepository.NODE_LICENSE)) {
-                    Node id = child.getAttributes().getNamedItem(SdkRepository.ATTR_ID);
-                    if (id != null) {
-                        licenses.put(id.getNodeValue(), child.getTextContent());
-                    }
-                }
-            }
-
-            // Parse packages
-            for (Node child = root.getFirstChild();
-                 child != null;
-                 child = child.getNextSibling()) {
-                if (child.getNodeType() == Node.ELEMENT_NODE &&
-                        nsUri.equals(child.getNamespaceURI())) {
-                    String name = child.getLocalName();
-                    Package p = null;
-
-                    try {
-                        // We can load addon and extra packages from all sources, either
-                        // internal or user sources.
-                        if (SdkRepository.NODE_ADD_ON.equals(name)) {
-                            p = new AddonPackage(this, child, licenses);
-
-                        } else if (SdkRepository.NODE_EXTRA.equals(name)) {
-                            p = new ExtraPackage(this, child, licenses);
-
-                        } else if (!mUserSource) {
-                            // We only load platform, doc and tool packages from internal
-                            // sources, never from user sources.
-                            if (SdkRepository.NODE_PLATFORM.equals(name)) {
-                                p = new PlatformPackage(this, child, licenses);
-                            } else if (SdkRepository.NODE_DOC.equals(name)) {
-                                p = new DocPackage(this, child, licenses);
-                            } else if (SdkRepository.NODE_TOOL.equals(name)) {
-                                p = new ToolPackage(this, child, licenses);
-                            }
-                        }
-
-                        if (p != null) {
-                            packages.add(p);
-                            monitor.setDescription("Found %1$s", p.getShortDescription());
-                        }
-                    } catch (Exception e) {
-                        // Ignore invalid packages
-                    }
-                }
-            }
-
-            mPackages = packages.toArray(new Package[packages.size()]);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns the first child element with the given XML local name.
-     * If xmlLocalName is null, returns the very first child element.
-     */
-    private Node getFirstChild(Node node, String nsUri, String xmlLocalName) {
-
-        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
-            if (child.getNodeType() == Node.ELEMENT_NODE &&
-                    nsUri.equals(child.getNamespaceURI())) {
-                if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) {
-                    return child;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Takes an XML document as a string as parameter and returns a DOM for it.
-     *
-     * On error, returns null and prints a (hopefully) useful message on the monitor.
-     */
-    private Document getDocument(ByteArrayInputStream xml, ITaskMonitor monitor) {
-        try {
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            factory.setIgnoringComments(true);
-            factory.setNamespaceAware(true);
-
-            DocumentBuilder builder = factory.newDocumentBuilder();
-            xml.reset();
-            Document doc = builder.parse(new InputSource(xml));
-
-            return doc;
-        } catch (ParserConfigurationException e) {
-            monitor.setResult("Failed to create XML document builder");
-
-        } catch (SAXException e) {
-            monitor.setResult("Failed to parse XML document");
-
-        } catch (IOException e) {
-            monitor.setResult("Failed to read XML document");
-        }
-
-        return null;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java
deleted file mode 100755
index e0452b8..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.ISdkLog;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Properties;
-
-/**
- * A list of sdk-repository sources.
- */
-public class RepoSources {
-
-    private static final String KEY_COUNT = "count";
-
-    private static final String KEY_SRC = "src";
-
-    private static final String SRC_FILENAME = "repositories.cfg"; //$NON-NLS-1$
-
-    private ArrayList<RepoSource> mSources = new ArrayList<RepoSource>();
-
-    public RepoSources() {
-    }
-
-    /**
-     * Adds a new source to the Sources list.
-     */
-    public void add(RepoSource source) {
-        mSources.add(source);
-    }
-
-    /**
-     * Removes a source from the Sources list.
-     */
-    public void remove(RepoSource source) {
-        mSources.remove(source);
-    }
-
-    /**
-     * Returns the sources list array. This is never null.
-     */
-    public RepoSource[] getSources() {
-        return mSources.toArray(new RepoSource[mSources.size()]);
-    }
-
-    /**
-     * Loads all user sources. This <em>replaces</em> all existing user sources
-     * by the ones from the property file.
-     */
-    public void loadUserSources(ISdkLog log) {
-
-        // Remove all existing user sources
-        for (Iterator<RepoSource> it = mSources.iterator(); it.hasNext(); ) {
-            RepoSource s = it.next();
-            if (s.isUserSource()) {
-                it.remove();
-            }
-        }
-
-        // Load new user sources from property file
-        FileInputStream fis = null;
-        try {
-            String folder = AndroidLocation.getFolder();
-            File f = new File(folder, SRC_FILENAME);
-            if (f.exists()) {
-                fis = new FileInputStream(f);
-
-                Properties props = new Properties();
-                props.load(fis);
-
-                int count = Integer.parseInt(props.getProperty(KEY_COUNT, "0"));
-
-                for (int i = 0; i < count; i++) {
-                    String url = props.getProperty(String.format("%s%02d", KEY_SRC, i));  //$NON-NLS-1$
-                    if (url != null) {
-                        RepoSource s = new RepoSource(url, true /*userSource*/);
-                        if (!hasSource(s)) {
-                            mSources.add(s);
-                        }
-                    }
-                }
-            }
-
-        } catch (NumberFormatException e) {
-            log.error(e, null);
-
-        } catch (AndroidLocationException e) {
-            log.error(e, null);
-
-        } catch (IOException e) {
-            log.error(e, null);
-
-        } finally {
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if there's already a similar source in the sources list.
-     * <p/>
-     * The search is O(N), which should be acceptable on the expectedly small source list.
-     */
-    public boolean hasSource(RepoSource source) {
-        for (RepoSource s : mSources) {
-            if (s.equals(source)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Saves all the user sources.
-     * @param log
-     */
-    public void saveUserSources(ISdkLog log) {
-        FileOutputStream fos = null;
-        try {
-            String folder = AndroidLocation.getFolder();
-            File f = new File(folder, SRC_FILENAME);
-
-            fos = new FileOutputStream(f);
-
-            Properties props = new Properties();
-
-            int count = 0;
-            for (RepoSource s : mSources) {
-                if (s.isUserSource()) {
-                    count++;
-                    props.setProperty(String.format("%s%02d", KEY_SRC, count), s.getUrl());  //$NON-NLS-1$
-                }
-            }
-            props.setProperty(KEY_COUNT, Integer.toString(count));
-
-            props.store( fos, "## User Sources for Android tool");  //$NON-NLS-1$
-
-        } catch (AndroidLocationException e) {
-            log.error(e, null);
-
-        } catch (IOException e) {
-            log.error(e, null);
-
-        } finally {
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java
deleted file mode 100755
index bf70f91..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Represents a tool XML node in an SDK repository.
- */
-public class ToolPackage extends Package {
-
-    /**
-     * Creates a new tool package from the attributes and elements of the given XML node.
-     * <p/>
-     * This constructor should throw an exception if the package cannot be created.
-     */
-    ToolPackage(RepoSource source, Node packageNode, Map<String,String> licenses) {
-        super(source, packageNode, licenses);
-    }
-
-    /**
-     * Manually create a new package with one archive and the given attributes or properties.
-     * This is used to create packages from local directories in which case there must be
-     * one archive which URL is the actual target location.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    ToolPackage(
-            RepoSource source,
-            Properties props,
-            int revision,
-            String license,
-            String description,
-            String descUrl,
-            Os archiveOs,
-            Arch archiveArch,
-            String archiveOsPath) {
-        super(source,
-                props,
-                revision,
-                license,
-                description,
-                descUrl,
-                archiveOs,
-                archiveArch,
-                archiveOsPath);
-    }
-
-    /** Returns a short description for an {@link IDescription}. */
-    @Override
-    public String getShortDescription() {
-        return String.format("Android SDK Tools, revision %1$d", getRevision());
-    }
-
-    /** Returns a long description for an {@link IDescription}. */
-    @Override
-    public String getLongDescription() {
-        String s = getDescription();
-        if (s == null || s.length() == 0) {
-            s = getShortDescription();
-        }
-
-        if (s.indexOf("revision") == -1) {
-            s += String.format("\nRevision %1$d", getRevision());
-        }
-
-        return s;
-    }
-
-    /**
-     * Computes a potential installation folder if an archive of this package were
-     * to be installed right away in the given SDK root.
-     * <p/>
-     * A "tool" package should always be located in SDK/tools.
-     *
-     * @param osSdkRoot The OS path of the SDK root folder.
-     * @param suggestedDir A suggestion for the installation folder name, based on the root
-     *                     folder used in the zip archive.
-     * @param sdkManager An existing SDK manager to list current platforms and addons.
-     * @return A new {@link File} corresponding to the directory to use to install this package.
-     */
-    @Override
-    public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
-        return new File(osSdkRoot, SdkConstants.FD_TOOLS);
-    }
-
-    @Override
-    public boolean sameItemAs(Package pkg) {
-        // only one tool package so any tool package is the same item.
-        return pkg instanceof ToolPackage;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/XmlParserUtils.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/XmlParserUtils.java
deleted file mode 100755
index 7d3cd7e..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/XmlParserUtils.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import org.w3c.dom.Node;
-
-/**
- * Misc utilities to help extracting elements and attributes out of an XML document.
- */
-class XmlParserUtils {
-
-    /**
-     * Returns the first child element with the given XML local name.
-     * If xmlLocalName is null, returns the very first child element.
-     */
-    public static Node getFirstChild(Node node, String xmlLocalName) {
-
-        String nsUri = node.getNamespaceURI();
-        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
-            if (child.getNodeType() == Node.ELEMENT_NODE &&
-                    nsUri.equals(child.getNamespaceURI())) {
-                if (xmlLocalName == null || xmlLocalName.equals(child.getLocalName())) {
-                    return child;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Retrieves the value of that XML element as a string.
-     * Returns an empty string when the element is missing.
-     */
-    public static String getXmlString(Node node, String xmlLocalName) {
-        Node child = getFirstChild(node, xmlLocalName);
-
-        return child == null ? "" : child.getTextContent();  //$NON-NLS-1$
-    }
-
-    /**
-     * Retrieves the value of that XML element as an integer.
-     * Returns the default value when the element is missing or is not an integer.
-     */
-    public static int getXmlInt(Node node, String xmlLocalName, int defaultValue) {
-        String s = getXmlString(node, xmlLocalName);
-        try {
-            return Integer.parseInt(s);
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Retrieves the value of that XML element as a long.
-     * Returns the default value when the element is missing or is not an integer.
-     */
-    public static long getXmlLong(Node node, String xmlLocalName, long defaultValue) {
-        String s = getXmlString(node, xmlLocalName);
-        try {
-            return Long.parseLong(s);
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Retrieve an attribute which value must match one of the given enums using a
-     * case-insensitive name match.
-     *
-     * Returns defaultValue if the attribute does not exist or its value does not match
-     * the given enum values.
-     */
-    public static Object getEnumAttribute(
-            Node archiveNode,
-            String attrName,
-            Object[] values,
-            Object defaultValue) {
-
-        Node attr = archiveNode.getAttributes().getNamedItem(attrName);
-        if (attr != null) {
-            String found = attr.getNodeValue();
-            for (Object value : values) {
-                if (value.toString().equalsIgnoreCase(found)) {
-                    return value;
-                }
-            }
-        }
-
-        return defaultValue;
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java
deleted file mode 100755
index 725dcbb..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.repository;
-
-
-import java.io.InputStream;
-
-/**
- * Public constants for the sdk-repository XML Schema.
- */
-public class SdkRepository {
-
-    /** The URL of the official Google sdk-repository site. */
-    public static final String URL_GOOGLE_SDK_REPO_SITE =
-        "https://dl-ssl.google.com/android/repository/";                        //$NON-NLS-1$
-
-    public static final String URL_DEFAULT_XML_FILE = "repository.xml";         //$NON-NLS-1$
-
-    /** The base of our XML namespace. */
-    private static final String NS_SDK_REPOSITORY_BASE =
-        "http://schemas.android.com/sdk/android/repository/";                   //$NON-NLS-1$
-
-    /** The pattern of our XML namespace. */
-    public static final String NS_SDK_REPOSITORY_PATTERN =
-        NS_SDK_REPOSITORY_BASE + "[1-9][0-9]*";        //$NON-NLS-1$
-
-    /** The latest version of the sdk-repository XML Schema.
-     *  Valid version numbers are between 1 and this number, included. */
-    public static final int NS_LATEST_VERSION = 1;
-
-    /** The XML namespace of the latest sdk-repository XML. */
-    public static final String NS_SDK_REPOSITORY = getSchemaUri(NS_LATEST_VERSION);
-
-    /** The root sdk-repository element */
-    public static final String NODE_SDK_REPOSITORY = "sdk-repository";          //$NON-NLS-1$
-
-    /** A platform package. */
-    public static final String NODE_PLATFORM = "platform";                      //$NON-NLS-1$
-    /** An add-on package. */
-    public static final String NODE_ADD_ON   = "add-on";                        //$NON-NLS-1$
-    /** A tool package. */
-    public static final String NODE_TOOL     = "tool";                          //$NON-NLS-1$
-    /** A doc package. */
-    public static final String NODE_DOC      = "doc";                           //$NON-NLS-1$
-    /** An extra package. */
-    public static final String NODE_EXTRA    = "extra";                         //$NON-NLS-1$
-
-    /** The license definition. */
-    public static final String NODE_LICENSE       = "license";                  //$NON-NLS-1$
-    /** The optional uses-license for all packages (platform, add-on, tool, doc) or for a lib. */
-    public static final String NODE_USES_LICENSE  = "uses-license";             //$NON-NLS-1$
-    /** The revision, an int > 0, for all packages (platform, add-on, tool, doc). */
-    public static final String NODE_REVISION      = "revision";                 //$NON-NLS-1$
-    /** The optional description for all packages (platform, add-on, tool, doc) or for a lib. */
-    public static final String NODE_DESCRIPTION   = "description";              //$NON-NLS-1$
-    /** The optional description URL for all packages (platform, add-on, tool, doc). */
-    public static final String NODE_DESC_URL      = "desc-url";                 //$NON-NLS-1$
-    /** The optional release note for all packages (platform, add-on, tool, doc). */
-    public static final String NODE_RELEASE_NOTE  = "release-note";             //$NON-NLS-1$
-    /** The optional release note URL for all packages (platform, add-on, tool, doc). */
-    public static final String NODE_RELEASE_URL   = "release-url";              //$NON-NLS-1$
-    /** The optional minimal tools revision required by platform & extra packages. */
-    public static final String NODE_MIN_TOOLS_REV = "min-tools-rev";            //$NON-NLS-1$
-
-    /** The version, a string, for platform packages. */
-    public static final String NODE_VERSION   = "version";                      //$NON-NLS-1$
-    /** The api-level, an int > 0, for platform, add-on and doc packages. */
-    public static final String NODE_API_LEVEL = "api-level";                    //$NON-NLS-1$
-    /** The codename, a string, for platform packages. */
-    public static final String NODE_CODENAME = "codename";                      //$NON-NLS-1$
-    /** The vendor, a string, for add-on packages. */
-    public static final String NODE_VENDOR    = "vendor";                       //$NON-NLS-1$
-    /** The name, a string, for add-on packages or for libraries. */
-    public static final String NODE_NAME      = "name";                         //$NON-NLS-1$
-
-    /** The libs container, optional for an add-on. */
-    public static final String NODE_LIBS      = "libs";                         //$NON-NLS-1$
-    /** A lib element in a libs container. */
-    public static final String NODE_LIB       = "lib";                          //$NON-NLS-1$
-
-    /** The path, a string, for extra packages. */
-    public static final String NODE_PATH = "path";                              //$NON-NLS-1$
-
-    /** The archives container, for all packages. */
-    public static final String NODE_ARCHIVES = "archives";                      //$NON-NLS-1$
-    /** An archive element, for the archives container. */
-    public static final String NODE_ARCHIVE  = "archive";                       //$NON-NLS-1$
-
-    /** An archive size, an int > 0. */
-    public static final String NODE_SIZE     = "size";                          //$NON-NLS-1$
-    /** A sha1 archive checksum, as a 40-char hex. */
-    public static final String NODE_CHECKSUM = "checksum";                      //$NON-NLS-1$
-    /** A download archive URL, either absolute or relative to the repository xml. */
-    public static final String NODE_URL      = "url";                           //$NON-NLS-1$
-
-    /** An archive checksum type, mandatory. */
-    public static final String ATTR_TYPE = "type";                              //$NON-NLS-1$
-    /** An archive OS attribute, mandatory. */
-    public static final String ATTR_OS   = "os";                                //$NON-NLS-1$
-    /** An optional archive Architecture attribute. */
-    public static final String ATTR_ARCH = "arch";                              //$NON-NLS-1$
-
-    /** A license definition ID. */
-    public static final String ATTR_ID = "id";                                  //$NON-NLS-1$
-    /** A license reference. */
-    public static final String ATTR_REF = "ref";                                //$NON-NLS-1$
-
-    /** Type of a sha1 checksum. */
-    public static final String SHA1_TYPE = "sha1";                              //$NON-NLS-1$
-
-    /** Length of a string representing a SHA1 checksum; always 40 characters long. */
-    public static final int SHA1_CHECKSUM_LEN = 40;
-
-
-    /**
-     * Returns a stream to the requested repository XML Schema.
-     *
-     * @param version Between 1 and {@link #NS_LATEST_VERSION}, included.
-     * @return An {@link InputStream} object for the local XSD file or
-     *         null if there is no schema for the requested version.
-     */
-    public static InputStream getXsdStream(int version) {
-        String filename = String.format("sdk-repository-%d.xsd", version);      //$NON-NLS-1$
-        return SdkRepository.class.getResourceAsStream(filename);
-    }
-
-    /**
-     * Returns the URI of the SDK Repository schema for the given version number.
-     * @param version Between 1 and {@link #NS_LATEST_VERSION} included.
-     */
-    public static String getSchemaUri(int version) {
-        return String.format(NS_SDK_REPOSITORY_BASE + "%d", version);           //$NON-NLS-1$
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-1.xsd b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-1.xsd
deleted file mode 100755
index f00e337..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-1.xsd
+++ /dev/null
@@ -1,379 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
--->
-<xsd:schema
-    targetNamespace="http://schemas.android.com/sdk/android/repository/1"
-    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-    xmlns:sdk="http://schemas.android.com/sdk/android/repository/1"
-    elementFormDefault="qualified"
-    attributeFormDefault="unqualified"
-    version="1">
-
-    <!-- The repository contains a collection of downloadable items known as
-         "packages". Each package has a type and various attributes and contains
-         a list of file "archives" that can be downloaded for specific OSes.
-
-         An Android SDK repository is a web site that contains a "repository.xml"
-         file that conforms to this XML Schema.
-    -->
-
-    <xsd:element name="sdk-repository">
-        <xsd:annotation>
-            <xsd:documentation>
-                The repository contains collections of downloadable packages.
-            </xsd:documentation>
-        </xsd:annotation>
-
-        <xsd:complexType>
-            <xsd:choice minOccurs="0" maxOccurs="unbounded">
-
-                <!-- The definition of an SDK platform package. -->
-
-                <xsd:element name="platform">
-                    <xsd:annotation>
-                        <xsd:documentation>An SDK platform package.</xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:complexType>
-                        <xsd:all>
-                            <!-- The Android platform version. It is string such as "1.0". -->
-                            <xsd:element name="version"   type="xsd:normalizedString" />
-                            <!-- The Android API Level for the platform. An int > 0. -->
-                            <xsd:element name="api-level" type="xsd:positiveInteger"  />
-                            <!-- The optional codename for this platform, if it's a preview. -->
-                            <xsd:element name="codename"  type="xsd:string" minOccurs="0" />
-
-                            <!-- The revision, an int > 0, incremented each time a new
-                                 package is generated. -->
-                            <xsd:element name="revision"     type="xsd:positiveInteger" />
-                            <!-- The optional license of this package. If present, users will have
-                                 to agree to it before downloading. -->
-                            <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" />
-                            <!-- The optional description of this package. -->
-                            <xsd:element name="description"  type="xsd:string"      minOccurs="0" />
-                            <!-- The optional description URL of this package -->
-                            <xsd:element name="desc-url"     type="xsd:token"       minOccurs="0" />
-                            <!-- The optional release note for this package. -->
-                            <xsd:element name="release-note" type="xsd:string"      minOccurs="0" />
-                            <!-- The optional release note URL of this package -->
-                            <xsd:element name="release-url"  type="xsd:token"       minOccurs="0" />
-                            <!-- A list of file archives for this package. -->
-                            <xsd:element name="archives"     type="sdk:archivesType" />
-                            <!-- The minimal revision of tools required by this package.
-                                 Optional. If present, must be an int > 0. -->
-                            <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" />
-                        </xsd:all>
-                    </xsd:complexType>
-                </xsd:element>
-
-
-                <!-- The definition of an SDK Add-on package. -->
-
-                <xsd:element name="add-on">
-                    <xsd:annotation>
-                        <xsd:documentation>An SDK add-on package.</xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:complexType>
-                        <xsd:all>
-                            <!-- The name of the add-on. -->
-                            <xsd:element name="name"      type="xsd:normalizedString" />
-                            <!-- The vendor of the add-on. -->
-                            <xsd:element name="vendor"    type="xsd:normalizedString" />
-                            <!-- The Android API Level for the add-on. An int > 0. -->
-                            <xsd:element name="api-level" type="xsd:positiveInteger"  />
-                            <!-- The optional codename for this add-on, if it's a preview. -->
-                            <xsd:element name="codename"  type="xsd:string" minOccurs="0" />
-
-                            <!-- The revision, an int > 0, incremented each time a new
-                                 package is generated. -->
-                            <xsd:element name="revision"     type="xsd:positiveInteger" />
-                            <!-- The optional license of this package. If present, users will have
-                                 to agree to it before downloading. -->
-                            <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" />
-                            <!-- The optional description of this package. -->
-                            <xsd:element name="description"  type="xsd:string"      minOccurs="0" />
-                            <!-- The optional description URL of this package -->
-                            <xsd:element name="desc-url"     type="xsd:token"       minOccurs="0" />
-                            <!-- The optional release note for this package. -->
-                            <xsd:element name="release-note" type="xsd:string"      minOccurs="0" />
-                            <!-- The optional release note URL of this package -->
-                            <xsd:element name="release-url"  type="xsd:token"       minOccurs="0" />
-                            <!-- A list of file archives for this package. -->
-                            <xsd:element name="archives"     type="sdk:archivesType" />
-
-                            <!-- An add-on can declare 0 or more libraries. -->
-
-                            <xsd:element name="libs">
-                                <xsd:complexType>
-                                    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
-                                        <xsd:element name="lib">
-                                            <xsd:complexType>
-                                                <xsd:all>
-                                                    <!-- The name of the library. -->
-                                                    <xsd:element name="name" type="xsd:normalizedString" />
-                                                    <!-- The optional description of this add-on library. -->
-                                                    <xsd:element name="description" type="xsd:string" minOccurs="0" />
-                                                </xsd:all>
-                                            </xsd:complexType>
-                                        </xsd:element>
-                                    </xsd:sequence>
-                                </xsd:complexType>
-                            </xsd:element>
-                        </xsd:all>
-                    </xsd:complexType>
-                </xsd:element>
-
-
-                <!-- The definition of an SDK tool package. -->
-
-                <xsd:element name="tool">
-                    <xsd:annotation>
-                        <xsd:documentation>An SDK tool package.</xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:complexType>
-                        <xsd:all>
-                            <!-- The revision, an int > 0, incremented each time a new
-                                 package is generated. -->
-                            <xsd:element name="revision"     type="xsd:positiveInteger" />
-                            <!-- The optional license of this package. If present, users will have
-                                 to agree to it before downloading. -->
-                            <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" />
-                            <!-- The optional description of this package. -->
-                            <xsd:element name="description"  type="xsd:string"      minOccurs="0" />
-                            <!-- The optional description URL of this package -->
-                            <xsd:element name="desc-url"     type="xsd:token"       minOccurs="0" />
-                            <!-- The optional release note for this package. -->
-                            <xsd:element name="release-note" type="xsd:string"      minOccurs="0" />
-                            <!-- The optional release note URL of this package -->
-                            <xsd:element name="release-url"  type="xsd:token"       minOccurs="0" />
-                            <!-- A list of file archives for this package. -->
-                            <xsd:element name="archives"     type="sdk:archivesType" />
-                        </xsd:all>
-                    </xsd:complexType>
-                </xsd:element>
-
-
-                <!-- The definition of an SDK doc package. -->
-
-                <xsd:element name="doc">
-                    <xsd:annotation>
-                        <xsd:documentation>An SDK doc package.</xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:complexType>
-                        <xsd:all>
-                            <!-- The Android API Level for the documentation. An int > 0. -->
-                            <xsd:element name="api-level" type="xsd:positiveInteger"  />
-                            <!-- The optional codename for this doc, if it's a preview. -->
-                            <xsd:element name="codename"  type="xsd:string" minOccurs="0" />
-
-                            <!-- The revision, an int > 0, incremented each time a new
-                                 package is generated. -->
-                            <xsd:element name="revision"     type="xsd:positiveInteger" />
-                            <!-- The optional license of this package. If present, users will have
-                                 to agree to it before downloading. -->
-                            <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" />
-                            <!-- The optional description of this package. -->
-                            <xsd:element name="description"  type="xsd:string"      minOccurs="0" />
-                            <!-- The optional description URL of this package -->
-                            <xsd:element name="desc-url"     type="xsd:token"       minOccurs="0" />
-                            <!-- The optional release note for this package. -->
-                            <xsd:element name="release-note" type="xsd:string"      minOccurs="0" />
-                            <!-- The optional release note URL of this package -->
-                            <xsd:element name="release-url"  type="xsd:token"       minOccurs="0" />
-                            <!-- A list of file archives for this package. -->
-                            <xsd:element name="archives"     type="sdk:archivesType" />
-                        </xsd:all>
-                    </xsd:complexType>
-                </xsd:element>
-
-
-                <!-- The definition of an SDK extra package. This kind of package is for
-                     "free" content and specifies in which fixed root directory it must be
-                     installed.
-                -->
-
-                <xsd:element name="extra">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            An SDK extra package. This kind of package is for "free"
-                            content and specifies in which fixed root directory it must be
-                            installed.
-                            The paths "add-ons", "platforms", "tools" and "docs" are
-                            reserved and cannot be used.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:complexType>
-                        <xsd:all>
-                            <!-- The install folder name. It must be a single-segment path.
-                                 The paths "add-ons", "platforms", "tools" and "docs" are
-                                 reserved and cannot be used.
-                            -->
-                            <xsd:element name="path">
-                                <xsd:simpleType>
-                                    <xsd:restriction base="xsd:token">
-                                        <xsd:pattern value="[^/\\]+"/>
-                                    </xsd:restriction>
-                                </xsd:simpleType>
-                            </xsd:element>
-
-                            <!-- The revision, an int > 0, incremented each time a new
-                                 package is generated. -->
-                            <xsd:element name="revision"     type="xsd:positiveInteger" />
-                            <!-- The optional license of this package. If present, users will have
-                                 to agree to it before downloading. -->
-                            <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" />
-                            <!-- The optional description of this package. -->
-                            <xsd:element name="description"  type="xsd:string"      minOccurs="0" />
-                            <!-- The optional description URL of this package -->
-                            <xsd:element name="desc-url"     type="xsd:token"       minOccurs="0" />
-                            <!-- The optional release note for this package. -->
-                            <xsd:element name="release-note" type="xsd:string"      minOccurs="0" />
-                            <!-- The optional release note URL of this package -->
-                            <xsd:element name="release-url"  type="xsd:token"       minOccurs="0" />
-                            <!-- A list of file archives for this package. -->
-                            <xsd:element name="archives"     type="sdk:archivesType" />
-                            <!-- The minimal revision of tools required by this package.
-                                 Optional. If present, must be an int > 0. -->
-                            <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" />
-                        </xsd:all>
-                    </xsd:complexType>
-                </xsd:element>
-
-
-
-                <!-- The definition of a license to be referenced by the uses-license element. -->
-
-                <xsd:element name="license">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            A license definition. Such a license must be used later as a reference
-                            using a uses-license element in one of the package elements.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:complexType>
-                        <xsd:simpleContent>
-                            <xsd:extension base="xsd:string">
-                                <xsd:attribute name="id"   type="xsd:ID" />
-                                <xsd:attribute name="type" type="xsd:token" fixed="text" />
-                            </xsd:extension>
-                        </xsd:simpleContent>
-                    </xsd:complexType>
-                </xsd:element>
-            </xsd:choice>
-        </xsd:complexType>
-    </xsd:element>
-
-
-    <!-- Type describing the license used by a package.
-         The license MUST be defined using a license node and referenced
-         using the ref attribute of the license element inside a package.
-     -->
-
-    <xsd:complexType name="licenseType">
-        <xsd:annotation>
-            <xsd:documentation>
-                Describes the license used by a package. The license MUST be defined
-                using a license node and referenced using the ref attribute of the
-                license element inside a package.
-            </xsd:documentation>
-        </xsd:annotation>
-        <xsd:attribute name="ref" type="xsd:IDREF" />
-    </xsd:complexType>
-
-
-    <!-- A collection of files that can be downloaded for a given architecture.
-         The <archives> node is mandatory in the repository elements and the
-         collection must have at least one <archive> declared.
-         Each archive is a zip file that will be unzipped in a location that depends
-         on its package type.
-     -->
-
-    <xsd:complexType name="archivesType">
-        <xsd:annotation>
-            <xsd:documentation>
-                A collection of files that can be downloaded for a given architecture.
-                The &lt;archives&gt; node is mandatory in the repository packages and the
-                collection must have at least one &lt;archive&gt; declared.
-                Each archive is a zip file that will be unzipped in a location that depends
-                on its package type.
-            </xsd:documentation>
-        </xsd:annotation>
-        <xsd:sequence minOccurs="1" maxOccurs="unbounded">
-            <!-- One archive file -->
-            <xsd:element name="archive">
-                <xsd:complexType>
-                    <!-- Properties of the archive file -->
-                    <xsd:all>
-                        <!-- The size in bytes of the archive to download. -->
-                        <xsd:element name="size"     type="xsd:positiveInteger" />
-                        <!-- The checksum of the archive file. -->
-                        <xsd:element name="checksum" type="sdk:checksumType" />
-                        <!-- The URL is an absolute URL if it starts with http://, https://
-                             or ftp://. Otherwise it is relative to the parent directory that
-                             contains this repository.xml -->
-                        <xsd:element name="url"      type="xsd:token" />
-                    </xsd:all>
-
-                    <!-- Attributes that identify the OS and architecture -->
-                    <xsd:attribute name="os" use="required">
-                        <xsd:simpleType>
-                            <xsd:restriction base="xsd:token">
-                                <xsd:enumeration value="any" />
-                                <xsd:enumeration value="linux" />
-                                <xsd:enumeration value="macosx" />
-                                <xsd:enumeration value="windows" />
-                            </xsd:restriction>
-                        </xsd:simpleType>
-                    </xsd:attribute>
-                    <xsd:attribute name="arch" use="optional">
-                        <xsd:simpleType>
-                            <xsd:restriction base="xsd:token">
-                                <xsd:enumeration value="any" />
-                                <xsd:enumeration value="ppc" />
-                                <xsd:enumeration value="x86" />
-                                <xsd:enumeration value="x86_64" />
-                            </xsd:restriction>
-                        </xsd:simpleType>
-                    </xsd:attribute>
-                </xsd:complexType>
-            </xsd:element>
-        </xsd:sequence>
-    </xsd:complexType>
-
-
-    <!-- The definition of a file checksum -->
-
-    <xsd:simpleType name="sha1Number">
-        <xsd:annotation>
-            <xsd:documentation>A SHA1 checksum.</xsd:documentation>
-        </xsd:annotation>
-        <xsd:restriction base="xsd:string">
-            <xsd:pattern value="([0-9a-fA-F]){40}"/>
-        </xsd:restriction>
-    </xsd:simpleType>
-
-    <xsd:complexType name="checksumType">
-        <xsd:annotation>
-            <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation>
-        </xsd:annotation>
-        <xsd:simpleContent>
-            <xsd:extension base="sdk:sha1Number">
-                <xsd:attribute name="type" type="xsd:token" fixed="sha1" />
-            </xsd:extension>
-        </xsd:simpleContent>
-    </xsd:complexType>
-
-
-</xsd:schema>
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidManifest.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidManifest.java
deleted file mode 100644
index c4fa8bc..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidManifest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.xml;
-
-/**
- * Helper and Constants for the AndroidManifest.xml file.
- *
- */
-public final class AndroidManifest {
-
-    public final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$
-    public final static String NODE_APPLICATION = "application"; //$NON-NLS-1$
-    public final static String NODE_ACTIVITY = "activity"; //$NON-NLS-1$
-    public final static String NODE_SERVICE = "service"; //$NON-NLS-1$
-    public final static String NODE_RECEIVER = "receiver"; //$NON-NLS-1$
-    public final static String NODE_PROVIDER = "provider"; //$NON-NLS-1$
-    public final static String NODE_INTENT = "intent-filter"; //$NON-NLS-1$
-    public final static String NODE_ACTION = "action"; //$NON-NLS-1$
-    public final static String NODE_CATEGORY = "category"; //$NON-NLS-1$
-    public final static String NODE_USES_SDK = "uses-sdk"; //$NON-NLS-1$
-    public final static String NODE_INSTRUMENTATION = "instrumentation"; //$NON-NLS-1$
-    public final static String NODE_USES_LIBRARY = "uses-library"; //$NON-NLS-1$
-
-    public final static String ATTRIBUTE_PACKAGE = "package"; //$NON-NLS-1$
-    public final static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
-    public final static String ATTRIBUTE_PROCESS = "process"; //$NON-NLS-$
-    public final static String ATTRIBUTE_DEBUGGABLE = "debuggable"; //$NON-NLS-$
-    public final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-$
-    public final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage"; //$NON-NLS-1$
-    public final static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$
-
-
-    /**
-     * Combines a java package, with a class value from the manifest to make a fully qualified
-     * class name
-     * @param javaPackage the java package from the manifest.
-     * @param className the class name from the manifest.
-     * @return the fully qualified class name.
-     */
-    public static String combinePackageAndClassName(String javaPackage, String className) {
-        if (className == null || className.length() == 0) {
-            return javaPackage;
-        }
-        if (javaPackage == null || javaPackage.length() == 0) {
-            return className;
-        }
-
-        // the class name can be a subpackage (starts with a '.'
-        // char), a simple class name (no dot), or a full java package
-        boolean startWithDot = (className.charAt(0) == '.');
-        boolean hasDot = (className.indexOf('.') != -1);
-        if (startWithDot || hasDot == false) {
-
-            // add the concatenation of the package and class name
-            if (startWithDot) {
-                return javaPackage + className;
-            } else {
-                return javaPackage + '.' + className;
-            }
-        } else {
-            // just add the class as it should be a fully qualified java name.
-            return className;
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidXPathFactory.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidXPathFactory.java
deleted file mode 100644
index 641cd81..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/xml/AndroidXPathFactory.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.xml;
-
-import com.android.sdklib.SdkConstants;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathFactory;
-
-/**
- * XPath factory with automatic support for the android name space.
- */
-public class AndroidXPathFactory {
-    /** Default prefix for android name space: 'android' */
-    public final static String DEFAULT_NS_PREFIX = "android"; //$NON-NLS-1$
-
-    private final static XPathFactory sFactory = XPathFactory.newInstance();
-
-    /** Name space context for Android resource XML files. */
-    private static class AndroidNamespaceContext implements NamespaceContext {
-        private final static AndroidNamespaceContext sThis = new AndroidNamespaceContext(
-                DEFAULT_NS_PREFIX);
-
-        private final String mAndroidPrefix;
-        private final List<String> mAndroidPrefixes = new ArrayList<String>();
-
-        /**
-         * Returns the default {@link AndroidNamespaceContext}.
-         */
-        private static AndroidNamespaceContext getDefault() {
-            return sThis;
-        }
-
-        /**
-         * Construct the context with the prefix associated with the android namespace.
-         * @param androidPrefix the Prefix
-         */
-        public AndroidNamespaceContext(String androidPrefix) {
-            mAndroidPrefix = androidPrefix;
-            mAndroidPrefixes.add(mAndroidPrefix);
-        }
-
-        public String getNamespaceURI(String prefix) {
-            if (prefix != null) {
-                if (prefix.equals(mAndroidPrefix)) {
-                    return SdkConstants.NS_RESOURCES;
-                }
-            }
-
-            return XMLConstants.NULL_NS_URI;
-        }
-
-        public String getPrefix(String namespaceURI) {
-            if (SdkConstants.NS_RESOURCES.equals(namespaceURI)) {
-                return mAndroidPrefix;
-            }
-
-            return null;
-        }
-
-        public Iterator<?> getPrefixes(String namespaceURI) {
-            if (SdkConstants.NS_RESOURCES.equals(namespaceURI)) {
-                return mAndroidPrefixes.iterator();
-            }
-
-            return null;
-        }
-    }
-
-    /**
-     * Creates a new XPath object, specifying which prefix in the query is used for the
-     * android namespace.
-     * @param androidPrefix The namespace prefix.
-     */
-    public static XPath newXPath(String androidPrefix) {
-        XPath xpath = sFactory.newXPath();
-        xpath.setNamespaceContext(new AndroidNamespaceContext(androidPrefix));
-        return xpath;
-    }
-
-    /**
-     * Creates a new XPath object using the default prefix for the android namespace.
-     * @see #DEFAULT_NS_PREFIX
-     */
-    public static XPath newXPath() {
-        XPath xpath = sFactory.newXPath();
-        xpath.setNamespaceContext(AndroidNamespaceContext.getDefault());
-        return xpath;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockAddonPackage.java b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockAddonPackage.java
deleted file mode 100755
index 4d4199f..0000000
--- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockAddonPackage.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-
-/**
- * A mock {@link AddonPackage} for testing.
- *
- * By design, this package contains one and only one archive.
- */
-public class MockAddonPackage extends AddonPackage {
-
-    /**
-     * Creates a {@link MockAddonTarget} with the requested base platform and addon revision
-     * and then a {@link MockAddonPackage} wrapping it.
-     *
-     * By design, this package contains one and only one archive.
-     */
-    public MockAddonPackage(MockPlatformPackage basePlatform, int revision) {
-        super(new MockAddonTarget(basePlatform.getTarget(), revision), null /*props*/);
-    }
-
-    /**
-     * A mock AddonTarget.
-     * This reimplements the minimum needed from the interface for our limited testing needs.
-     */
-    static class MockAddonTarget implements IAndroidTarget {
-
-        private final IAndroidTarget mParentTarget;
-        private final int mRevision;
-
-        public MockAddonTarget(IAndroidTarget parentTarget, int revision) {
-            mParentTarget = parentTarget;
-            mRevision = revision;
-        }
-
-        public String getClasspathName() {
-            return null;
-        }
-
-        public String getDefaultSkin() {
-            return null;
-        }
-
-        public String getDescription() {
-            return "mock addon target";
-        }
-
-        public String getFullName() {
-            return "mock addon target";
-        }
-
-        public String getLocation() {
-            return "";
-        }
-
-        public String getName() {
-            return "mock addon target";
-        }
-
-        public IOptionalLibrary[] getOptionalLibraries() {
-            return null;
-        }
-
-        public IAndroidTarget getParent() {
-            return mParentTarget;
-        }
-
-        public String getPath(int pathId) {
-            return null;
-        }
-
-        public String[] getPlatformLibraries() {
-            return null;
-        }
-
-        public int getRevision() {
-            return mRevision;
-        }
-
-        public String[] getSkins() {
-            return null;
-        }
-
-        public int getUsbVendorId() {
-            return 0;
-        }
-
-        public String getVendor() {
-            return null;
-        }
-
-        public AndroidVersion getVersion() {
-            return mParentTarget.getVersion();
-        }
-
-        public String getVersionName() {
-            return String.format("mock-addon-%1$d", getVersion().getApiLevel());
-        }
-
-        public String hashString() {
-            return getVersionName();
-        }
-
-        /** Returns false for an addon. */
-        public boolean isPlatform() {
-            return false;
-        }
-
-        public boolean isCompatibleBaseFor(IAndroidTarget target) {
-            throw new UnsupportedOperationException("Implement this as needed for tests");
-        }
-
-        public int compareTo(IAndroidTarget o) {
-            throw new UnsupportedOperationException("Implement this as needed for tests");
-        }
-
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockPlatformPackage.java b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockPlatformPackage.java
deleted file mode 100755
index b840b82..0000000
--- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockPlatformPackage.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-
-import java.util.Properties;
-
-/**
- * A mock {@link PlatformPackage} for testing.
- *
- * By design, this package contains one and only one archive.
- */
-public class MockPlatformPackage extends PlatformPackage {
-
-    private final IAndroidTarget mTarget;
-
-    /**
-     * Creates a {@link MockPlatformTarget} with the requested API and revision
-     * and then a {@link MockPlatformPackage} wrapping it.
-     *
-     * By design, this package contains one and only one archive.
-     */
-    public MockPlatformPackage(int apiLevel, int revision) {
-        this(new MockPlatformTarget(apiLevel, revision), null /*props*/);
-    }
-
-    /**
-     * Creates a {@link MockPlatformTarget} with the requested API and revision
-     * and then a {@link MockPlatformPackage} wrapping it.
-     *
-     * Also sets the min-tools-rev of the platform.
-     *
-     * By design, this package contains one and only one archive.
-     */
-    public MockPlatformPackage(int apiLevel, int revision, int min_tools_rev) {
-        this(new MockPlatformTarget(apiLevel, revision), createProps(min_tools_rev));
-    }
-
-    /** A little trick to be able to capture the target new after passing it to the super. */
-    private MockPlatformPackage(IAndroidTarget target, Properties props) {
-        super(target, props);
-        mTarget = target;
-    }
-
-    private static Properties createProps(int min_tools_rev) {
-        Properties props = new Properties();
-        props.setProperty(PlatformPackage.PROP_MIN_TOOLS_REV, Integer.toString((min_tools_rev)));
-        return props;
-    }
-
-    public IAndroidTarget getTarget() {
-        return mTarget;
-    }
-
-    /**
-     * A mock PlatformTarget.
-     * This reimplements the minimum needed from the interface for our limited testing needs.
-     */
-    static class MockPlatformTarget implements IAndroidTarget {
-
-        private final int mApiLevel;
-        private final int mRevision;
-
-        public MockPlatformTarget(int apiLevel, int revision) {
-            mApiLevel = apiLevel;
-            mRevision = revision;
-
-        }
-
-        public String getClasspathName() {
-            return null;
-        }
-
-        public String getDefaultSkin() {
-            return null;
-        }
-
-        public String getDescription() {
-            return "mock platform target";
-        }
-
-        public String getFullName() {
-            return "mock platform target";
-        }
-
-        public String getLocation() {
-            return "";
-        }
-
-        public String getName() {
-            return "mock platform target";
-        }
-
-        public IOptionalLibrary[] getOptionalLibraries() {
-            return null;
-        }
-
-        public IAndroidTarget getParent() {
-            return null;
-        }
-
-        public String getPath(int pathId) {
-            return null;
-        }
-
-        public String[] getPlatformLibraries() {
-            return null;
-        }
-
-        public int getRevision() {
-            return mRevision;
-        }
-
-        public String[] getSkins() {
-            return null;
-        }
-
-        public int getUsbVendorId() {
-            return 0;
-        }
-
-        public String getVendor() {
-            return null;
-        }
-
-        public AndroidVersion getVersion() {
-            return new AndroidVersion(mApiLevel, null /*codename*/);
-        }
-
-        public String getVersionName() {
-            return String.format("android-%1$d", mApiLevel);
-        }
-
-        public String hashString() {
-            return getVersionName();
-        }
-
-        /** Returns true for a platform. */
-        public boolean isPlatform() {
-            return true;
-        }
-
-        public boolean isCompatibleBaseFor(IAndroidTarget target) {
-            throw new UnsupportedOperationException("Implement this as needed for tests");
-        }
-
-        public int compareTo(IAndroidTarget o) {
-            throw new UnsupportedOperationException("Implement this as needed for tests");
-        }
-
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockToolPackage.java b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockToolPackage.java
deleted file mode 100755
index e1ce621..0000000
--- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockToolPackage.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.internal.repository.Archive.Arch;
-import com.android.sdklib.internal.repository.Archive.Os;
-
-/**
- * A mock {@link ToolPackage} for testing.
- *
- * By design, this package contains one and only one archive.
- */
-public class MockToolPackage extends ToolPackage {
-
-    /**
-     * Creates a {@link MockToolPackage} with the given revision and hardcoded defaults
-     * for everything else.
-     * <p/>
-     * By design, this creates a package with one and only one archive.
-     */
-    public MockToolPackage(int revision) {
-        super(
-            null, // source,
-            null, // props,
-            revision,
-            null, // license,
-            "desc", // description,
-            "url", // descUrl,
-            Os.getCurrentOs(), // archiveOs,
-            Arch.getCurrentArch(), // archiveArch,
-            "foo" // archiveOsPath
-            );
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/RepoSourceTest.java b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/RepoSourceTest.java
deleted file mode 100755
index 87da294..0000000
--- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/RepoSourceTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.internal.repository;
-
-import com.android.sdklib.repository.SdkRepository;
-
-import org.w3c.dom.Document;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link RepoSource}
- */
-public class RepoSourceTest extends TestCase {
-
-    private static class MockMonitor implements ITaskMonitor {
-        public void setResult(String resultFormat, Object... args) {
-        }
-
-        public void setProgressMax(int max) {
-        }
-
-        public void setDescription(String descriptionFormat, Object... args) {
-        }
-
-        public boolean isCancelRequested() {
-            return false;
-        }
-
-        public void incProgress(int delta) {
-        }
-
-        public int getProgress() {
-            return 0;
-        }
-
-        public boolean displayPrompt(String title, String message) {
-            return false;
-        }
-
-        public ITaskMonitor createSubMonitor(int tickCount) {
-            return null;
-        }
-    }
-
-    /**
-     * An internal helper class to give us visibility to the protected members we want
-     * to test.
-     */
-    private static class MockRepoSource extends RepoSource {
-        public MockRepoSource() {
-            super("fake-url", false /*userSource*/);
-        }
-
-        public Document _findAlternateToolsXml(InputStream xml) {
-            return super.findAlternateToolsXml(xml);
-        }
-
-        public boolean _parsePackages(Document doc, String nsUri, ITaskMonitor monitor) {
-            return super.parsePackages(doc, nsUri, monitor);
-        }
-    }
-
-    private MockRepoSource mSource;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mSource = new MockRepoSource();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        mSource = null;
-    }
-
-    public void testFindAlternateToolsXml_Errors() {
-        // Support null as input
-        Document result = mSource._findAlternateToolsXml(null);
-        assertNull(result);
-
-        // Support an empty input
-        String str = "";
-        ByteArrayInputStream input = new ByteArrayInputStream(str.getBytes());
-        result = mSource._findAlternateToolsXml(input);
-        assertNull(result);
-
-        // Support a random string as input
-        str = "Some random string, not even HTML nor XML";
-        input = new ByteArrayInputStream(str.getBytes());
-        result = mSource._findAlternateToolsXml(input);
-        assertNull(result);
-
-        // Support an HTML input, e.g. a typical 404 document as returned by DL
-        str = "<html><head> " +
-        "<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"> " +
-        "<title>404 Not Found</title> " + "<style><!--" + "body {font-family: arial,sans-serif}" +
-        "div.nav { ... blah blah more css here ... color: green}" +
-        "//--></style> " + "<script><!--" + "var rc=404;" + "//-->" + "</script> " + "</head> " +
-        "<body text=#000000 bgcolor=#ffffff> " +
-        "<table border=0 cellpadding=2 cellspacing=0 width=100%><tr><td rowspan=3 width=1% nowrap> " +
-        "<b><font face=times color=#0039b6 size=10>G</font><font face=times color=#c41200 size=10>o</font><font face=times color=#f3c518 size=10>o</font><font face=times color=#0039b6 size=10>g</font><font face=times color=#30a72f size=10>l</font><font face=times color=#c41200 size=10>e</font>&nbsp;&nbsp;</b> " +
-        "<td>&nbsp;</td></tr> " +
-        "<tr><td bgcolor=\"#3366cc\"><font face=arial,sans-serif color=\"#ffffff\"><b>Error</b></td></tr> " +
-        "<tr><td>&nbsp;</td></tr></table> " + "<blockquote> " + "<H1>Not Found</H1> " +
-        "The requested URL <code>/404</code> was not found on this server." + " " + "<p> " +
-        "</blockquote> " +
-        "<table width=100% cellpadding=0 cellspacing=0><tr><td bgcolor=\"#3366cc\"><img alt=\"\" width=1 height=4></td></tr></table> " +
-        "</body></html> ";
-        input = new ByteArrayInputStream(str.getBytes());
-        result = mSource._findAlternateToolsXml(input);
-        assertNull(result);
-
-        // Support some random XML document, totally unrelated to our sdk-repository schema
-        str = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
-        "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"" +
-        "    package=\"some.cool.app\" android:versionName=\"1.6.04\" android:versionCode=\"1604\">" +
-        "    <application android:label=\"@string/app_name\" android:icon=\"@drawable/icon\"/>" +
-        "</manifest>";
-        input = new ByteArrayInputStream(str.getBytes());
-        result = mSource._findAlternateToolsXml(input);
-        assertNull(result);
-    }
-
-    public void testFindAlternateToolsXml_1() {
-        InputStream xmlStream = this.getClass().getResourceAsStream(
-                    "/com/android/sdklib/testdata/repository_sample_1.xml");
-
-        Document result = mSource._findAlternateToolsXml(xmlStream);
-        assertNotNull(result);
-        assertTrue(mSource._parsePackages(result,
-                SdkRepository.NS_SDK_REPOSITORY, new MockMonitor()));
-
-        // check the packages we found... we expected to find 2 tool packages with 1 archive each.
-        Package[] pkgs = mSource.getPackages();
-        assertEquals(2, pkgs.length);
-        for (Package p : pkgs) {
-            assertEquals(ToolPackage.class, p.getClass());
-            assertEquals(1, p.getArchives().length);
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/SdkRepositoryTest.java b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/SdkRepositoryTest.java
deleted file mode 100755
index 17bbaa1..0000000
--- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/SdkRepositoryTest.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdklib.repository;
-
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-import java.io.InputStream;
-import java.io.StringReader;
-
-import javax.xml.XMLConstants;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-
-import junit.framework.TestCase;
-
-/**
- * Tests local validation of an SDK Repository sample XMLs using an XML Schema validator.
- *
- * References:
- * http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html
- */
-public class SdkRepositoryTest extends TestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * A SAX error handler that captures the errors and warnings.
-     * This allows us to capture *all* errors and just not get an exception on the first one.
-     */
-    private static class CaptureErrorHandler implements ErrorHandler {
-
-        private String mWarnings = "";
-        private String mErrors = "";
-
-        @SuppressWarnings("unused")
-        public String getErrors() {
-            return mErrors;
-        }
-
-        @SuppressWarnings("unused")
-        public String getWarnings() {
-            return mWarnings;
-        }
-
-        /**
-         * Verifies if the handler captures some errors or warnings.
-         * Prints them on stderr.
-         * Also fails the unit test if any error was generated.
-         */
-        public void verify() {
-            if (mWarnings.length() > 0) {
-                System.err.println(mWarnings);
-            }
-
-            if (mErrors.length() > 0) {
-                System.err.println(mErrors);
-                fail(mErrors);
-            }
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void error(SAXParseException ex) throws SAXException {
-            mErrors += "Error: " + ex.getMessage() + "\n";
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void fatalError(SAXParseException ex) throws SAXException {
-            mErrors += "Fatal Error: " + ex.getMessage() + "\n";
-        }
-
-        /**
-         * @throws SAXException
-         */
-        public void warning(SAXParseException ex) throws SAXException {
-            mWarnings += "Warning: " + ex.getMessage() + "\n";
-        }
-
-    }
-
-    // --- Helpers ------------
-
-    /** Helper method that returns a validator for our XSD */
-    private Validator getValidator(int version, CaptureErrorHandler handler) throws SAXException {
-        InputStream xsdStream = SdkRepository.getXsdStream(version);
-        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        Schema schema = factory.newSchema(new StreamSource(xsdStream));
-        Validator validator = schema.newValidator();
-        if (handler != null) {
-            validator.setErrorHandler(handler);
-        }
-
-        return validator;
-    }
-
-    /** 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 ------------
-
-    /** Validate a valid sample using namespace version 1 using an InputStream */
-    public void testValidateLocalRepositoryFile1() throws Exception {
-        InputStream xmlStream = this.getClass().getResourceAsStream(
-                    "/com/android/sdklib/testdata/repository_sample_1.xml");
-        Source source = new StreamSource(xmlStream);
-
-        CaptureErrorHandler handler = new CaptureErrorHandler();
-        Validator validator = getValidator(1, handler);
-        validator.validate(source);
-        handler.verify();
-    }
-
-    /** A document should at least have a root to be valid */
-    public void testEmptyXml() throws Exception {
-        String document = "<?xml version=\"1.0\"?>";
-
-        Source source = new StreamSource(new StringReader(document));
-
-        CaptureErrorHandler handler = new CaptureErrorHandler();
-        Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, 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();
-    }
-
-    private static String OPEN_TAG =
-        "<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/" +
-        Integer.toString(SdkRepository.NS_LATEST_VERSION) +
-        "\">";
-
-    private static String CLOSE_TAG = "</r:sdk-repository>";
-
-    /** A document with a root element containing no platform, addon, etc., is valid. */
-    public void testEmptyRootXml() throws Exception {
-        String document = "<?xml version=\"1.0\"?>" +
-            OPEN_TAG +
-            CLOSE_TAG;
-
-        Source source = new StreamSource(new StringReader(document));
-
-        CaptureErrorHandler handler = new CaptureErrorHandler();
-        Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, handler);
-        validator.validate(source);
-        handler.verify();
-    }
-
-    /** A document with an unknown element. */
-    public void testUnknownContentXml() throws Exception {
-        String document = "<?xml version=\"1.0\"?>" +
-            OPEN_TAG +
-            "<r:unknown />" +
-            CLOSE_TAG;
-
-        Source source = new StreamSource(new StringReader(document));
-
-        // don't capture the validator errors, we want it to fail and catch the exception
-        Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, 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();
-    }
-
-    /** A document with an incomplete element. */
-    public void testIncompleteContentXml() throws Exception {
-        String document = "<?xml version=\"1.0\"?>" +
-            OPEN_TAG +
-            "<r:platform> <r:api-level>1</r:api-level> <r:libs /> </r:platform>" +
-            CLOSE_TAG;
-
-        Source source = new StreamSource(new StringReader(document));
-
-        // don't capture the validator errors, we want it to fail and catch the exception
-        Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, 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.*", e.getMessage());
-            return;
-        }
-        // If we get here, the validator has not failed as we expected it to.
-        fail();
-    }
-
-    /** A document with a wrong type element. */
-    public void testWrongTypeContentXml() throws Exception {
-        String document = "<?xml version=\"1.0\"?>" +
-            OPEN_TAG +
-            "<r:platform> <r:api-level>NotAnInteger</r:api-level> <r:libs /> </r:platform>" +
-            CLOSE_TAG;
-
-        Source source = new StreamSource(new StringReader(document));
-
-        // don't capture the validator errors, we want it to fail and catch the exception
-        Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null);
-        try {
-            validator.validate(source);
-        } catch (SAXParseException e) {
-            // We expect a parse error referring to this grammar rule
-            assertRegex("cvc-datatype-valid.1.2.1: 'NotAnInteger' is not a valid value.*",
-                    e.getMessage());
-            return;
-        }
-        // If we get here, the validator has not failed as we expected it to.
-        fail();
-    }
-
-    /** A document an unknown license id. */
-    public void testLicenseIdNotFound() throws Exception {
-        // we define a license named "lic1" and then reference "lic2" instead
-        String document = "<?xml version=\"1.0\"?>" +
-            OPEN_TAG +
-            "<r:license id=\"lic1\"> some license </r:license> " +
-            "<r:tool> <r:uses-license ref=\"lic2\" /> <r:revision>1</r:revision> " +
-            "<r:archives> <r:archive os=\"any\"> <r:size>1</r:size> <r:checksum>2822ae37115ebf13412bbef91339ee0d9454525e</r:checksum> " +
-            "<r:url>url</r:url> </r:archive> </r:archives> </r:tool>" +
-            CLOSE_TAG;
-
-        Source source = new StreamSource(new StringReader(document));
-
-        // don't capture the validator errors, we want it to fail and catch the exception
-        Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null);
-        try {
-            validator.validate(source);
-        } catch (SAXParseException e) {
-            // We expect a parse error referring to this grammar rule
-            assertRegex("cvc-id.1: There is no ID/IDREF binding for IDREF 'lic2'.*",
-                    e.getMessage());
-            return;
-        }
-        // If we get here, the validator has not failed as we expected it to.
-        fail();
-    }
-
-    /** A document a slash in an extra path. */
-    public void testExtraPathWithSlash() throws Exception {
-        // we define a license named "lic1" and then reference "lic2" instead
-        String document = "<?xml version=\"1.0\"?>" +
-            OPEN_TAG +
-            "<r:extra> <r:revision>1</r:revision> <r:path>path/cannot\\contain\\segments</r:path> " +
-            "<r:archives> <r:archive os=\"any\"> <r:size>1</r:size> <r:checksum>2822ae37115ebf13412bbef91339ee0d9454525e</r:checksum> " +
-            "<r:url>url</r:url> </r:archive> </r:archives> </r:extra>" +
-            CLOSE_TAG;
-
-        Source source = new StreamSource(new StringReader(document));
-
-        // don't capture the validator errors, we want it to fail and catch the exception
-        Validator validator = getValidator(SdkRepository.NS_LATEST_VERSION, null);
-        try {
-            validator.validate(source);
-        } catch (SAXParseException e) {
-            // We expect a parse error referring to this grammar rule
-            assertRegex("cvc-pattern-valid: Value 'path/cannot\\\\contain\\\\segments' is not facet-valid with respect to pattern.*",
-                    e.getMessage());
-            return;
-        }
-        // If we get here, the validator has not failed as we expected it to.
-        fail();
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/repository_sample_1.xml b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/repository_sample_1.xml
deleted file mode 100755
index c90e18d..0000000
--- a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/testdata/repository_sample_1.xml
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0"?>
-<!--
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
--->
-<sdk:sdk-repository
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xmlns:sdk="http://schemas.android.com/sdk/android/repository/1">
-
-    <!-- Define a couple of licenses. These will be referenced by uses-license later. -->
-
-    <sdk:license type="text" id="license1">
-        This is the license
-        for this platform.
-    </sdk:license>
-
-    <sdk:license id="license2">
-        Licenses are only of type 'text' right now, so this is implied.
-    </sdk:license>
-
-    <!-- Inner elements must be either platform, add-on, doc or tool.
-         There can be 0 or more of each, in any order. -->
-
-    <sdk:platform>
-        <sdk:version>1.0</sdk:version>
-        <sdk:api-level>1</sdk:api-level>
-        <sdk:revision>3</sdk:revision>
-        <sdk:uses-license ref="license1" />
-        <sdk:description>Some optional description</sdk:description>
-        <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url>
-        <sdk:release-note>This is an optional release note
-            for this package. It's a free multi-line text.
-        </sdk:release-note>
-        <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url>
-        <sdk:min-tools-rev>2</sdk:min-tools-rev>
-        <!-- The archives node is mandatory and it cannot be empty. -->
-        <sdk:archives>
-            <sdk:archive os="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>http://www.example.com/files/plat1.zip</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-    </sdk:platform>
-
-    <sdk:doc>
-        <sdk:api-level>1</sdk:api-level>
-        <sdk:revision>1</sdk:revision>
-        <!-- the license element is not mandatory. -->
-        <sdk:description>Some optional description</sdk:description>
-        <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url>
-        <sdk:archives>
-            <sdk:archive os="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-    </sdk:doc>
-
-    <sdk:add-on>
-        <sdk:name>My First add-on</sdk:name>
-        <sdk:api-level>1</sdk:api-level>
-        <sdk:vendor>John Doe</sdk:vendor>
-        <sdk:revision>1</sdk:revision>
-        <sdk:uses-license ref="license2" />
-        <sdk:description>Some optional description</sdk:description>
-        <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url>
-        <sdk:archives>
-            <sdk:archive os="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-        <!-- The libs node is mandatory, however it can be empty. -->
-        <sdk:libs>
-            <sdk:lib>
-                <sdk:name>android.blah.somelib</sdk:name>
-                <sdk:description>The description for this library.</sdk:description>
-            </sdk:lib>
-            <sdk:lib>
-                <!-- sdk:description is optional, name is not -->
-                <sdk:name>com.android.mymaps</sdk:name>
-            </sdk:lib>
-        </sdk:libs>
-    </sdk:add-on>
-
-    <sdk:platform>
-        <sdk:version>1.1</sdk:version>
-        <sdk:api-level>2</sdk:api-level>
-        <sdk:revision>12</sdk:revision>
-        <sdk:uses-license ref="license1" />
-        <!-- sdk:description and sdk:desc-url are optional -->
-        <sdk:archives>
-            <sdk:archive os="windows">
-                <!--  arch attribute is optional -->
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/platform-2-12-win.zip</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="macosx" arch="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/platform-2-12-mac.zip</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="macosx" arch="ppc">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/platform-2-12-mac.zip</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="linux" arch="x86">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="linux" arch="x86_64">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-    </sdk:platform>
-
-    <sdk:add-on>
-        <sdk:name>My Second add-on</sdk:name>
-        <sdk:api-level>2</sdk:api-level>
-        <sdk:vendor>John Deer</sdk:vendor>
-        <sdk:revision>42</sdk:revision>
-        <sdk:archives>
-            <sdk:archive os="windows">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/second-42-win.zip</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="linux">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-        <sdk:libs>
-            <sdk:lib>
-                <sdk:name>android.blah.somelib</sdk:name>
-                <sdk:description>The description for this library.</sdk:description>
-            </sdk:lib>
-            <sdk:lib>
-                <sdk:name>com.android.mymaps</sdk:name>
-            </sdk:lib>
-        </sdk:libs>
-        <sdk:uses-license ref="license2" />
-    </sdk:add-on>
-
-   <sdk:platform>
-        <sdk:version>Pastry</sdk:version>
-        <sdk:api-level>5</sdk:api-level>
-        <sdk:codename>Pastry</sdk:codename>
-        <sdk:revision>3</sdk:revision>
-        <sdk:uses-license ref="license1" />
-        <sdk:description>Preview version for Pastry</sdk:description>
-        <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url>
-        <!-- The archives node is mandatory and it cannot be empty. -->
-        <sdk:archives>
-            <sdk:archive os="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>http://www.example.com/files/plat1.zip</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-    </sdk:platform>
-
-    <sdk:tool>
-        <sdk:revision>1</sdk:revision>
-        <sdk:description>Some optional description</sdk:description>
-        <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url>
-        <sdk:uses-license ref="license1" />
-        <sdk:archives>
-            <sdk:archive os="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>http://www.example.com/files/tools1.zip</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-    </sdk:tool>
-
-    <sdk:doc>
-        <sdk:api-level>2</sdk:api-level>
-        <sdk:revision>42</sdk:revision>
-        <sdk:uses-license ref="license2" />
-        <sdk:archives>
-            <sdk:archive os="windows">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/docs/2.zip</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="linux">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="macosx">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-    </sdk:doc>
-
-    <sdk:tool>
-        <sdk:revision>42</sdk:revision>
-        <sdk:uses-license ref="license1" />
-        <sdk:archives>
-            <sdk:archive os="windows">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/tools/2.zip</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="linux">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url>
-            </sdk:archive>
-            <sdk:archive os="macosx">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-    </sdk:tool>
-
-    <sdk:add-on>
-        <sdk:uses-license ref="license2" />
-        <sdk:name>This add-on has no libraries</sdk:name>
-        <sdk:api-level>4</sdk:api-level>
-        <sdk:vendor>Joe Bar</sdk:vendor>
-        <sdk:revision>3</sdk:revision>
-        <sdk:archives>
-            <sdk:archive os="any" arch="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-        <!-- The libs node is mandatory, however it can be empty. -->
-        <sdk:libs />
-    </sdk:add-on>
-
-    <sdk:extra>
-        <sdk:path>usb_driver</sdk:path>
-        <sdk:uses-license ref="license2" />
-        <sdk:revision>43</sdk:revision>
-        <sdk:archives>
-            <sdk:archive os="any" arch="any">
-                <sdk:size>65536</sdk:size>
-                <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
-                <sdk:url>distrib/extraduff.zip</sdk:url>
-            </sdk:archive>
-        </sdk:archives>
-        <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description>
-        <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url>
-        <sdk:min-tools-rev>3</sdk:min-tools-rev>
-    </sdk:extra>
-
-</sdk:sdk-repository>
diff --git a/tools/sdkmanager/libs/sdkuilib/.classpath b/tools/sdkmanager/libs/sdkuilib/.classpath
deleted file mode 100644
index 73592c4..0000000
--- a/tools/sdkmanager/libs/sdkuilib/.classpath
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="tests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry exported="true" kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/sdkmanager/libs/sdkuilib/.project b/tools/sdkmanager/libs/sdkuilib/.project
deleted file mode 100644
index da430c8..0000000
--- a/tools/sdkmanager/libs/sdkuilib/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>SdkUiLib</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/sdkmanager/libs/sdkuilib/Android.mk b/tools/sdkmanager/libs/sdkuilib/Android.mk
deleted file mode 100644
index 8e0bc23..0000000
--- a/tools/sdkmanager/libs/sdkuilib/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-SDKUILIB_LOCAL_DIR := $(call my-dir)
-include $(SDKUILIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkmanager/libs/sdkuilib/README b/tools/sdkmanager/libs/sdkuilib/README
deleted file mode 100644
index d66b84a..0000000
--- a/tools/sdkmanager/libs/sdkuilib/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Using the Eclipse projects for ddmuilib.
-
-ddmuilib requires SWT to compile.
-
-SWT is available in the depot under prebuild/<platform>/swt
-
-Because the build path cannot contain relative path that are not inside the project directory,
-the .classpath file references a user library called ANDROID_SWT.
-
-In order to compile the project, make a user library called ANDROID_SWT containing the jar
-available at prebuild/<platform>/swt.
\ No newline at end of file
diff --git a/tools/sdkmanager/libs/sdkuilib/src/Android.mk b/tools/sdkmanager/libs/sdkuilib/src/Android.mk
deleted file mode 100644
index 970c122..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_RESOURCE_DIRS := .
-
-LOCAL_JAVA_LIBRARIES := \
-	sdklib \
-	androidprefs \
-	swt \
-	org.eclipse.jface_3.4.2.M20090107-0800 \
-	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
-	org.eclipse.core.commands_3.4.0.I20080509-2000
-	
-LOCAL_MODULE := sdkuilib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AdbWrapper.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AdbWrapper.java
deleted file mode 100755
index cb553d1..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AdbWrapper.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.internal.repository.ITaskMonitor;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-
-/**
- * A lightweight wrapper to start & stop ADB.
- */
-public class AdbWrapper {
-
-    /*
-     * Note: we could bring ddmlib in SdkManager for that purpose, however this allows us to
-     * specialize the start/stop methods to our needs (e.g. a task monitor, etc.)
-     */
-
-    private final String mAdbOsLocation;
-    private final ITaskMonitor mMonitor;
-
-    /**
-     * Creates a new lightweight ADB wrapper.
-     *
-     * @param osSdkPath The root OS path of the SDK. Cannot be null.
-     * @param monitor A logger object. Cannot be null.
-     */
-    public AdbWrapper(String osSdkPath, ITaskMonitor monitor) {
-        mMonitor = monitor;
-
-        if (!osSdkPath.endsWith(File.separator)) {
-            osSdkPath += File.separator;
-        }
-        mAdbOsLocation = osSdkPath + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_ADB;
-    }
-
-    private void display(String format, Object...args) {
-        mMonitor.setResult(format, args);
-    }
-
-    /**
-     * Starts the adb host side server.
-     * @return true if success
-     */
-    public synchronized boolean startAdb() {
-        if (mAdbOsLocation == null) {
-            display("Error: missing path to ADB."); //$NON-NLS-1$
-            return false;
-        }
-
-        Process proc;
-        int status = -1;
-
-        try {
-            String[] command = new String[2];
-            command[0] = mAdbOsLocation;
-            command[1] = "start-server"; //$NON-NLS-1$
-            proc = Runtime.getRuntime().exec(command);
-
-            ArrayList<String> errorOutput = new ArrayList<String>();
-            ArrayList<String> stdOutput = new ArrayList<String>();
-            status = grabProcessOutput(proc, errorOutput, stdOutput,
-                    false /* waitForReaders */);
-
-        } catch (IOException ioe) {
-            display("Unable to run 'adb': %1$s.", ioe.getMessage()); //$NON-NLS-1$
-            // we'll return false;
-        } catch (InterruptedException ie) {
-            display("Unable to run 'adb': %1$s.", ie.getMessage()); //$NON-NLS-1$
-            // we'll return false;
-        }
-
-        if (status != 0) {
-            display("'adb start-server' failed."); //$NON-NLS-1$
-            return false;
-        }
-
-        display("'adb start-server' succeeded."); //$NON-NLS-1$
-
-        return true;
-    }
-
-    /**
-     * Stops the adb host side server.
-     * @return true if success
-     */
-    public synchronized boolean stopAdb() {
-        if (mAdbOsLocation == null) {
-            display("Error: missing path to ADB."); //$NON-NLS-1$
-            return false;
-        }
-
-        Process proc;
-        int status = -1;
-
-        try {
-            String[] command = new String[2];
-            command[0] = mAdbOsLocation;
-            command[1] = "kill-server"; //$NON-NLS-1$
-            proc = Runtime.getRuntime().exec(command);
-            status = proc.waitFor();
-        }
-        catch (IOException ioe) {
-            // we'll return false;
-        }
-        catch (InterruptedException ie) {
-            // we'll return false;
-        }
-
-        if (status != 0) {
-            display("'adb kill-server' failed -- run manually if necessary."); //$NON-NLS-1$
-            return false;
-        }
-
-        display("'adb kill-server' succeeded."); //$NON-NLS-1$
-        return true;
-    }
-
-    /**
-     * Get the stderr/stdout outputs of a process and return when the process is done.
-     * Both <b>must</b> be read or the process will block on windows.
-     * @param process The process to get the ouput from
-     * @param errorOutput The array to store the stderr output. cannot be null.
-     * @param stdOutput The array to store the stdout output. cannot be null.
-     * @param waitforReaders if true, this will wait for the reader threads.
-     * @return the process return code.
-     * @throws InterruptedException
-     */
-    private int grabProcessOutput(final Process process, final ArrayList<String> errorOutput,
-            final ArrayList<String> stdOutput, boolean waitforReaders)
-            throws InterruptedException {
-        assert errorOutput != null;
-        assert stdOutput != null;
-        // read the lines as they come. if null is returned, it's
-        // because the process finished
-        Thread t1 = new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            display("ADB Error: %1$s", line);
-                            errorOutput.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        Thread t2 = new Thread("") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            display("ADB: %1$s", line);
-                            stdOutput.add(line);
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        };
-
-        t1.start();
-        t2.start();
-
-        // it looks like on windows process#waitFor() can return
-        // before the thread have filled the arrays, so we wait for both threads and the
-        // process itself.
-        if (waitforReaders) {
-            try {
-                t1.join();
-            } catch (InterruptedException e) {
-            }
-            try {
-                t2.join();
-            } catch (InterruptedException e) {
-            }
-        }
-
-        // get the return code from the process
-        return process.waitFor();
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ArchiveInfo.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ArchiveInfo.java
deleted file mode 100755
index 83dc8ca..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ArchiveInfo.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdklib.internal.repository.Archive;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Represents an archive that we want to install.
- * Note that the installer deals with archives whereas the user mostly sees packages
- * but as far as we are concerned for installation there's a 1-to-1 mapping.
- * <p/>
- * A new archive is always a remote archive that needs to be downloaded and then
- * installed. It can replace an existing local one. It can also depends on another
- * (new or local) archive, which means the dependent archive needs to be successfully
- * installed first. Finally this archive can also be a dependency for another one.
- *
- * @see ArchiveInfo#ArchiveInfo(Archive, Archive, ArchiveInfo)
- */
-class ArchiveInfo {
-
-    private final Archive mNewArchive;
-    private final Archive mReplaced;
-    private final ArchiveInfo mDependsOn;
-    private final ArrayList<ArchiveInfo> mDependencyFor = new ArrayList<ArchiveInfo>();
-    private boolean mAccepted;
-    private boolean mRejected;
-
-    /**
-     *
-     * @param newArchive A "new archive" to be installed. This is always an archive
-     *          that comes from a remote site. This can not be null.
-     * @param replaced An optional local archive that the new one will replace.
-     *          Can be null if this archive does not replace anything.
-     * @param dependsOn An optional new or local dependency, that is an archive that
-     *          <em>this</em> archive depends upon. In other words, we can only install
-     *          this archive if the dependency has been successfully installed. It also
-     *          means we need to install the dependency first.
-     */
-    public ArchiveInfo(Archive newArchive, Archive replaced, ArchiveInfo dependsOn) {
-        mNewArchive = newArchive;
-        mReplaced = replaced;
-        mDependsOn = dependsOn;
-    }
-
-    /**
-     * Returns the "new archive" to be installed.
-     * This is always an archive that comes from a remote site.
-     */
-    public Archive getNewArchive() {
-        return mNewArchive;
-    }
-
-    /**
-     * Returns an optional local archive that the new one will replace.
-     * Can be null if this archive does not replace anything.
-     */
-    public Archive getReplaced() {
-        return mReplaced;
-    }
-
-    /**
-     * Returns an optional new or local dependency, that is an archive that <em>this</em>
-     * archive depends upon. In other words, we can only install this archive if the
-     * dependency has been successfully installed. It also means we need to install the
-     * dependency first.
-     */
-    public ArchiveInfo getDependsOn() {
-        return mDependsOn;
-    }
-
-    /**
-     * Returns true if this new archive is a dependency for <em>another</em> one that we
-     * want to install.
-     */
-    public boolean isDependencyFor() {
-        return mDependencyFor.size() > 0;
-    }
-
-    /**
-     * Adds an {@link ArchiveInfo} for which <em>this</em> package is a dependency.
-     * This means the package added here depends on this package.
-     */
-    public void addDependencyFor(ArchiveInfo dependencyFor) {
-        if (!mDependencyFor.contains(dependencyFor)) {
-            mDependencyFor.add(dependencyFor);
-        }
-    }
-
-    public Collection<ArchiveInfo> getDependenciesFor() {
-        return mDependencyFor;
-    }
-
-    /**
-     * Sets whether this archive was accepted (either manually by the user or
-     * automatically if it doesn't have a license) for installation.
-     */
-    public void setAccepted(boolean accepted) {
-        mAccepted = accepted;
-    }
-
-    /**
-     * Returns whether this archive was accepted (either manually by the user or
-     * automatically if it doesn't have a license) for installation.
-     */
-    public boolean isAccepted() {
-        return mAccepted;
-    }
-
-    /**
-     * Sets whether this archive was rejected manually by the user.
-     * An archive can neither accepted nor rejected.
-     */
-    public void setRejected(boolean rejected) {
-        mRejected = rejected;
-    }
-
-    /**
-     * Returns whether this archive was rejected manually by the user.
-     * An archive can neither accepted nor rejected.
-     */
-    public boolean isRejected() {
-        return mRejected;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AvdManagerPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AvdManagerPage.java
deleted file mode 100755
index 6cd0996..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AvdManagerPage.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdkuilib.internal.widgets.AvdSelector;
-import com.android.sdkuilib.internal.widgets.AvdSelector.DisplayMode;
-import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-public class AvdManagerPage extends Composite implements ISdkListener {
-
-    private AvdSelector mAvdSelector;
-
-    private final UpdaterData mUpdaterData;
-
-    /**
-     * Create the composite.
-     * @param parent The parent of the composite.
-     * @param updaterData An instance of {@link UpdaterData}.
-     */
-    public AvdManagerPage(Composite parent, UpdaterData updaterData) {
-        super(parent, SWT.BORDER);
-
-        mUpdaterData = updaterData;
-        mUpdaterData.addListeners(this);
-
-        createContents(this);
-        postCreate();  //$hide$
-    }
-
-    private void createContents(Composite parent) {
-        parent.setLayout(new GridLayout(1, false));
-
-        Label label = new Label(parent, SWT.NONE);
-        label.setText("List of existing Android Virtual Devices:");
-
-        mAvdSelector = new AvdSelector(parent,
-                mUpdaterData.getOsSdkRoot(),
-                mUpdaterData.getAvdManager(),
-                DisplayMode.MANAGER);
-        mAvdSelector.setSettingsController(mUpdaterData.getSettingsController());
-    }
-
-    @Override
-    public void dispose() {
-        mUpdaterData.removeListener(this);
-        super.dispose();
-    }
-
-    @Override
-    protected void checkSubclass() {
-        // Disable the check that prevents subclassing of SWT components
-    }
-
-    // -- Start of internal part ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    /**
-     * Called by the constructor right after {@link #createContents(Composite)}.
-     */
-    private void postCreate() {
-        // nothing to be done for now.
-    }
-
-    public void onSdkChange() {
-        mAvdSelector.refresh(false /*reload*/);
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISettingsPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISettingsPage.java
deleted file mode 100755
index 739c479..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISettingsPage.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import java.net.URL;
-import java.util.Properties;
-
-/**
- * Interface that a settings page must implement.
- */
-public interface ISettingsPage {
-
-    /**
-     * Java system setting picked up by {@link URL} for http proxy port.
-     * Type: String.
-     */
-    public static final String KEY_HTTP_PROXY_PORT = "http.proxyPort";           //$NON-NLS-1$
-    /**
-     * Java system setting picked up by {@link URL} for http proxy host.
-     * Type: String.
-     */
-    public static final String KEY_HTTP_PROXY_HOST = "http.proxyHost";           //$NON-NLS-1$
-    /**
-     * Setting to force using http:// instead of https:// connections.
-     * Type: Boolean.
-     * Default: False.
-     */
-    public static final String KEY_FORCE_HTTP = "sdkman.force.http";             //$NON-NLS-1$
-    /**
-     * Setting to display only packages that are new or updates.
-     * Type: Boolean.
-     * Default: True.
-     */
-    public static final String KEY_SHOW_UPDATE_ONLY = "sdkman.show.update.only"; //$NON-NLS-1$
-    /**
-     * Setting to ask for permission before restarting ADB.
-     * Type: Boolean.
-     * Default: True.
-     */
-    public static final String KEY_ASK_ADB_RESTART = "sdkman.ask.adb.restart";   //$NON-NLS-1$
-    /**
-     * Setting to set the density of the monitor.
-     * Type: Integer.
-     * Default: -1
-     */
-    public static final String KEY_MONITOR_DENSITY = "sdkman.monitor.density"; //$NON-NLS-1$
-
-    /** Loads settings from the given {@link Properties} container and update the page UI. */
-    public abstract void loadSettings(Properties in_settings);
-
-    /** Called by the application to retrieve settings from the UI and store them in
-     * the given {@link Properties} container. */
-    public abstract void retrieveSettings(Properties out_settings);
-
-    /**
-     * Called by the application to give a callback that the page should invoke when
-     * settings have changed.
-     */
-    public abstract void setOnSettingsChanged(SettingsChangedCallback settingsChangedCallback);
-
-    /**
-     * Callback used to notify the application that settings have changed and need to be
-     * applied.
-     */
-    public interface SettingsChangedCallback {
-        /**
-         * Invoked by the settings page when settings have changed and need to be
-         * applied. The application will call {@link ISettingsPage#retrieveSettings(Properties)}
-         * and apply the new settings.
-         */
-        public abstract void onSettingsChanged(ISettingsPage page);
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java
deleted file mode 100755
index 833baac..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdklib.internal.repository.Archive;
-import com.android.sdklib.internal.repository.IDescription;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-
-/*
- * TODO list
- * - select => update desc, enable update + delete, enable home page if url
- * - home page callback
- * - update callback
- * - delete callback
- * - refresh callback
- */
-
-public class LocalPackagesPage extends Composite implements ISdkListener {
-
-    private final UpdaterData mUpdaterData;
-
-    private Label mSdkLocLabel;
-    private Text mSdkLocText;
-    private Button mSdkLocBrowse;
-    private TableViewer mTableViewerPackages;
-    private Table mTablePackages;
-    private TableColumn mColumnPackages;
-    private Group mDescriptionContainer;
-    private Composite mContainerButtons;
-    private Button mUpdateButton;
-    private Label mPlaceholder1;
-    private Button mDeleteButton;
-    private Label mPlaceholder2;
-    private Button mRefreshButton;
-    private Label mDescriptionLabel;
-
-
-    /**
-     * Create the composite.
-     * @param parent The parent of the composite.
-     * @param updaterData An instance of {@link UpdaterData}.
-     */
-    public LocalPackagesPage(Composite parent, UpdaterData updaterData) {
-        super(parent, SWT.BORDER);
-
-        mUpdaterData = updaterData;
-
-        createContents(this);
-        postCreate();  //$hide$
-    }
-
-    private void createContents(Composite parent) {
-        parent.setLayout(new GridLayout(3, false));
-
-        createSdkLocation(parent);
-
-        mTableViewerPackages = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION);
-        mTablePackages = mTableViewerPackages.getTable();
-        mTablePackages.setHeaderVisible(true);
-        mTablePackages.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
-        mTablePackages.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onTreeSelected(); //$hide$
-            }
-        });
-
-        mColumnPackages = new TableColumn(mTablePackages, SWT.NONE);
-        mColumnPackages.setWidth(377);
-        mColumnPackages.setText("Installed Packages");
-
-        mDescriptionContainer = new Group(parent, SWT.NONE);
-        mDescriptionContainer.setLayout(new GridLayout(1, false));
-        mDescriptionContainer.setText("Description");
-        mDescriptionContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
-
-        mDescriptionLabel = new Label(mDescriptionContainer, SWT.NONE);
-        mDescriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1));
-        mDescriptionLabel.setText("Line1\nLine2\nLine3");
-
-        mContainerButtons = new Composite(parent, SWT.NONE);
-        mContainerButtons.setLayout(new GridLayout(5, false));
-        mContainerButtons.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
-
-        mUpdateButton = new Button(mContainerButtons, SWT.NONE);
-        mUpdateButton.setText("Update All...");
-        mUpdateButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onUpdateSelected();  //$hide$ (hide from SWT designer)
-            }
-        });
-
-        mPlaceholder1 = new Label(mContainerButtons, SWT.NONE);
-        mPlaceholder1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
-
-        mDeleteButton = new Button(mContainerButtons, SWT.NONE);
-        mDeleteButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
-        mDeleteButton.setText("Delete...");
-        mDeleteButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onDeleteSelected();  //$hide$ (hide from SWT designer)
-            }
-        });
-
-        mPlaceholder2 = new Label(mContainerButtons, SWT.NONE);
-        mPlaceholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
-
-        mRefreshButton = new Button(mContainerButtons, SWT.NONE);
-        mRefreshButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-        mRefreshButton.setText("Refresh");
-        mRefreshButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onRefreshSelected();  //$hide$ (hide from SWT designer)
-            }
-        });
-    }
-
-    private void createSdkLocation(Composite parent) {
-        mSdkLocLabel = new Label(parent, SWT.NONE);
-        mSdkLocLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-        mSdkLocLabel.setText("SDK Location:");
-
-        // If the sdk path is not user-customizable, do not create
-        // the browse button and use horizSpan=2 on the text field.
-
-        mSdkLocText = new Text(parent, SWT.BORDER);
-        mSdkLocText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-
-        if (mUpdaterData.canUserChangeSdkRoot()) {
-            mSdkLocBrowse = new Button(parent, SWT.NONE);
-            mSdkLocBrowse.setText("Browse...");
-        } else {
-            mSdkLocText.setEditable(false);
-            ((GridData)mSdkLocText.getLayoutData()).horizontalSpan++;
-        }
-
-        if (mUpdaterData.getOsSdkRoot() != null) {
-            mSdkLocText.setText(mUpdaterData.getOsSdkRoot());
-        }
-    }
-
-    @Override
-    public void dispose() {
-        mUpdaterData.removeListener(this);
-        super.dispose();
-    }
-
-    @Override
-    protected void checkSubclass() {
-        // Disable the check that prevents subclassing of SWT components
-    }
-
-    // -- Start of internal part ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    /**
-     * Called by the constructor right after {@link #createContents(Composite)}.
-     */
-    private void postCreate() {
-        mUpdaterData.addListeners(this);
-        adjustColumnsWidth();
-        updateButtonsState();
-    }
-
-    /**
-     * Adds a listener to adjust the columns width when the parent is resized.
-     * <p/>
-     * If we need something more fancy, we might want to use this:
-     * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
-     */
-    private void adjustColumnsWidth() {
-        // Add a listener to resize the column to the full width of the table
-        ControlAdapter resizer = new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Rectangle r = mTablePackages.getClientArea();
-                mColumnPackages.setWidth(r.width);
-            }
-        };
-        mTablePackages.addControlListener(resizer);
-        resizer.controlResized(null);
-    }
-
-    /**
-     * Enable or disable buttons depending on list content and selection
-     */
-    private void updateButtonsState() {
-        ISelection sel = mTableViewerPackages.getSelection();
-        boolean hasSelection = sel != null && !sel.isEmpty();
-
-        mUpdateButton.setEnabled(mTablePackages.getItemCount() > 0);
-        mDeleteButton.setEnabled(hasSelection);
-        mRefreshButton.setEnabled(true);
-    }
-
-    /**
-     * Called when an item in the package table viewer is selected.
-     * If the items is an {@link IDescription} (as it should), this will display its long
-     * description in the description area. Otherwise when the item is not of the expected
-     * type or there is no selection, it empties the description area.
-     */
-    private void onTreeSelected() {
-        updateButtonsState();
-
-        ISelection sel = mTableViewerPackages.getSelection();
-        if (sel instanceof IStructuredSelection) {
-            Object elem = ((IStructuredSelection) sel).getFirstElement();
-            if (elem instanceof IDescription) {
-                mDescriptionLabel.setText(((IDescription) elem).getLongDescription());
-                mDescriptionContainer.layout(true);
-                return;
-            }
-        }
-        mDescriptionLabel.setText("");  //$NON-NLS1-$
-    }
-
-    private void onUpdateSelected() {
-        mUpdaterData.updateOrInstallAll(null /*selectedArchives*/);
-    }
-
-    private void onDeleteSelected() {
-        ISelection sel = mTableViewerPackages.getSelection();
-        if (sel instanceof IStructuredSelection) {
-            Object elem = ((IStructuredSelection) sel).getFirstElement();
-            if (elem instanceof Package) {
-
-                String title = "Delete SDK Package";
-                String error = null;
-
-                Package p = (Package) elem;
-                Archive[] archives = p.getArchives();
-                if (archives.length == 1 && archives[0] != null && archives[0].isLocal()) {
-                    Archive archive = archives[0];
-                    String osPath = archive.getLocalOsPath();
-
-                    File dir = new File(osPath);
-                    if (dir.isDirectory()) {
-                        String msg = String.format("Are you sure you want to delete '%1$s' at '%2$s'? This cannot be undone.",
-                                p.getShortDescription(), osPath);
-
-                        if (MessageDialog.openQuestion(getShell(), title, msg)) {
-                            archive.deleteLocal();
-
-                            // refresh list
-                            onRefreshSelected();
-                        }
-                    } else {
-                        error = "Directory not found for this package";
-                    }
-                } else {
-                    error = "No local archive found for this package";
-                }
-
-                if (error != null) {
-                    MessageDialog.openError(getShell(), title, error);
-                }
-
-                return;
-            }
-        }
-    }
-
-    private void onRefreshSelected() {
-        mUpdaterData.reloadSdk();
-        updateButtonsState();
-    }
-
-    public void onSdkChange() {
-        LocalSdkAdapter localSdkAdapter = mUpdaterData.getLocalSdkAdapter();
-        mTableViewerPackages.setLabelProvider(  localSdkAdapter.getLabelProvider());
-        mTableViewerPackages.setContentProvider(localSdkAdapter.getContentProvider());
-        mTableViewerPackages.setInput(localSdkAdapter);
-        onTreeSelected();
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java
deleted file mode 100755
index c124b47..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdklib.internal.repository.IDescription;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdklib.internal.repository.RepoSource;
-import com.android.sdkuilib.internal.repository.icons.ImageFactory;
-
-import org.eclipse.jface.viewers.IContentProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * Table adapters to use the local SDK list.
- */
-class LocalSdkAdapter  {
-
-    private final UpdaterData mUpdaterData;
-
-    public LocalSdkAdapter(UpdaterData updaterData) {
-        mUpdaterData = updaterData;
-    }
-
-    public ILabelProvider getLabelProvider() {
-        return new ViewerLabelProvider();
-    }
-
-
-    public IContentProvider getContentProvider() {
-        return new TableContentProvider();
-    }
-
-    // ------------
-
-    public class ViewerLabelProvider extends LabelProvider {
-        /** Returns an image appropriate for this element. */
-        @Override
-        public Image getImage(Object element) {
-            ImageFactory imgFactory = mUpdaterData.getImageFactory();
-
-            if (imgFactory != null) {
-                return imgFactory.getImageForObject(element);
-            }
-
-            return super.getImage(element);
-        }
-
-        /** Returns the toString of the element. */
-        @Override
-        public String getText(Object element) {
-            if (element instanceof IDescription) {
-                return ((IDescription) element).getShortDescription();
-            }
-            return super.getText(element);
-        }
-    }
-
-    // ------------
-
-    private class TableContentProvider implements IStructuredContentProvider {
-
-        // Called when the viewer is disposed
-        public void dispose() {
-            // pass
-        }
-
-        // Called when the input is set or changed on the provider
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            assert newInput == LocalSdkAdapter.this;
-        }
-
-        /**
-         * Called to collect the root elements for the given input.
-         * The input here is a {@link LocalSdkAdapter} object, this returns an array
-         * of {@link RepoSource}.
-         */
-        public Object[] getElements(Object inputElement) {
-            if (inputElement == LocalSdkAdapter.this) {
-                Package[] packages = mUpdaterData.getInstalledPackage();
-
-                if (packages != null) {
-                    return packages;
-                }
-            }
-
-            return new Object[0];
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java
deleted file mode 100755
index 8757e66..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-
-import com.android.sdklib.internal.repository.Archive;
-import com.android.sdklib.internal.repository.IDescription;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdklib.internal.repository.RepoSource;
-import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener;
-
-import org.eclipse.jface.dialogs.IInputValidator;
-import org.eclipse.jface.dialogs.InputDialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.CheckStateChangedEvent;
-import org.eclipse.jface.viewers.CheckboxTreeViewer;
-import org.eclipse.jface.viewers.ICheckStateListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.ITreeSelection;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-
-import java.util.ArrayList;
-
-
-public class RemotePackagesPage extends Composite implements ISdkListener {
-
-    private final UpdaterData mUpdaterData;
-
-    private CheckboxTreeViewer mTreeViewerSources;
-    private Tree mTreeSources;
-    private TreeColumn mColumnSource;
-    private Button mUpdateOnlyCheckBox;
-    private Group mDescriptionContainer;
-    private Button mAddSiteButton;
-    private Button mDeleteSiteButton;
-    private Button mRefreshButton;
-    private Button mInstallSelectedButton;
-    private Label mDescriptionLabel;
-
-
-
-    /**
-     * Create the composite.
-     * @param parent The parent of the composite.
-     * @param updaterData An instance of {@link UpdaterData}.
-     */
-    RemotePackagesPage(Composite parent, UpdaterData updaterData) {
-        super(parent, SWT.BORDER);
-
-        mUpdaterData = updaterData;
-
-        createContents(this);
-        postCreate();  //$hide$
-    }
-
-    private void createContents(Composite parent) {
-        parent.setLayout(new GridLayout(5, false));
-
-        mTreeViewerSources = new CheckboxTreeViewer(parent, SWT.BORDER);
-        mTreeViewerSources.addCheckStateListener(new ICheckStateListener() {
-            public void checkStateChanged(CheckStateChangedEvent event) {
-                onTreeCheckStateChanged(event); //$hide$
-            }
-        });
-        mTreeSources = mTreeViewerSources.getTree();
-        mTreeSources.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onTreeSelected(); //$hide$
-            }
-        });
-        mTreeSources.setHeaderVisible(true);
-        mTreeSources.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
-
-        mColumnSource = new TreeColumn(mTreeSources, SWT.NONE);
-        mColumnSource.setWidth(289);
-        mColumnSource.setText("Sites, Packages and Archives");
-
-        mDescriptionContainer = new Group(parent, SWT.NONE);
-        mDescriptionContainer.setLayout(new GridLayout(1, false));
-        mDescriptionContainer.setText("Description");
-        mDescriptionContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 5, 1));
-
-        mDescriptionLabel = new Label(mDescriptionContainer, SWT.NONE);
-        mDescriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
-        mDescriptionLabel.setText("Line1\nLine2\nLine3");
-
-        mAddSiteButton = new Button(parent, SWT.NONE);
-        mAddSiteButton.setText("Add Site...");
-        mAddSiteButton.setToolTipText("Allows you to enter a new user external site. " +
-                "Such site can only contribute add-ons and extra packages.");
-        mAddSiteButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onAddSiteSelected(); //$hide$
-            }
-        });
-
-        mDeleteSiteButton = new Button(parent, SWT.NONE);
-        mDeleteSiteButton.setText("Delete Site...");
-        mDeleteSiteButton.setToolTipText("Allows you to remove an external site. " +
-                "Built-in sites cannot be removed.");
-        mDeleteSiteButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onRemoveSiteSelected(); //$hide$
-            }
-        });
-
-        mUpdateOnlyCheckBox = new Button(parent, SWT.CHECK);
-        mUpdateOnlyCheckBox.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
-        mUpdateOnlyCheckBox.setText("Display updates only");
-        mUpdateOnlyCheckBox.setToolTipText("When selected, only compatible update packages are shown in the list above.");
-        mUpdateOnlyCheckBox.setSelection(mUpdaterData.getSettingsController().getShowUpdateOnly());
-        mUpdateOnlyCheckBox.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                onShowUpdateOnly(); //$hide$
-            }
-        });
-
-        mRefreshButton = new Button(parent, SWT.NONE);
-        mRefreshButton.setText("Refresh");
-        mRefreshButton.setToolTipText("Refreshes the list of packages from open sites.");
-        mRefreshButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onRefreshSelected(); //$hide$
-            }
-        });
-
-        mInstallSelectedButton = new Button(parent, SWT.NONE);
-        mInstallSelectedButton.setText("Install Selected");
-        mInstallSelectedButton.setToolTipText("Allows you to review all selected packages " +
-                "and install them.");
-        mInstallSelectedButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onInstallSelectedArchives();  //$hide$
-            }
-        });
-    }
-
-    @Override
-    public void dispose() {
-        mUpdaterData.removeListener(this);
-        super.dispose();
-    }
-
-    @Override
-    protected void checkSubclass() {
-        // Disable the check that prevents subclassing of SWT components
-    }
-
-    // -- Start of internal part ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    /**
-     * Called by the constructor right after {@link #createContents(Composite)}.
-     */
-    private void postCreate() {
-        mUpdaterData.addListeners(this);
-        adjustColumnsWidth();
-        updateButtonsState();
-    }
-
-    /**
-     * Adds a listener to adjust the columns width when the parent is resized.
-     * <p/>
-     * If we need something more fancy, we might want to use this:
-     * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
-     */
-    private void adjustColumnsWidth() {
-        // Add a listener to resize the column to the full width of the table
-        ControlAdapter resizer = new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Rectangle r = mTreeSources.getClientArea();
-                mColumnSource.setWidth(r.width);
-            }
-        };
-
-        mTreeSources.addControlListener(resizer);
-        resizer.controlResized(null);
-    }
-
-    /**
-     * Called when an item in the package table viewer is selected.
-     * If the items is an {@link IDescription} (as it should), this will display its long
-     * description in the description area. Otherwise when the item is not of the expected
-     * type or there is no selection, it empties the description area.
-     */
-    private void onTreeSelected() {
-        updateButtonsState();
-
-        ISelection sel = mTreeViewerSources.getSelection();
-        if (sel instanceof ITreeSelection) {
-            Object elem = ((ITreeSelection) sel).getFirstElement();
-            if (elem instanceof IDescription) {
-                mDescriptionLabel.setText(((IDescription) elem).getLongDescription());
-                mDescriptionContainer.layout(true);
-                return;
-            }
-        }
-        mDescriptionLabel.setText("");  //$NON-NLS1-$
-    }
-
-    /**
-     * Handle checking and unchecking of the tree items.
-     *
-     * When unchecking, all sub-tree items checkboxes are cleared too.
-     * When checking a source, all of its packages are checked too.
-     * When checking a package, only its compatible archives are checked.
-     */
-    private void onTreeCheckStateChanged(CheckStateChangedEvent event) {
-        updateButtonsState();
-
-        boolean b = event.getChecked();
-        Object elem = event.getElement(); // Will be Archive or Package or RepoSource
-
-        assert event.getSource() == mTreeViewerSources;
-
-        // when deselecting, we just deselect all children too
-        if (b == false) {
-            mTreeViewerSources.setSubtreeChecked(elem, b);
-            return;
-        }
-
-        ITreeContentProvider provider =
-            (ITreeContentProvider) mTreeViewerSources.getContentProvider();
-
-        // When selecting, we want to only select compatible archives.
-        if (elem instanceof RepoSource) {
-            mTreeViewerSources.setExpandedState(elem, true);
-            for (Object pkg : provider.getChildren(elem)) {
-                mTreeViewerSources.setChecked(pkg, true);
-                selectCompatibleArchives(pkg, provider);
-            }
-        } else if (elem instanceof Package) {
-            selectCompatibleArchives(elem, provider);
-        }
-    }
-
-    private void selectCompatibleArchives(Object pkg, ITreeContentProvider provider) {
-        for (Object archive : provider.getChildren(pkg)) {
-            if (archive instanceof Archive) {
-                mTreeViewerSources.setChecked(archive, ((Archive) archive).isCompatible());
-            }
-        }
-    }
-
-    private void onShowUpdateOnly() {
-        SettingsController controller = mUpdaterData.getSettingsController();
-        controller.setShowUpdateOnly(mUpdateOnlyCheckBox.getSelection());
-        controller.saveSettings();
-        mTreeViewerSources.refresh();
-    }
-
-    private void onInstallSelectedArchives() {
-        ArrayList<Archive> archives = new ArrayList<Archive>();
-        for (Object element : mTreeViewerSources.getCheckedElements()) {
-            if (element instanceof Archive) {
-                archives.add((Archive) element);
-            }
-        }
-
-        if (mUpdaterData != null) {
-            mUpdaterData.updateOrInstallAll(archives);
-        }
-    }
-
-    private void onAddSiteSelected() {
-
-        final RepoSource[] knowSources = mUpdaterData.getSources().getSources();
-        String title = "Add Site URL";
-        String msg = "Please enter the URL of the repository.xml for the new site:";
-
-        InputDialog dlg = new InputDialog(getShell(), title, msg, null, new IInputValidator() {
-            public String isValid(String newText) {
-
-                if (newText == null || newText.length() == 0) {
-                    return "Please enter an URL.";
-                }
-
-                // A URL should have one of the following prefixes
-                if (!newText.startsWith("file://") &&
-                        !newText.startsWith("ftp://") &&
-                        !newText.startsWith("http://") &&
-                        !newText.startsWith("https://")) {
-                    return "The URL must start by one of file://, ftp://, http:// or https://";
-                }
-
-                // Reject URLs that are already in the source list
-                for (RepoSource s : knowSources) {
-                    if (newText.equals(s.getUrl())) {
-                        return "This site is already listed.";
-                    }
-                }
-
-                return null;
-            }
-        });
-
-        if (dlg.open() == Window.OK) {
-            String url = dlg.getValue();
-            mUpdaterData.getSources().add(new RepoSource(url, true /*userSource*/));
-            onRefreshSelected();
-        }
-    }
-
-    private void onRemoveSiteSelected() {
-        boolean changed = false;
-
-        ISelection sel = mTreeViewerSources.getSelection();
-        if (mUpdaterData != null && sel instanceof ITreeSelection) {
-            for (Object c : ((ITreeSelection) sel).toList()) {
-                if (c instanceof RepoSource && ((RepoSource) c).isUserSource()) {
-                    RepoSource source = (RepoSource) c;
-
-                    String title = "Delete Site?";
-
-                    String msg = String.format("Are you sure you want to delete the site '%1$s'?",
-                            source.getUrl());
-
-                    if (MessageDialog.openQuestion(getShell(), title, msg)) {
-                        mUpdaterData.getSources().remove(source);
-                        changed = true;
-                    }
-                }
-            }
-        }
-
-        if (changed) {
-            onRefreshSelected();
-        }
-    }
-
-    private void onRefreshSelected() {
-        if (mUpdaterData != null) {
-            mUpdaterData.refreshSources(false /*forceFetching*/);
-        }
-        mTreeViewerSources.refresh();
-        updateButtonsState();
-    }
-
-    public void onSdkChange() {
-        RepoSourcesAdapter sources = mUpdaterData.getSourcesAdapter();
-        mTreeViewerSources.setContentProvider(sources.getContentProvider());
-        mTreeViewerSources.setLabelProvider(  sources.getLabelProvider());
-        mTreeViewerSources.setInput(sources);
-        onTreeSelected();
-    }
-
-    private void updateButtonsState() {
-        // We install archives, so there should be at least one checked archive.
-        // Having sites or packages checked does not count.
-        boolean hasCheckedArchive = false;
-        Object[] checked = mTreeViewerSources.getCheckedElements();
-        if (checked != null) {
-            for (Object c : checked) {
-                if (c instanceof Archive) {
-                    hasCheckedArchive = true;
-                    break;
-                }
-            }
-        }
-
-        // Is there a selected site Source?
-        boolean hasSelectedUserSource = false;
-        ISelection sel = mTreeViewerSources.getSelection();
-        if (sel instanceof ITreeSelection) {
-            for (Object c : ((ITreeSelection) sel).toList()) {
-                if (c instanceof RepoSource &&
-                        ((RepoSource) c).isUserSource()) {
-                    hasSelectedUserSource = true;
-                    break;
-                }
-            }
-        }
-
-        mAddSiteButton.setEnabled(true);
-        mDeleteSiteButton.setEnabled(hasSelectedUserSource);
-        mRefreshButton.setEnabled(true);
-        mInstallSelectedButton.setEnabled(hasCheckedArchive);
-
-        // set value on the show only update checkbox
-        mUpdateOnlyCheckBox.setSelection(mUpdaterData.getSettingsController().getShowUpdateOnly());
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java
deleted file mode 100755
index fafa9c1..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdklib.internal.repository.Archive;
-import com.android.sdklib.internal.repository.IDescription;
-import com.android.sdklib.internal.repository.ITask;
-import com.android.sdklib.internal.repository.ITaskMonitor;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdklib.internal.repository.RepoSource;
-import com.android.sdklib.internal.repository.Package.UpdateInfo;
-import com.android.sdkuilib.internal.repository.icons.ImageFactory;
-
-import org.eclipse.jface.viewers.IContentProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Image;
-
-import java.util.ArrayList;
-
-/**
- * A list of sdk-repository sources.
- *
- * This implementation is UI dependent.
- */
-public class RepoSourcesAdapter {
-
-    private final UpdaterData mUpdaterData;
-
-    /**
-     * A dummy RepoSource entry returned for sources which had load errors.
-     * It displays a summary of the error as its short description or
-     * it displays the source's long description.
-     */
-    public static class RepoSourceError implements IDescription {
-
-        private final RepoSource mSource;
-
-        public RepoSourceError(RepoSource source) {
-            mSource = source;
-        }
-
-        public String getLongDescription() {
-            return mSource.getLongDescription();
-        }
-
-        public String getShortDescription() {
-            return mSource.getFetchError();
-        }
-    }
-
-    /**
-     * A dummy RepoSource entry returned for sources with no packages.
-     * We need that to force the SWT tree to display an open/close triangle
-     * even for empty sources.
-     */
-    public static class RepoSourceEmpty implements IDescription {
-
-        private final RepoSource mSource;
-        private final boolean mEmptyBecauseOfUpdateOnly;
-
-        public RepoSourceEmpty(RepoSource source, boolean emptyBecauseOfUpdateOnly) {
-            mSource = source;
-            mEmptyBecauseOfUpdateOnly = emptyBecauseOfUpdateOnly;
-        }
-
-        public String getLongDescription() {
-            return mSource.getLongDescription();
-        }
-
-        public String getShortDescription() {
-            if (mEmptyBecauseOfUpdateOnly) {
-                return "Some packages were found but are not compatible updates.";
-            } else {
-                return "No packages found";
-            }
-        }
-    }
-
-    public RepoSourcesAdapter(UpdaterData updaterData) {
-        mUpdaterData = updaterData;
-    }
-
-    public ILabelProvider getLabelProvider() {
-        return new ViewerLabelProvider();
-    }
-
-
-    public IContentProvider getContentProvider() {
-        return new TreeContentProvider();
-    }
-
-    // ------------
-
-    private class ViewerLabelProvider extends LabelProvider {
-
-        /** Returns an image appropriate for this element. */
-        @Override
-        public Image getImage(Object element) {
-
-            ImageFactory imgFactory = mUpdaterData.getImageFactory();
-
-            if (imgFactory != null) {
-                return imgFactory.getImageForObject(element);
-            }
-
-            return super.getImage(element);
-        }
-
-        /** Returns the toString of the element. */
-        @Override
-        public String getText(Object element) {
-            if (element instanceof IDescription) {
-                return ((IDescription) element).getShortDescription();
-            }
-            return super.getText(element);
-        }
-    }
-
-    // ------------
-
-    private class TreeContentProvider implements ITreeContentProvider {
-
-        // Called when the viewer is disposed
-        public void dispose() {
-            // pass
-        }
-
-        // Called when the input is set or changed on the provider
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-            assert newInput == RepoSourcesAdapter.this;
-        }
-
-        /**
-         * Called to collect the root elements for the given input.
-         * The input here is a {@link RepoSourcesAdapter} object, this returns an array
-         * of {@link RepoSource}.
-         */
-        public Object[] getElements(Object inputElement) {
-            return getChildren(inputElement);
-        }
-
-        /**
-         * Get the children of the given parent. This is requested on-demand as
-         * nodes are expanded.
-         *
-         * For a {@link RepoSourcesAdapter} object, returns an array of {@link RepoSource}s.
-         * For a {@link RepoSource}, returns an array of {@link Package}s.
-         * For a {@link Package}, returns an array of {@link Archive}s.
-         */
-        public Object[] getChildren(Object parentElement) {
-            if (parentElement == RepoSourcesAdapter.this) {
-                return mUpdaterData.getSources().getSources();
-
-            } else if (parentElement instanceof RepoSource) {
-                return getRepoSourceChildren((RepoSource) parentElement);
-
-            } else if (parentElement instanceof Package) {
-                return getPackageChildren((Package) parentElement);
-            }
-
-            return new Object[0];
-        }
-
-        /**
-         * Returns the list of packages for this repo source, eventually filtered to display
-         * only update packages. If the list is empty, returns a specific empty node. If there's
-         * an error, returns a specific error node.
-         */
-        private Object[] getRepoSourceChildren(final RepoSource source) {
-            Package[] packages = source.getPackages();
-
-            if (packages == null && source.getFetchError() == null) {
-                final boolean forceHttp = mUpdaterData.getSettingsController().getForceHttp();
-
-                mUpdaterData.getTaskFactory().start("Loading Source", new ITask() {
-                    public void run(ITaskMonitor monitor) {
-                        source.load(monitor, forceHttp);
-                    }
-                });
-
-                packages = source.getPackages();
-            }
-
-            boolean wasEmptyBeforeFilter = (packages == null || packages.length == 0);
-
-            // filter out only the packages that are new/upgrade.
-            if (packages != null && mUpdaterData.getSettingsController().getShowUpdateOnly()) {
-                packages = filteredPackages(packages);
-            }
-            if (packages != null && packages.length == 0) {
-                packages = null;
-            }
-
-            if (packages == null && source.getFetchError() != null) {
-                // Return a dummy entry to display the fetch error
-                return new Object[] { new RepoSourceError(source) };
-            }
-
-            // Either return a non-null package list or create a new empty node
-            if (packages != null) {
-                return packages;
-            } else {
-                return new Object[] { new RepoSourceEmpty(source, !wasEmptyBeforeFilter) } ;
-            }
-        }
-
-        /**
-         * Returns the list of archives for the given package, eventually filtering it
-         * to only show the compatible archives.
-         */
-        private Object[] getPackageChildren(Package pkg) {
-            Archive[] archives = pkg.getArchives();
-            if (mUpdaterData.getSettingsController().getShowUpdateOnly()) {
-                for (Archive archive : archives) {
-                    // if we only want the compatible archives, then we just take the first
-                    // one. it's unlikely there are 2 compatible archives for the same
-                    // package
-                    if (archive.isCompatible()) {
-                        return new Object[] { archive };
-                    }
-                }
-            }
-
-            return archives;
-        }
-
-        /**
-         * Returns the parent of a given element.
-         * The input {@link RepoSourcesAdapter} is the parent of all {@link RepoSource} elements.
-         */
-        public Object getParent(Object element) {
-
-            if (element instanceof RepoSource) {
-                return RepoSourcesAdapter.this;
-
-            } else if (element instanceof Package) {
-                return ((Package) element).getParentSource();
-
-            } else if (element instanceof Archive) {
-                return ((Archive) element).getParentPackage();
-            }
-            return null;
-        }
-
-        /**
-         * Returns true if a given element has children, which is used to display a
-         * "+/expand" box next to the tree node.
-         * All {@link RepoSource} and {@link Package} are expandable, whether they actually
-         * have any children or not.
-         */
-        public boolean hasChildren(Object element) {
-            return element instanceof RepoSource || element instanceof Package;
-        }
-    }
-
-    /**
-     * Filters out a list of remote packages to only keep the ones that are either new or
-     * updates of existing package.
-     * @param remotePackages the list of packages to filter.
-     * @return a non null (but maybe empty) list of new or update packages.
-     */
-    private Package[] filteredPackages(Package[] remotePackages) {
-        // get the installed packages
-        Package[] installedPackages = mUpdaterData.getInstalledPackage();
-
-        ArrayList<Package> filteredList = new ArrayList<Package>();
-
-        // for each remote packages, we look for an existing version.
-        // If no existing version -> add to the list
-        // if existing version but with older revision -> add it to the list
-        for (Package remotePkg : remotePackages) {
-            boolean newPkg = true;
-
-            // For all potential packages, we also make sure that there's an archive for the current
-            // platform, or we simply skip them.
-            if (remotePkg.hasCompatibleArchive()) {
-                for (Package installedPkg : installedPackages) {
-                    UpdateInfo info = installedPkg.canBeUpdatedBy(remotePkg);
-                    if (info == UpdateInfo.UPDATE) {
-                        filteredList.add(remotePkg);
-                        newPkg = false;
-                        break; // there shouldn't be 2 revisions of the same package
-                    } else if (info != UpdateInfo.INCOMPATIBLE) {
-                        newPkg = false;
-                        break; // there shouldn't be 2 revisions of the same package
-                    }
-                }
-
-                // if we have not found the same package, then we add it (it's a new package)
-                if (newPkg) {
-                    filteredList.add(remotePkg);
-                }
-            }
-        }
-
-        return filteredList.toArray(new Package[filteredList.size()]);
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsController.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsController.java
deleted file mode 100755
index 7c793e4..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsController.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.ISdkLog;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Properties;
-
-/**
- * Controller class to get settings values. Settings are kept in-memory.
- * Users of this class must first load the settings before changing them and save
- * them when modified.
- * <p/>
- * Settings are enumerated by constants in {@link ISettingsPage}.
- */
-public class SettingsController {
-
-    private static final String SETTINGS_FILENAME = "androidtool.cfg"; //$NON-NLS-1$
-
-    private final Properties mProperties = new Properties();
-
-    private ISettingsPage mSettingsPage;
-
-    private final UpdaterData mUpdaterData;
-
-    public SettingsController(UpdaterData updaterData) {
-        mUpdaterData = updaterData;
-    }
-
-    //--- Access to settings ------------
-
-    /**
-     * Returns the value of the {@link ISettingsPage#KEY_FORCE_HTTP} setting.
-     * @see ISettingsPage#KEY_FORCE_HTTP
-     */
-    public boolean getForceHttp() {
-        return Boolean.parseBoolean(mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP));
-    }
-
-    /**
-     * Returns the value of the {@link ISettingsPage#KEY_ASK_ADB_RESTART} setting.
-     * @see ISettingsPage#KEY_ASK_ADB_RESTART
-     */
-    public boolean getAskBeforeAdbRestart() {
-        String value = mProperties.getProperty(ISettingsPage.KEY_ASK_ADB_RESTART);
-        if (value == null) {
-            return true;
-        }
-        return Boolean.parseBoolean(value);
-    }
-
-    /**
-     * Returns the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting.
-     * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY
-     */
-    public boolean getShowUpdateOnly() {
-        String value = mProperties.getProperty(ISettingsPage.KEY_SHOW_UPDATE_ONLY);
-        if (value == null) {
-            return true;
-        }
-        return Boolean.parseBoolean(value);
-    }
-
-    /**
-     * Sets the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting.
-     * @param enabled True if only compatible update items should be shown.
-     * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY
-     */
-    public void setShowUpdateOnly(boolean enabled) {
-        setSetting(ISettingsPage.KEY_SHOW_UPDATE_ONLY, enabled);
-    }
-
-    /**
-     * Returns the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting
-     * @see ISettingsPage#KEY_MONITOR_DENSITY
-     */
-    public int getMonitorDensity() {
-        String value = mProperties.getProperty(ISettingsPage.KEY_MONITOR_DENSITY, null);
-        if (value == null) {
-            return -1;
-        }
-
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            return -1;
-        }
-    }
-
-    /**
-     * Sets the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting.
-     * @param density the density of the monitor
-     * @see ISettingsPage#KEY_MONITOR_DENSITY
-     */
-    public void setMonitorDensity(int density) {
-        mProperties.setProperty(ISettingsPage.KEY_MONITOR_DENSITY, Integer.toString(density));
-    }
-
-    /**
-     * Internal helper to set a boolean setting.
-     */
-    private void setSetting(String key, boolean value) {
-        mProperties.setProperty(key, Boolean.toString(value));
-    }
-
-    //--- Controller methods -------------
-
-    /**
-     * Associate the given {@link ISettingsPage} with this {@link SettingsController}.
-     *
-     * This loads the current properties into the setting page UI.
-     * It then associates the SettingsChanged callback with this controller.
-     */
-    public void setSettingsPage(ISettingsPage settingsPage) {
-
-        mSettingsPage = settingsPage;
-        mSettingsPage.loadSettings(mProperties);
-
-        settingsPage.setOnSettingsChanged(new ISettingsPage.SettingsChangedCallback() {
-            public void onSettingsChanged(ISettingsPage page) {
-                SettingsController.this.onSettingsChanged();
-            }
-        });
-    }
-
-    /**
-     * Load settings from the settings file.
-     */
-    public void loadSettings() {
-        FileInputStream fis = null;
-        String path = null;
-        try {
-            String folder = AndroidLocation.getFolder();
-            File f = new File(folder, SETTINGS_FILENAME);
-            path = f.getPath();
-            if (f.exists()) {
-                fis = new FileInputStream(f);
-
-                mProperties.load(fis);
-
-                // Properly reformat some settings to enforce their default value when missing.
-                setShowUpdateOnly(getShowUpdateOnly());
-                setSetting(ISettingsPage.KEY_ASK_ADB_RESTART, getAskBeforeAdbRestart());
-            }
-
-        } catch (Exception e) {
-            ISdkLog log = mUpdaterData.getSdkLog();
-            if (log != null) {
-                log.error(e, "Failed to load settings from '%1$s'", path);
-            }
-        } finally {
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-    }
-
-    /**
-     * Saves settings to the settings file.
-     */
-    public void saveSettings() {
-
-        FileOutputStream fos = null;
-        String path = null;
-        try {
-            String folder = AndroidLocation.getFolder();
-            File f = new File(folder, SETTINGS_FILENAME);
-            path = f.getPath();
-
-            fos = new FileOutputStream(f);
-
-            mProperties.store( fos, "## Settings for Android Tool");  //$NON-NLS-1$
-
-        } catch (Exception e) {
-            ISdkLog log = mUpdaterData.getSdkLog();
-
-            if (log != null) {
-                log.error(e, "Failed to save settings at '%1$s'", path);
-            }
-
-            // This is important enough that we want to really nag the user about it
-            String reason = null;
-
-            if (e instanceof FileNotFoundException) {
-                reason = "File not found";
-            } else if (e instanceof AndroidLocationException) {
-                reason = ".android folder not found, please define ANDROID_SDK_HOME";
-            } else if (e.getMessage() != null) {
-                reason = String.format("%1$s: %2$s", e.getClass().getSimpleName(), e.getMessage());
-            } else {
-                reason = e.getClass().getName();
-            }
-
-            MessageDialog.openInformation(mUpdaterData.getWindowShell(),
-                    "SDK Manager Settings",
-                    String.format(
-                        "The Android SDK and AVD Manager failed to save its settings (%1$s) at %2$s",
-                        reason, path));
-
-        } finally {
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-    }
-
-    /**
-     * When settings have changed: retrieve the new settings, apply them and save them.
-     *
-     * This updates Java system properties for the HTTP proxy.
-     */
-    private void onSettingsChanged() {
-        if (mSettingsPage == null) {
-            return;
-        }
-
-        mSettingsPage.retrieveSettings(mProperties);
-        applySettings();
-        saveSettings();
-
-        // In case the HTTP/HTTPS setting change, force sources to be reloaded
-        // (this only refreshes sources that the user has already tried to open.)
-        mUpdaterData.refreshSources(false /*forceFetching*/);
-    }
-
-    /**
-     * Applies the current settings.
-     */
-    public void applySettings() {
-        Properties props = System.getProperties();
-        props.setProperty(ISettingsPage.KEY_HTTP_PROXY_HOST,
-                mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_HOST, "")); //$NON-NLS-1$
-        props.setProperty(ISettingsPage.KEY_HTTP_PROXY_PORT,
-                mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_PORT, ""));   //$NON-NLS-1$
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdateChooserDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdateChooserDialog.java
deleted file mode 100755
index 11919a0..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdateChooserDialog.java
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java
deleted file mode 100755
index ed6c6e2..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.repository.AddonPackage;
-import com.android.sdklib.internal.repository.Archive;
-import com.android.sdklib.internal.repository.ITask;
-import com.android.sdklib.internal.repository.ITaskFactory;
-import com.android.sdklib.internal.repository.ITaskMonitor;
-import com.android.sdklib.internal.repository.LocalSdkParser;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdklib.internal.repository.RepoSource;
-import com.android.sdklib.internal.repository.RepoSources;
-import com.android.sdklib.internal.repository.ToolPackage;
-import com.android.sdkuilib.internal.repository.icons.ImageFactory;
-import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-
-/**
- * Data shared between {@link UpdaterWindowImpl} and its pages.
- */
-class UpdaterData {
-    private String mOsSdkRoot;
-
-    private final ISdkLog mSdkLog;
-    private ITaskFactory mTaskFactory;
-    private boolean mUserCanChangeSdkRoot;
-
-    private SdkManager mSdkManager;
-    private AvdManager mAvdManager;
-
-    private final LocalSdkParser mLocalSdkParser = new LocalSdkParser();
-    private final RepoSources mSources = new RepoSources();
-
-    private final LocalSdkAdapter mLocalSdkAdapter = new LocalSdkAdapter(this);
-    private final RepoSourcesAdapter mSourcesAdapter = new RepoSourcesAdapter(this);
-
-    private ImageFactory mImageFactory;
-
-    private final SettingsController mSettingsController;
-
-    private final ArrayList<ISdkListener> mListeners = new ArrayList<ISdkListener>();
-
-    private Shell mWindowShell;
-
-    public UpdaterData(String osSdkRoot, ISdkLog sdkLog) {
-        mOsSdkRoot = osSdkRoot;
-        mSdkLog = sdkLog;
-
-        mSettingsController = new SettingsController(this);
-
-        initSdk();
-    }
-
-    // ----- getters, setters ----
-
-    public void setOsSdkRoot(String osSdkRoot) {
-        if (mOsSdkRoot == null || mOsSdkRoot.equals(osSdkRoot) == false) {
-            mOsSdkRoot = osSdkRoot;
-            initSdk();
-        }
-    }
-
-    public String getOsSdkRoot() {
-        return mOsSdkRoot;
-    }
-
-    public void setTaskFactory(ITaskFactory taskFactory) {
-        mTaskFactory = taskFactory;
-    }
-
-    public ITaskFactory getTaskFactory() {
-        return mTaskFactory;
-    }
-
-    public void setUserCanChangeSdkRoot(boolean userCanChangeSdkRoot) {
-        mUserCanChangeSdkRoot = userCanChangeSdkRoot;
-    }
-
-    public boolean canUserChangeSdkRoot() {
-        return mUserCanChangeSdkRoot;
-    }
-
-    public RepoSources getSources() {
-        return mSources;
-    }
-
-    public RepoSourcesAdapter getSourcesAdapter() {
-        return mSourcesAdapter;
-    }
-
-    public LocalSdkParser getLocalSdkParser() {
-        return mLocalSdkParser;
-    }
-
-    public LocalSdkAdapter getLocalSdkAdapter() {
-        return mLocalSdkAdapter;
-    }
-
-    public ISdkLog getSdkLog() {
-        return mSdkLog;
-    }
-
-    public void setImageFactory(ImageFactory imageFactory) {
-        mImageFactory = imageFactory;
-    }
-
-    public ImageFactory getImageFactory() {
-        return mImageFactory;
-    }
-
-    public SdkManager getSdkManager() {
-        return mSdkManager;
-    }
-
-    public AvdManager getAvdManager() {
-        return mAvdManager;
-    }
-
-    public SettingsController getSettingsController() {
-        return mSettingsController;
-    }
-
-    /** Adds a listener ({@link ISdkListener}) that is notified when the SDK is reloaded. */
-    public void addListeners(ISdkListener listener) {
-        if (mListeners.contains(listener) == false) {
-            mListeners.add(listener);
-        }
-    }
-
-    /** Removes a listener ({@link ISdkListener}) that is notified when the SDK is reloaded. */
-    public void removeListener(ISdkListener listener) {
-        mListeners.remove(listener);
-    }
-
-    public void setWindowShell(Shell windowShell) {
-        mWindowShell = windowShell;
-    }
-
-    public Shell getWindowShell() {
-        return mWindowShell;
-    }
-
-    // -----
-
-    /**
-     * Initializes the {@link SdkManager} and the {@link AvdManager}.
-     */
-    private void initSdk() {
-        mSdkManager = SdkManager.createManager(mOsSdkRoot, mSdkLog);
-        try {
-            mAvdManager = null; // remove the old one if needed.
-            mAvdManager = new AvdManager(mSdkManager, mSdkLog);
-        } catch (AndroidLocationException e) {
-            mSdkLog.error(e, "Unable to read AVDs");
-        }
-
-        // notify adapters/parsers
-        // TODO
-
-        // notify listeners.
-        notifyListeners();
-    }
-
-    /**
-     * Reloads the SDK content (targets).
-     * <p/> This also reloads the AVDs in case their status changed.
-     * <p/>This does not notify the listeners ({@link ISdkListener}).
-     */
-    public void reloadSdk() {
-        // reload SDK
-        mSdkManager.reloadSdk(mSdkLog);
-
-        // reload AVDs
-        if (mAvdManager != null) {
-            try {
-                mAvdManager.reloadAvds(mSdkLog);
-            } catch (AndroidLocationException e) {
-                // FIXME
-            }
-        }
-
-        // notify adapters?
-        mLocalSdkParser.clearPackages();
-        // TODO
-
-        // notify listeners
-        notifyListeners();
-    }
-
-    /**
-     * Reloads the AVDs.
-     * <p/>This does not notify the listeners.
-     */
-    public void reloadAvds() {
-        // reload AVDs
-        if (mAvdManager != null) {
-            try {
-                mAvdManager.reloadAvds(mSdkLog);
-            } catch (AndroidLocationException e) {
-                mSdkLog.error(e, null);
-            }
-        }
-    }
-
-    /**
-     * Returns the list of installed packages, parsing them if this has not yet been done.
-     */
-    public Package[] getInstalledPackage() {
-        LocalSdkParser parser = getLocalSdkParser();
-
-        Package[] packages = parser.getPackages();
-
-        if (packages == null) {
-            // load on demand the first time
-            packages = parser.parseSdk(getOsSdkRoot(), getSdkManager(), getSdkLog());
-        }
-
-        return packages;
-    }
-
-    /**
-     * Notify the listeners ({@link ISdkListener}) that the SDK was reloaded.
-     * <p/>This can be called from any thread.
-     */
-    public void notifyListeners() {
-        if (mWindowShell != null && mListeners.size() > 0) {
-            mWindowShell.getDisplay().syncExec(new Runnable() {
-                public void run() {
-                    for (ISdkListener listener : mListeners) {
-                        try {
-                            listener.onSdkChange();
-                        } catch (Throwable t) {
-                            mSdkLog.error(t, null);
-                        }
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Install the list of given {@link Archive}s. This is invoked by the user selecting some
-     * packages in the remote page and then clicking "install selected".
-     *
-     * @param result The archives to install. Incompatible ones will be skipped.
-     */
-    public void installArchives(final ArrayList<ArchiveInfo> result) {
-        if (mTaskFactory == null) {
-            throw new IllegalArgumentException("Task Factory is null");
-        }
-
-        final boolean forceHttp = getSettingsController().getForceHttp();
-
-        mTaskFactory.start("Installing Archives", new ITask() {
-            public void run(ITaskMonitor monitor) {
-
-                final int progressPerArchive = 2 * Archive.NUM_MONITOR_INC;
-                monitor.setProgressMax(result.size() * progressPerArchive);
-                monitor.setDescription("Preparing to install archives");
-
-                boolean installedAddon = false;
-                boolean installedTools = false;
-
-                // Mark all current local archives as already installed.
-                HashSet<Archive> installedArchives = new HashSet<Archive>();
-                for (Package p : getInstalledPackage()) {
-                    for (Archive a : p.getArchives()) {
-                        installedArchives.add(a);
-                    }
-                }
-
-                int numInstalled = 0;
-                for (ArchiveInfo ai : result) {
-                    Archive archive = ai.getNewArchive();
-
-                    int nextProgress = monitor.getProgress() + progressPerArchive;
-                    try {
-                        if (monitor.isCancelRequested()) {
-                            break;
-                        }
-
-                        ArchiveInfo adep = ai.getDependsOn();
-                        if (adep != null && !installedArchives.contains(adep.getNewArchive())) {
-                            // This archive depends on another one that was not installed.
-                            // Skip it.
-                            monitor.setResult("Skipping '%1$s'; it depends on '%2$s' which was not installed.",
-                                    archive.getParentPackage().getShortDescription(),
-                                    adep.getNewArchive().getParentPackage().getShortDescription());
-                        }
-
-                        if (archive.install(mOsSdkRoot, forceHttp, mSdkManager, monitor)) {
-                            // We installed this archive.
-                            installedArchives.add(archive);
-                            numInstalled++;
-
-                            // If this package was replacing an existing one, the old one
-                            // is no longer installed.
-                            installedArchives.remove(ai.getReplaced());
-
-                            // Check if we successfully installed a tool or add-on package.
-                            if (archive.getParentPackage() instanceof AddonPackage) {
-                                installedAddon = true;
-                            } else if (archive.getParentPackage() instanceof ToolPackage) {
-                                installedTools = true;
-                            }
-                        }
-
-                    } catch (Throwable t) {
-                        // Display anything unexpected in the monitor.
-                        String msg = t.getMessage();
-                        if (msg != null) {
-                            monitor.setResult("Unexpected Error installing '%1$s': %2$s",
-                                    archive.getParentPackage().getShortDescription(), msg);
-                        } else {
-                            // no error info? get the stack call to display it
-                            // At least that'll give us a better bug report.
-                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                            t.printStackTrace(new PrintStream(baos));
-
-                            // and display it
-                            monitor.setResult("Unexpected Error installing '%1$s'\n%2$s",
-                                    archive.getParentPackage().getShortDescription(),
-                                    baos.toString());
-                        }
-                    } finally {
-
-                        // Always move the progress bar to the desired position.
-                        // This allows internal methods to not have to care in case
-                        // they abort early
-                        monitor.incProgress(nextProgress - monitor.getProgress());
-                    }
-                }
-
-                if (installedAddon) {
-                    // Update the USB vendor ids for adb
-                    try {
-                        mSdkManager.updateAdb();
-                        monitor.setResult("Updated ADB to support the USB devices declared in the SDK add-ons.");
-                    } catch (Exception e) {
-                        mSdkLog.error(e, "Update ADB failed");
-                        monitor.setResult("failed to update adb to support the USB devices declared in the SDK add-ons.");
-                    }
-                }
-
-                if (installedAddon || installedTools) {
-                    // We need to restart ADB. Actually since we don't know if it's even
-                    // running, maybe we should just kill it and not start it.
-                    // Note: it turns out even under Windows we don't need to kill adb
-                    // before updating the tools folder, as adb.exe is (surprisingly) not
-                    // locked.
-
-                    askForAdbRestart(monitor);
-                }
-
-                if (installedTools) {
-                    notifyToolsNeedsToBeRestarted();
-                }
-
-                if (numInstalled == 0) {
-                    monitor.setDescription("Done. Nothing was installed.");
-                } else {
-                    monitor.setDescription("Done. %1$d %2$s installed.",
-                            numInstalled,
-                            numInstalled == 1 ? "package" : "packages");
-
-                    //notify listeners something was installed, so that they can refresh
-                    reloadSdk();
-                }
-            }
-        });
-    }
-
-    /**
-     * Attemps to restart ADB.
-     *
-     * If the "ask before restart" setting is set (the default), prompt the user whether
-     * now is a good time to restart ADB.
-     * @param monitor
-     */
-    private void askForAdbRestart(ITaskMonitor monitor) {
-        final boolean[] canRestart = new boolean[] { true };
-
-        if (getSettingsController().getAskBeforeAdbRestart()) {
-            // need to ask for permission first
-            Display display = mWindowShell.getDisplay();
-
-            display.syncExec(new Runnable() {
-                public void run() {
-                    canRestart[0] = MessageDialog.openQuestion(mWindowShell,
-                            "ADB Restart",
-                            "A package that depends on ADB has been updated. It is recommended " +
-                            "to restart ADB. Is it OK to do it now? If not, you can restart it " +
-                            "manually later.");
-                }
-            });
-        }
-
-        if (canRestart[0]) {
-            AdbWrapper adb = new AdbWrapper(getOsSdkRoot(), monitor);
-            adb.stopAdb();
-            adb.startAdb();
-        }
-    }
-
-    private void notifyToolsNeedsToBeRestarted() {
-        Display display = mWindowShell.getDisplay();
-
-        display.syncExec(new Runnable() {
-            public void run() {
-                MessageDialog.openInformation(mWindowShell,
-                        "Android Tools Updated",
-                        "The Android SDK and AVD Manager that you are currently using has been updated. " +
-                        "It is recommended that you now close the manager window and re-open it. " +
-                        "If you started this window from Eclipse, please check if the Android " +
-                        "plug-in needs to be updated.");
-            }
-        });
-    }
-
-
-    /**
-     * Tries to update all the *existing* local packages.
-     * <p/>
-     * There are two modes of operation:
-     * <ul>
-     * <li>If selectedArchives is null, refreshes all sources, compares the available remote
-     * packages with the current local ones and suggest updates to be done to the user (including
-     * new platforms that the users doesn't have yet).
-     * <li>If selectedArchives is not null, this represents a list of archives/packages that
-     * the user wants to install or update, so just process these.
-     * </ul>
-     *
-     * @param selectedArchives The list of remote archive to consider for the update.
-     *  This can be null, in which case a list of remote archive is fetched from all
-     *  available sources.
-     */
-    public void updateOrInstallAll(Collection<Archive> selectedArchives) {
-        if (selectedArchives == null) {
-            refreshSources(true);
-        }
-
-        UpdaterLogic ul = new UpdaterLogic();
-        ArrayList<ArchiveInfo> archives = ul.computeUpdates(
-                selectedArchives,
-                getSources(),
-                getLocalSdkParser().getPackages());
-
-        if (selectedArchives == null) {
-            ul.addNewPlatforms(archives, getSources(), getLocalSdkParser().getPackages());
-        }
-
-        // TODO if selectedArchives is null and archives.len==0, find if there's
-        // any new platform we can suggest to install instead.
-
-        UpdateChooserDialog dialog = new UpdateChooserDialog(getWindowShell(), this, archives);
-        dialog.open();
-
-        ArrayList<ArchiveInfo> result = dialog.getResult();
-        if (result != null && result.size() > 0) {
-            installArchives(result);
-        }
-    }
-    /**
-     * Refresh all sources. This is invoked either internally (reusing an existing monitor)
-     * or as a UI callback on the remote page "Refresh" button (in which case the monitor is
-     * null and a new task should be created.)
-     *
-     * @param forceFetching When true, load sources that haven't been loaded yet.
-     *                      When false, only refresh sources that have been loaded yet.
-     */
-    public void refreshSources(final boolean forceFetching) {
-        assert mTaskFactory != null;
-
-        final boolean forceHttp = getSettingsController().getForceHttp();
-
-        mTaskFactory.start("Refresh Sources",new ITask() {
-            public void run(ITaskMonitor monitor) {
-                RepoSource[] sources = mSources.getSources();
-                monitor.setProgressMax(sources.length);
-                for (RepoSource source : sources) {
-                    if (forceFetching ||
-                            source.getPackages() != null ||
-                            source.getFetchError() != null) {
-                        source.load(monitor.createSubMonitor(1), forceHttp);
-                    }
-                    monitor.incProgress(1);
-                }
-            }
-        });
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterLogic.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterLogic.java
deleted file mode 100755
index 4478448..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterLogic.java
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.internal.repository.AddonPackage;
-import com.android.sdklib.internal.repository.Archive;
-import com.android.sdklib.internal.repository.DocPackage;
-import com.android.sdklib.internal.repository.ExtraPackage;
-import com.android.sdklib.internal.repository.IPackageVersion;
-import com.android.sdklib.internal.repository.MinToolsPackage;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdklib.internal.repository.PlatformPackage;
-import com.android.sdklib.internal.repository.RepoSource;
-import com.android.sdklib.internal.repository.RepoSources;
-import com.android.sdklib.internal.repository.ToolPackage;
-import com.android.sdklib.internal.repository.Package.UpdateInfo;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-
-/**
- * The logic to compute which packages to install, based on the choices
- * made by the user. This adds dependent packages as needed.
- * <p/>
- * When the user doesn't provide a selection, looks at local package to find
- * those that can be updated and compute dependencies too.
- */
-class UpdaterLogic {
-
-    /**
-     * Compute which packages to install by taking the user selection
-     * and adding dependent packages as needed.
-     *
-     * When the user doesn't provide a selection, looks at local package to find
-     * those that can be updated and compute dependencies too.
-     */
-    public ArrayList<ArchiveInfo> computeUpdates(
-            Collection<Archive> selectedArchives,
-            RepoSources sources,
-            Package[] localPkgs) {
-
-        ArrayList<ArchiveInfo> archives = new ArrayList<ArchiveInfo>();
-        ArrayList<Package> remotePkgs = new ArrayList<Package>();
-        RepoSource[] remoteSources = sources.getSources();
-
-        if (selectedArchives == null) {
-            selectedArchives = findUpdates(localPkgs, remotePkgs, remoteSources);
-        }
-
-        for (Archive a : selectedArchives) {
-            insertArchive(a,
-                    archives,
-                    selectedArchives,
-                    remotePkgs,
-                    remoteSources,
-                    localPkgs,
-                    false /*automated*/);
-        }
-
-        return archives;
-    }
-
-    /**
-     * Finds new platforms that the user does not have in his/her local SDK
-     * and adds them to the list of archives to install.
-     */
-    public void addNewPlatforms(ArrayList<ArchiveInfo> archives,
-            RepoSources sources,
-            Package[] localPkgs) {
-
-        // Find the highest platform installed
-        float currentPlatformScore = 0;
-        float currentAddonScore = 0;
-        float currentDocScore = 0;
-        HashMap<String, Float> currentExtraScore = new HashMap<String, Float>();
-        for (Package p : localPkgs) {
-            int rev = p.getRevision();
-            int api = 0;
-            boolean isPreview = false;
-            if (p instanceof  IPackageVersion) {
-                AndroidVersion vers = ((IPackageVersion) p).getVersion();
-                api = vers.getApiLevel();
-                isPreview = vers.isPreview();
-            }
-
-            // The score is 10*api + (1 if preview) + rev/100
-            // This allows previews to rank above a non-preview and
-            // allows revisions to rank appropriately.
-            float score = api * 10 + (isPreview ? 1 : 0) + rev/100.f;
-
-            if (p instanceof PlatformPackage) {
-                currentPlatformScore = Math.max(currentPlatformScore, score);
-            } else if (p instanceof AddonPackage) {
-                currentAddonScore = Math.max(currentAddonScore, score);
-            } else if (p instanceof ExtraPackage) {
-                currentExtraScore.put(((ExtraPackage) p).getPath(), score);
-            } else if (p instanceof DocPackage) {
-                currentDocScore = Math.max(currentDocScore, score);
-            }
-        }
-
-        RepoSource[] remoteSources = sources.getSources();
-        ArrayList<Package> remotePkgs = new ArrayList<Package>();
-        fetchRemotePackages(remotePkgs, remoteSources);
-
-        Package suggestedDoc = null;
-
-        for (Package p : remotePkgs) {
-            int rev = p.getRevision();
-            int api = 0;
-            boolean isPreview = false;
-            if (p instanceof  IPackageVersion) {
-                AndroidVersion vers = ((IPackageVersion) p).getVersion();
-                api = vers.getApiLevel();
-                isPreview = vers.isPreview();
-            }
-
-            float score = api * 10 + (isPreview ? 1 : 0) + rev/100.f;
-
-            boolean shouldAdd = false;
-            if (p instanceof PlatformPackage) {
-                shouldAdd = score > currentPlatformScore;
-            } else if (p instanceof AddonPackage) {
-                shouldAdd = score > currentAddonScore;
-            } else if (p instanceof ExtraPackage) {
-                String key = ((ExtraPackage) p).getPath();
-                shouldAdd = !currentExtraScore.containsKey(key) ||
-                    score > currentExtraScore.get(key).floatValue();
-            } else if (p instanceof DocPackage) {
-                // We don't want all the doc, only the most recent one
-                if (score > currentDocScore) {
-                    suggestedDoc = p;
-                    currentDocScore = score;
-                }
-            }
-
-            if (shouldAdd) {
-                // We should suggest this package for installation.
-                for (Archive a : p.getArchives()) {
-                    if (a.isCompatible()) {
-                        insertArchive(a,
-                                archives,
-                                null /*selectedArchives*/,
-                                remotePkgs,
-                                remoteSources,
-                                localPkgs,
-                                true /*automated*/);
-                    }
-                }
-            }
-        }
-
-        if (suggestedDoc != null) {
-            // We should suggest this package for installation.
-            for (Archive a : suggestedDoc.getArchives()) {
-                if (a.isCompatible()) {
-                    insertArchive(a,
-                            archives,
-                            null /*selectedArchives*/,
-                            remotePkgs,
-                            remoteSources,
-                            localPkgs,
-                            true /*automated*/);
-                }
-            }
-        }
-
-    }
-
-    /**
-     * Find suitable updates to all current local packages.
-     */
-    private Collection<Archive> findUpdates(Package[] localPkgs,
-            ArrayList<Package> remotePkgs,
-            RepoSource[] remoteSources) {
-        ArrayList<Archive> updates = new ArrayList<Archive>();
-
-        fetchRemotePackages(remotePkgs, remoteSources);
-
-        for (Package localPkg : localPkgs) {
-            for (Package remotePkg : remotePkgs) {
-                if (localPkg.canBeUpdatedBy(remotePkg) == UpdateInfo.UPDATE) {
-                    // Found a suitable update. Only accept the remote package
-                    // if it provides at least one compatible archive.
-
-                    for (Archive a : remotePkg.getArchives()) {
-                        if (a.isCompatible()) {
-                            updates.add(a);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        return updates;
-    }
-
-    private ArchiveInfo insertArchive(Archive archive,
-            ArrayList<ArchiveInfo> outArchives,
-            Collection<Archive> selectedArchives,
-            ArrayList<Package> remotePkgs,
-            RepoSource[] remoteSources,
-            Package[] localPkgs,
-            boolean automated) {
-        Package p = archive.getParentPackage();
-
-        // Is this an update?
-        Archive updatedArchive = null;
-        for (Package lp : localPkgs) {
-            assert lp.getArchives().length == 1;
-            if (lp.getArchives().length > 0 && lp.canBeUpdatedBy(p) == UpdateInfo.UPDATE) {
-                updatedArchive = lp.getArchives()[0];
-            }
-        }
-
-        // find dependencies
-        ArchiveInfo dep = findDependency(p,
-                outArchives,
-                selectedArchives,
-                remotePkgs,
-                remoteSources,
-                localPkgs);
-
-        // Make sure it's not a dup
-        ArchiveInfo ai = null;
-
-        for (ArchiveInfo ai2 : outArchives) {
-            if (ai2.getNewArchive().getParentPackage().sameItemAs(archive.getParentPackage())) {
-                ai = ai2;
-                break;
-            }
-        }
-
-        if (ai == null) {
-            ai = new ArchiveInfo(
-                archive, //newArchive
-                updatedArchive, //replaced
-                dep //dependsOn
-                );
-            outArchives.add(ai);
-        }
-
-        if (dep != null) {
-            dep.addDependencyFor(ai);
-        }
-
-        return ai;
-    }
-
-    private ArchiveInfo findDependency(Package pkg,
-            ArrayList<ArchiveInfo> outArchives,
-            Collection<Archive> selectedArchives,
-            ArrayList<Package> remotePkgs,
-            RepoSource[] remoteSources,
-            Package[] localPkgs) {
-
-        // Current dependencies can be:
-        // - addon: *always* depends on platform of same API level
-        // - platform: *might* depends on tools of rev >= min-tools-rev
-
-        if (pkg instanceof AddonPackage) {
-            AddonPackage addon = (AddonPackage) pkg;
-
-            return findPlatformDependency(
-                    addon,
-                    outArchives,
-                    selectedArchives,
-                    remotePkgs,
-                    remoteSources,
-                    localPkgs);
-
-        } else if (pkg instanceof MinToolsPackage) {
-            MinToolsPackage platformOrExtra = (MinToolsPackage) pkg;
-
-            return findToolsDependency(
-                    platformOrExtra,
-                    outArchives,
-                    selectedArchives,
-                    remotePkgs,
-                    remoteSources,
-                    localPkgs);
-        }
-
-        return null;
-    }
-
-    /**
-     * Resolves dependencies on tools.
-     *
-     * A platform or an extra package can both have a min-tools-rev, in which case it
-     * depends on having a tools package of the requested revision.
-     * Finds the tools dependency. If found, add it to the list of things to install.
-     * Returns the archive info dependency, if any.
-     */
-    protected ArchiveInfo findToolsDependency(MinToolsPackage platformOrExtra,
-            ArrayList<ArchiveInfo> outArchives,
-            Collection<Archive> selectedArchives,
-            ArrayList<Package> remotePkgs,
-            RepoSource[] remoteSources,
-            Package[] localPkgs) {
-        // This is the requirement to match.
-        int rev = platformOrExtra.getMinToolsRevision();
-
-        if (rev == MinToolsPackage.MIN_TOOLS_REV_NOT_SPECIFIED) {
-            // Well actually there's no requirement.
-            return null;
-        }
-
-        // First look in local packages.
-        for (Package p : localPkgs) {
-            if (p instanceof ToolPackage) {
-                if (((ToolPackage) p).getRevision() >= rev) {
-                    // We found one already installed. We don't report this dependency
-                    // as the UI only cares about resolving "newly added dependencies".
-                    return null;
-                }
-            }
-        }
-
-        // Look in archives already scheduled for install
-        for (ArchiveInfo ai : outArchives) {
-            Package p = ai.getNewArchive().getParentPackage();
-            if (p instanceof ToolPackage) {
-                if (((ToolPackage) p).getRevision() >= rev) {
-                    // The dependency is already scheduled for install, nothing else to do.
-                    return ai;
-                }
-            }
-        }
-
-        // Otherwise look in the selected archives.
-        if (selectedArchives != null) {
-            for (Archive a : selectedArchives) {
-                Package p = a.getParentPackage();
-                if (p instanceof ToolPackage) {
-                    if (((ToolPackage) p).getRevision() >= rev) {
-                        // It's not already in the list of things to install, so add it now
-                        return insertArchive(a, outArchives,
-                                selectedArchives, remotePkgs, remoteSources, localPkgs,
-                                true /*automated*/);
-                    }
-                }
-            }
-        }
-
-        // Finally nothing matched, so let's look at all available remote packages
-        fetchRemotePackages(remotePkgs, remoteSources);
-        for (Package p : remotePkgs) {
-            if (p instanceof ToolPackage) {
-                if (((ToolPackage) p).getRevision() >= rev) {
-                    // It's not already in the list of things to install, so add the
-                    // first compatible archive we can find.
-                    for (Archive a : p.getArchives()) {
-                        if (a.isCompatible()) {
-                            return insertArchive(a, outArchives,
-                                    selectedArchives, remotePkgs, remoteSources, localPkgs,
-                                    true /*automated*/);
-                        }
-                    }
-                }
-            }
-        }
-
-        // We end up here if nothing matches. We don't have a good tools to match.
-        // Seriously, that can't happens unless we totally screwed our repo manifest.
-        // We'll let this one go through anyway.
-        return null;
-    }
-
-    /**
-     * Resolves dependencies on platform.
-     *
-     * An addon depends on having a platform with the same API version.
-     * Finds the platform dependency. If found, add it to the list of things to install.
-     * Returns the archive info dependency, if any.
-     */
-    protected ArchiveInfo findPlatformDependency(AddonPackage addon,
-            ArrayList<ArchiveInfo> outArchives,
-            Collection<Archive> selectedArchives,
-            ArrayList<Package> remotePkgs,
-            RepoSource[] remoteSources,
-            Package[] localPkgs) {
-        // This is the requirement to match.
-        AndroidVersion v = addon.getVersion();
-
-        // Find a platform that would satisfy the requirement.
-
-        // First look in local packages.
-        for (Package p : localPkgs) {
-            if (p instanceof PlatformPackage) {
-                if (v.equals(((PlatformPackage) p).getVersion())) {
-                    // We found one already installed. We don't report this dependency
-                    // as the UI only cares about resolving "newly added dependencies".
-                    return null;
-                }
-            }
-        }
-
-        // Look in archives already scheduled for install
-        for (ArchiveInfo ai : outArchives) {
-            Package p = ai.getNewArchive().getParentPackage();
-            if (p instanceof PlatformPackage) {
-                if (v.equals(((PlatformPackage) p).getVersion())) {
-                    // The dependency is already scheduled for install, nothing else to do.
-                    return ai;
-                }
-            }
-        }
-
-        // Otherwise look in the selected archives.
-        if (selectedArchives != null) {
-            for (Archive a : selectedArchives) {
-                Package p = a.getParentPackage();
-                if (p instanceof PlatformPackage) {
-                    if (v.equals(((PlatformPackage) p).getVersion())) {
-                        // It's not already in the list of things to install, so add it now
-                        return insertArchive(a, outArchives,
-                                selectedArchives, remotePkgs, remoteSources, localPkgs,
-                                true /*automated*/);
-                    }
-                }
-            }
-        }
-
-        // Finally nothing matched, so let's look at all available remote packages
-        fetchRemotePackages(remotePkgs, remoteSources);
-        for (Package p : remotePkgs) {
-            if (p instanceof PlatformPackage) {
-                if (v.equals(((PlatformPackage) p).getVersion())) {
-                    // It's not already in the list of things to install, so add the
-                    // first compatible archive we can find.
-                    for (Archive a : p.getArchives()) {
-                        if (a.isCompatible()) {
-                            return insertArchive(a, outArchives,
-                                    selectedArchives, remotePkgs, remoteSources, localPkgs,
-                                    true /*automated*/);
-                        }
-                    }
-                }
-            }
-        }
-
-        // We end up here if nothing matches. We don't have a good platform to match.
-        // Seriously, that can't happens unless the repository contains a bogus addon
-        // entry that does not match any existing platform API level.
-        // It's conceivable that a 3rd part addon repo might have error, in which case
-        // we'll let this one go through anyway.
-        return null;
-    }
-
-    /** Fetch all remote packages only if really needed. */
-    protected void fetchRemotePackages(ArrayList<Package> remotePkgs, RepoSource[] remoteSources) {
-        if (remotePkgs.size() > 0) {
-            return;
-        }
-
-        for (RepoSource remoteSrc : remoteSources) {
-            Package[] pkgs = remoteSrc.getPackages();
-            if (pkgs != null) {
-                nextPackage: for (Package pkg : pkgs) {
-                    for (Archive a : pkg.getArchives()) {
-                        // Only add a package if it contains at least one compatible archive
-                        if (a.isCompatible()) {
-                            remotePkgs.add(pkg);
-                            continue nextPackage;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java
deleted file mode 100755
index 6e24af4..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.internal.repository.RepoSource;
-import com.android.sdklib.internal.repository.RepoSources;
-import com.android.sdklib.repository.SdkRepository;
-import com.android.sdkuilib.internal.repository.icons.ImageFactory;
-import com.android.sdkuilib.internal.tasks.ProgressTaskFactory;
-import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.List;
-import org.eclipse.swt.widgets.Shell;
-
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-
-/**
- * This is the private implementation of the UpdateWindow.
- */
-public class UpdaterWindowImpl {
-
-    private final Shell mParentShell;
-    /** Internal data shared between the window and its pages. */
-    private final UpdaterData mUpdaterData;
-    /** The array of pages instances. Only one is visible at a time. */
-    private ArrayList<Composite> mPages = new ArrayList<Composite>();
-    /** Indicates a page change is due to an internal request. Prevents callbacks from looping. */
-    private boolean mInternalPageChange;
-    /** A list of extra pages to instantiate. Each entry is an object array with 2 elements:
-     *  the string title and the Composite class to instantiate to create the page. */
-    private ArrayList<Object[]> mExtraPages;
-    /** A factory to create progress task dialogs. */
-    private ProgressTaskFactory mTaskFactory;
-    /** The initial page to display. If null or not a know class, the first page will be displayed.
-     * Must be set before the first call to {@link #open()}. */
-    private Class<? extends Composite> mInitialPage;
-    /** Sets whether the auto-update wizard will be shown when opening the window. */
-    private boolean mRequestAutoUpdate;
-
-    // --- UI members ---
-
-    protected Shell mAndroidSdkUpdater;
-    private SashForm mSashForm;
-    private List mPageList;
-    private Composite mPagesRootComposite;
-    private LocalPackagesPage mLocalPackagePage;
-    private RemotePackagesPage mRemotePackagesPage;
-    private AvdManagerPage mAvdManagerPage;
-    private StackLayout mStackLayout;
-
-    public UpdaterWindowImpl(Shell parentShell, ISdkLog sdkLog, String osSdkRoot,
-            boolean userCanChangeSdkRoot) {
-        mParentShell = parentShell;
-        mUpdaterData = new UpdaterData(osSdkRoot, sdkLog);
-        mUpdaterData.setUserCanChangeSdkRoot(userCanChangeSdkRoot);
-    }
-
-    /**
-     * Open the window.
-     * @wbp.parser.entryPoint
-     */
-    public void open() {
-        if (mParentShell == null) {
-            Display.setAppName("Android"); //$hide$ (hide from SWT designer)
-        }
-
-        createContents();
-        mAndroidSdkUpdater.open();
-        mAndroidSdkUpdater.layout();
-
-        postCreate();    //$hide$ (hide from SWT designer)
-
-        Display display = Display.getDefault();
-        while (!mAndroidSdkUpdater.isDisposed()) {
-            if (!display.readAndDispatch()) {
-                display.sleep();
-            }
-        }
-
-        dispose();  //$hide$
-    }
-
-    /**
-     * Create contents of the window.
-     */
-    protected void createContents() {
-        mAndroidSdkUpdater = new Shell(mParentShell, SWT.SHELL_TRIM);
-        mAndroidSdkUpdater.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent e) {
-                onAndroidSdkUpdaterDispose();    //$hide$ (hide from SWT designer)
-            }
-        });
-
-        FillLayout fl;
-        mAndroidSdkUpdater.setLayout(fl = new FillLayout(SWT.HORIZONTAL));
-        fl.marginHeight = fl.marginWidth = 5;
-        mAndroidSdkUpdater.setMinimumSize(new Point(200, 50));
-        mAndroidSdkUpdater.setSize(745, 433);
-        mAndroidSdkUpdater.setText("Android SDK and AVD Manager");
-
-        mSashForm = new SashForm(mAndroidSdkUpdater, SWT.NONE);
-
-        mPageList = new List(mSashForm, SWT.BORDER);
-        mPageList.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onPageListSelected();    //$hide$ (hide from SWT designer)
-            }
-        });
-
-        mPagesRootComposite = new Composite(mSashForm, SWT.NONE);
-        mStackLayout = new StackLayout();
-        mPagesRootComposite.setLayout(mStackLayout);
-
-        mAvdManagerPage = new AvdManagerPage(mPagesRootComposite, mUpdaterData);
-        mLocalPackagePage = new LocalPackagesPage(mPagesRootComposite, mUpdaterData);
-        mRemotePackagesPage = new RemotePackagesPage(mPagesRootComposite, mUpdaterData);
-
-        mSashForm.setWeights(new int[] {150, 576});
-    }
-
-    // -- Start of internal part ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    // --- Public API -----------
-
-
-    /**
-     * Registers an extra page for the updater window.
-     * <p/>
-     * Pages must derive from {@link Composite} and implement a constructor that takes
-     * a single parent {@link Composite} argument.
-     * <p/>
-     * All pages must be registered before the call to {@link #open()}.
-     *
-     * @param title The title of the page.
-     * @param pageClass The {@link Composite}-derived class that will implement the page.
-     */
-    public void registerExtraPage(String title, Class<? extends Composite> pageClass) {
-        if (mExtraPages == null) {
-            mExtraPages = new ArrayList<Object[]>();
-        }
-        mExtraPages.add(new Object[]{ title, pageClass });
-    }
-
-    /**
-     * Indicate the initial page that should be selected when the window opens.
-     * This must be called before the call to {@link #open()}.
-     * If null or if the page class is not found, the first page will be selected.
-     */
-    public void setInitialPage(Class<? extends Composite> pageClass) {
-        mInitialPage = pageClass;
-    }
-
-    /**
-     * Sets whether the auto-update wizard will be shown when opening the window.
-     * <p/>
-     * This must be called before the call to {@link #open()}.
-     */
-    public void setRequestAutoUpdate(boolean requestAutoUpdate) {
-        mRequestAutoUpdate = requestAutoUpdate;
-    }
-
-    /**
-     * Adds a new listener to be notified when a change is made to the content of the SDK.
-     */
-    public void addListeners(ISdkListener listener) {
-        mUpdaterData.addListeners(listener);
-    }
-
-    /**
-     * Removes a new listener to be notified anymore when a change is made to the content of
-     * the SDK.
-     */
-    public void removeListener(ISdkListener listener) {
-        mUpdaterData.removeListener(listener);
-    }
-
-    // --- Internals & UI Callbacks -----------
-
-
-    /**
-     * Helper to return the SWT shell.
-     */
-    private Shell getShell() {
-        return mAndroidSdkUpdater;
-    }
-
-    /**
-     * Callback called when the window shell is disposed.
-     */
-    private void onAndroidSdkUpdaterDispose() {
-        if (mUpdaterData != null) {
-            ImageFactory imgFactory = mUpdaterData.getImageFactory();
-            if (imgFactory != null) {
-                imgFactory.dispose();
-            }
-        }
-    }
-
-    /**
-     * Creates the icon of the window shell.
-     */
-    private void setWindowImage(Shell androidSdkUpdater) {
-        String imageName = "android_icon_16.png"; //$NON-NLS-1$
-        if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_DARWIN) {
-            imageName = "android_icon_128.png"; //$NON-NLS-1$
-        }
-
-        if (mUpdaterData != null) {
-            ImageFactory imgFactory = mUpdaterData.getImageFactory();
-            if (imgFactory != null) {
-                mAndroidSdkUpdater.setImage(imgFactory.getImageByName(imageName));
-            }
-        }
-    }
-
-    /**
-     * Once the UI has been created, initializes the content.
-     * This creates the pages, selects the first one, setup sources and scan for local folders.
-     */
-    private void postCreate() {
-        mUpdaterData.setWindowShell(getShell());
-        mTaskFactory = new ProgressTaskFactory(getShell());
-        mUpdaterData.setTaskFactory(mTaskFactory);
-        mUpdaterData.setImageFactory(new ImageFactory(getShell().getDisplay()));
-
-        setWindowImage(mAndroidSdkUpdater);
-
-        addPage(mAvdManagerPage,     "Virtual Devices");
-        addPage(mLocalPackagePage,   "Installed Packages");
-        addPage(mRemotePackagesPage, "Available Packages");
-        addExtraPages();
-
-        int pageIndex = 0;
-        int i = 0;
-        for (Composite p : mPages) {
-            if (p.getClass().equals(mInitialPage)) {
-                pageIndex = i;
-                break;
-            }
-            i++;
-        }
-        displayPage(pageIndex);
-        mPageList.setSelection(pageIndex);
-
-        setupSources();
-        initializeSettings();
-        mUpdaterData.notifyListeners();
-
-        if (mRequestAutoUpdate) {
-            mUpdaterData.updateOrInstallAll(null /*selectedArchives*/);
-        }
-    }
-
-    /**
-     * Called by the main loop when the window has been disposed.
-     */
-    private void dispose() {
-        mUpdaterData.getSources().saveUserSources(mUpdaterData.getSdkLog());
-    }
-
-    // --- page switching ---
-
-    /**
-     * Adds an instance of a page to the page list.
-     * <p/>
-     * Each page is a {@link Composite}. The title of the page is stored in the
-     * {@link Composite#getData()} field.
-     */
-    private void addPage(Composite page, String title) {
-        page.setData(title);
-        mPages.add(page);
-        mPageList.add(title);
-    }
-
-    /**
-     * Adds all extra pages. For each page, instantiates an instance of the {@link Composite}
-     * using the constructor that takes a single {@link Composite} argument and then adds it
-     * to the page list.
-     */
-    @SuppressWarnings("unchecked")
-    private void addExtraPages() {
-        if (mExtraPages == null) {
-            return;
-        }
-
-        for (Object[] extraPage : mExtraPages) {
-            String title = (String) extraPage[0];
-            Class<? extends Composite> clazz = (Class<? extends Composite>) extraPage[1];
-
-            // We want the constructor that takes a single Composite as parameter
-            Constructor<? extends Composite> cons;
-            try {
-                cons = clazz.getConstructor(new Class<?>[] { Composite.class });
-                Composite instance = cons.newInstance(new Object[] { mPagesRootComposite });
-                addPage(instance, title);
-
-            } catch (NoSuchMethodException e) {
-                // There is no such constructor.
-                mUpdaterData.getSdkLog().error(e,
-                        "Failed to add extra page %1$s. Constructor args must be (Composite parent).",  //$NON-NLS-1$
-                        clazz.getSimpleName());
-
-            } catch (Exception e) {
-                // Log this instead of crashing the whole app.
-                mUpdaterData.getSdkLog().error(e,
-                        "Failed to add extra page %1$s.",  //$NON-NLS-1$
-                        clazz.getSimpleName());
-            }
-        }
-    }
-
-    /**
-     * Callback invoked when an item is selected in the page list.
-     * If this is not an internal page change, displays the given page.
-     */
-    private void onPageListSelected() {
-        if (mInternalPageChange == false) {
-            int index = mPageList.getSelectionIndex();
-            if (index >= 0) {
-                displayPage(index);
-            }
-        }
-    }
-
-    /**
-     * Displays the page at the given index.
-     *
-     * @param index An index between 0 and {@link #mPages}'s length - 1.
-     */
-    private void displayPage(int index) {
-        Composite page = mPages.get(index);
-        if (page != null) {
-            mStackLayout.topControl = page;
-            mPagesRootComposite.layout(true);
-
-            if (!mInternalPageChange) {
-                mInternalPageChange = true;
-                mPageList.setSelection(index);
-                mInternalPageChange = false;
-            }
-        }
-    }
-
-    /**
-     * Used to initialize the sources.
-     */
-    private void setupSources() {
-        RepoSources sources = mUpdaterData.getSources();
-        sources.add(new RepoSource(SdkRepository.URL_GOOGLE_SDK_REPO_SITE, false /*userSource*/));
-
-        // SDK_UPDATER_URLS is a semicolon-separated list of URLs that can be used to
-        // seed the SDK Updater list for full repositories.
-        String str = System.getenv("SDK_UPDATER_URLS");
-        if (str != null) {
-            String[] urls = str.split(";");
-            for (String url : urls) {
-                if (url != null && url.length() > 0) {
-                    RepoSource s = new RepoSource(url, false /*userSource*/);
-                    if (!sources.hasSource(s)) {
-                        sources.add(s);
-                    }
-                }
-            }
-        }
-
-        // Load user sources
-        sources.loadUserSources(mUpdaterData.getSdkLog());
-
-        // SDK_UPDATER_USER_URLS is a semicolon-separated list of URLs that can be used to
-        // seed the SDK Updater list for user-only repositories. User sources can only provide
-        // add-ons and extra packages.
-        str = System.getenv("SDK_UPDATER_USER_URLS");
-        if (str != null) {
-            String[] urls = str.split(";");
-            for (String url : urls) {
-                if (url != null && url.length() > 0) {
-                    RepoSource s = new RepoSource(url, true /*userSource*/);
-                    if (!sources.hasSource(s)) {
-                        sources.add(s);
-                    }
-                }
-            }
-        }
-
-        mRemotePackagesPage.onSdkChange();
-    }
-
-    /**
-     * Initializes settings.
-     * This must be called after addExtraPages(), which created a settings page.
-     * Iterate through all the pages to find the first (and supposedly unique) setting page,
-     * and use it to load and apply these settings.
-     */
-    private void initializeSettings() {
-        SettingsController c = mUpdaterData.getSettingsController();
-        c.loadSettings();
-        c.applySettings();
-
-        for (Object page : mPages) {
-            if (page instanceof ISettingsPage) {
-                ISettingsPage settingsPage = (ISettingsPage) page;
-
-                c.setSettingsPage(settingsPage);
-                break;
-            }
-        }
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java
deleted file mode 100755
index cbd846e..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository.icons;
-
-import com.android.sdklib.internal.repository.AddonPackage;
-import com.android.sdklib.internal.repository.Archive;
-import com.android.sdklib.internal.repository.DocPackage;
-import com.android.sdklib.internal.repository.ExtraPackage;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdklib.internal.repository.PlatformPackage;
-import com.android.sdklib.internal.repository.RepoSource;
-import com.android.sdklib.internal.repository.ToolPackage;
-import com.android.sdkuilib.internal.repository.RepoSourcesAdapter;
-
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Iterator;
-
-
-/**
- * An utility class to serve {@link Image} correspond to the various icons
- * present in this package and dispose of them correctly at the end.
- */
-public class ImageFactory {
-
-    private final Display mDisplay;
-    private final HashMap<String, Image> mImages = new HashMap<String, Image>();
-
-    public ImageFactory(Display display) {
-        mDisplay = display;
-    }
-
-    /**
-     * Loads an image given its filename (with its extension).
-     * Might return null if the image cannot be loaded.
-     *
-     * @param imageName The filename (with extension) of the image to load.
-     * @return A new or existing {@link Image}. The caller must NOT dispose the image (the
-     *  image will disposed by {@link #dispose()}). The returned image can be null if the
-     *  expected file is missing.
-     */
-    public Image getImageByName(String imageName) {
-
-        Image image = mImages.get(imageName);
-        if (image != null) {
-            return image;
-        }
-
-        InputStream stream = getClass().getResourceAsStream(imageName);
-        if (stream != null) {
-            try {
-                image = new Image(mDisplay, stream);
-            } catch (SWTException e) {
-                // ignore
-            } catch (IllegalArgumentException e) {
-                // ignore
-            }
-        }
-
-        // Store the image in the hash, even if this failed. If it fails now, it will fail later.
-        mImages.put(imageName, image);
-
-        return image;
-    }
-
-    /**
-     * Loads and returns the appropriate image for a given package, archive or source object.
-     *
-     * @param object A {@link RepoSource} or {@link Package} or {@link Archive}.
-     * @return A new or existing {@link Image}. The caller must NOT dispose the image (the
-     *  image will disposed by {@link #dispose()}). The returned image can be null if the
-     *  expected file is missing.
-     */
-    public Image getImageForObject(Object object) {
-        if (object instanceof RepoSource) {
-            return getImageByName("source_icon16.png");                         //$NON-NLS-1$
-
-        } else if (object instanceof RepoSourcesAdapter.RepoSourceError) {
-            return getImageByName("error_icon16.png");                          //$NON-NLS-1$
-
-        } else if (object instanceof RepoSourcesAdapter.RepoSourceEmpty) {
-            return getImageByName("nopkg_icon16.png");                          //$NON-NLS-1$
-
-        } else if (object instanceof PlatformPackage) {
-            return getImageByName("android_icon_16.png");                       //$NON-NLS-1$
-
-        } else if (object instanceof AddonPackage) {
-            return getImageByName("addon_icon16.png");                          //$NON-NLS-1$
-
-        } else if (object instanceof ToolPackage) {
-            return getImageByName("tool_icon16.png");                           //$NON-NLS-1$
-
-        } else if (object instanceof DocPackage) {
-            return getImageByName("doc_icon16.png");                            //$NON-NLS-1$
-
-        } else if (object instanceof ExtraPackage) {
-            return getImageByName("extra_icon16.png");                          //$NON-NLS-1$
-
-        } else if (object instanceof Archive) {
-            if (((Archive) object).isCompatible()) {
-                return getImageByName("archive_icon16.png");                    //$NON-NLS-1$
-            } else {
-                return getImageByName("incompat_icon16.png");                   //$NON-NLS-1$
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Dispose all the images created by this factory so far.
-     */
-    public void dispose() {
-        Iterator<Image> it = mImages.values().iterator();
-        while(it.hasNext()) {
-            Image img = it.next();
-            if (img != null && img.isDisposed() == false) {
-                img.dispose();
-            }
-            it.remove();
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/accept_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/accept_icon16.png
deleted file mode 100755
index a9483fb..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/accept_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/addon_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/addon_icon16.png
deleted file mode 100755
index ca6a231..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/addon_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_128.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_128.png
deleted file mode 100644
index 8ab958a..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_128.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_16.png
deleted file mode 100755
index 0b0744b..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/archive_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/archive_icon16.png
deleted file mode 100755
index be5edd7..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/archive_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/doc_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/doc_icon16.png
deleted file mode 100755
index 8f56cb0..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/doc_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon16.png
deleted file mode 100755
index ccb4d0a..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/extra_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/extra_icon16.png
deleted file mode 100755
index a6529f0..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/extra_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/incompat_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/incompat_icon16.png
deleted file mode 100755
index 2a307e9..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/incompat_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon16.png
deleted file mode 100755
index 147837f..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/reject_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/reject_icon16.png
deleted file mode 100755
index b87bbc9..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/reject_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon16.png
deleted file mode 100755
index 5eb1ead..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/tool_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/tool_icon16.png
deleted file mode 100755
index 8ca7710..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/tool_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/unknown_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/unknown_icon16.png
deleted file mode 100755
index 1b97eb7..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/unknown_icon16.png
+++ /dev/null
Binary files differ
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressDialog.java
deleted file mode 100755
index ff79c68..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressDialog.java
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.tasks;
-
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.internal.repository.ITaskMonitor;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.ProgressBar;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-
-
-/**
- * Implements a {@link ProgressDialog}, used by the {@link ProgressTask} class.
- * This separates the dialog UI from the task logic.
- *
- * Note: this does not implement the {@link ITaskMonitor} interface to avoid confusing
- * SWT Designer.
- */
-final class ProgressDialog extends Dialog {
-
-    /**
-     * Min Y location for dialog. Need to deal with the menu bar on mac os.
-     */
-    private final static int MIN_Y = SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN ?
-            20 : 0;
-
-    private static enum CancelMode {
-        /** Cancel button says "Cancel" and is enabled. Waiting for user to cancel. */
-        ACTIVE,
-        /** Cancel button has been clicked. Waiting for thread to finish. */
-        CANCEL_PENDING,
-        /** Close pending. Close button clicked or thread finished but there were some
-         * messages so the user needs to manually close. */
-        CLOSE_MANUAL,
-        /** Close button clicked or thread finished. The window will automatically close. */
-        CLOSE_AUTO
-    }
-
-    /** The current mode of operation of the dialog. */
-    private CancelMode mCancelMode = CancelMode.ACTIVE;
-
-    /** Last dialog size for this session. */
-    private static Point sLastSize;
-
-
-    // UI fields
-    private Shell mDialogShell;
-    private Composite mRootComposite;
-    private Label mLabel;
-    private ProgressBar mProgressBar;
-    private Button mCancelButton;
-    private Text mResultText;
-    private final Thread mTaskThread;
-
-
-    /**
-     * Create the dialog.
-     * @param parent Parent container
-     * @param taskThread The thread to run the task.
-     */
-    public ProgressDialog(Shell parent, Thread taskThread) {
-        super(parent, SWT.APPLICATION_MODAL);
-        mTaskThread = taskThread;
-    }
-
-    /**
-     * Open the dialog and blocks till it gets closed
-     */
-    public void open() {
-        createContents();
-        positionShell();            //$hide$ (hide from SWT designer)
-        mDialogShell.open();
-        mDialogShell.layout();
-
-        startThread();              //$hide$ (hide from SWT designer)
-
-        Display display = getParent().getDisplay();
-        while (!mDialogShell.isDisposed() && mCancelMode != CancelMode.CLOSE_AUTO) {
-            if (!display.readAndDispatch()) {
-                display.sleep();
-            }
-        }
-
-        setCancelRequested();       //$hide$ (hide from SWT designer)
-
-        if (!mDialogShell.isDisposed()) {
-            sLastSize = mDialogShell.getSize();
-            mDialogShell.close();
-        }
-    }
-
-    /**
-     * Create contents of the dialog.
-     */
-    private void createContents() {
-        mDialogShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE);
-        mDialogShell.addShellListener(new ShellAdapter() {
-            @Override
-            public void shellClosed(ShellEvent e) {
-                onShellClosed(e);
-            }
-        });
-        mDialogShell.setLayout(new GridLayout(1, false));
-        mDialogShell.setSize(450, 300);
-        mDialogShell.setText(getText());
-
-        mRootComposite = new Composite(mDialogShell, SWT.NONE);
-        mRootComposite.setLayout(new GridLayout(2, false));
-        mRootComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
-
-        mLabel = new Label(mRootComposite, SWT.NONE);
-        mLabel.setText("Task");
-        mLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
-
-        mProgressBar = new ProgressBar(mRootComposite, SWT.NONE);
-        mProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-        mCancelButton = new Button(mRootComposite, SWT.NONE);
-        mCancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-        mCancelButton.setText("Cancel");
-
-        mCancelButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onCancelSelected();  //$hide$
-            }
-        });
-
-        mResultText = new Text(mRootComposite,
-                SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL | SWT.MULTI);
-        mResultText.setEditable(true);
-        mResultText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
-    }
-
-    // -- End of UI, Start of internal logic ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    public boolean isCancelRequested() {
-        return mCancelMode != CancelMode.ACTIVE;
-    }
-
-    /**
-     * Sets the mode to cancel pending.
-     * The first time this grays the cancel button, to let the user know that the
-     * cancel operation is pending.
-     */
-    public void setCancelRequested() {
-        if (!mDialogShell.isDisposed()) {
-            // The dialog is not disposed, make sure to run all this in the UI thread
-            // and lock on the cancel button mode.
-            mDialogShell.getDisplay().syncExec(new Runnable() {
-
-                public void run() {
-                    synchronized (mCancelMode) {
-                        if (mCancelMode == CancelMode.ACTIVE) {
-                            mCancelMode = CancelMode.CANCEL_PENDING;
-
-                            if (!mCancelButton.isDisposed()) {
-                                mCancelButton.setEnabled(false);
-                            }
-                        }
-                    }
-                }
-            });
-        } else {
-            // The dialog is disposed. Just set the boolean. We shouldn't be here.
-            if (mCancelMode == CancelMode.ACTIVE) {
-                mCancelMode = CancelMode.CANCEL_PENDING;
-            }
-        }
-    }
-
-    /**
-     * Sets the mode to close manual.
-     * The first time, this also ungrays the pause button and converts it to a close button.
-     */
-    public void setManualCloseRequested() {
-        if (!mDialogShell.isDisposed()) {
-            // The dialog is not disposed, make sure to run all this in the UI thread
-            // and lock on the cancel button mode.
-            mDialogShell.getDisplay().syncExec(new Runnable() {
-
-                public void run() {
-                    synchronized (mCancelMode) {
-                        if (mCancelMode != CancelMode.CLOSE_MANUAL &&
-                                mCancelMode != CancelMode.CLOSE_AUTO) {
-                            mCancelMode = CancelMode.CLOSE_MANUAL;
-
-                            if (!mCancelButton.isDisposed()) {
-                                mCancelButton.setEnabled(true);
-                                mCancelButton.setText("Close");
-                            }
-                        }
-                    }
-                }
-            });
-        } else {
-            // The dialog is disposed. Just set the booleans. We shouldn't be here.
-            if (mCancelMode != CancelMode.CLOSE_MANUAL &&
-                    mCancelMode != CancelMode.CLOSE_AUTO) {
-                mCancelMode = CancelMode.CLOSE_MANUAL;
-            }
-        }
-    }
-
-    /**
-     * Sets the mode to close auto.
-     * The main loop will just exit and close the shell at the first opportunity.
-     */
-    public void setAutoCloseRequested() {
-        synchronized (mCancelMode) {
-            if (mCancelMode != CancelMode.CLOSE_AUTO) {
-                mCancelMode = CancelMode.CLOSE_AUTO;
-            }
-        }
-    }
-
-    /**
-     * Callback invoked when the cancel button is selected.
-     * When in closing mode, this simply closes the shell. Otherwise triggers a cancel.
-     */
-    private void onCancelSelected() {
-        if (mCancelMode == CancelMode.CLOSE_MANUAL) {
-            setAutoCloseRequested();
-        } else {
-            setCancelRequested();
-        }
-    }
-
-    /**
-     * Callback invoked when the shell is closed either by clicking the close button
-     * on by calling shell.close().
-     * This does the same thing as clicking the cancel/close button unless the mode is
-     * to auto close in which case we should do nothing to let the shell close normally.
-     */
-    private void onShellClosed(ShellEvent e) {
-        if (mCancelMode != CancelMode.CLOSE_AUTO) {
-            e.doit = false; // don't close directly
-            onCancelSelected();
-        }
-    }
-
-    /**
-     * Sets the description in the current task dialog.
-     * This method can be invoked from a non-UI thread.
-     */
-    public void setDescription(final String descriptionFormat, final Object...args) {
-        mDialogShell.getDisplay().syncExec(new Runnable() {
-            public void run() {
-                if (!mLabel.isDisposed()) {
-                    mLabel.setText(String.format(descriptionFormat, args));
-                }
-            }
-        });
-    }
-
-    /**
-     * Sets the description in the current task dialog.
-     * This method can be invoked from a non-UI thread.
-     */
-    public void setResult(final String resultFormat, final Object...args) {
-        if (!mDialogShell.isDisposed()) {
-            mDialogShell.getDisplay().syncExec(new Runnable() {
-                public void run() {
-                    if (!mResultText.isDisposed()) {
-                        mResultText.setVisible(true);
-                        String newText = String.format(resultFormat, args);
-                        String lastText = mResultText.getText();
-                        if (lastText != null &&
-                                lastText.length() > 0 &&
-                                !lastText.endsWith("\n") &&
-                                !newText.startsWith("\n")) {
-                            mResultText.append("\n");
-                        }
-                        mResultText.append(newText);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Sets the max value of the progress bar.
-     * This method can be invoked from a non-UI thread.
-     *
-     * @see ProgressBar#setMaximum(int)
-     */
-    public void setProgressMax(final int max) {
-        if (!mDialogShell.isDisposed()) {
-            mDialogShell.getDisplay().syncExec(new Runnable() {
-                public void run() {
-                    if (!mProgressBar.isDisposed()) {
-                        mProgressBar.setMaximum(max);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Sets the current value of the progress bar.
-     * This method can be invoked from a non-UI thread.
-     */
-    public void setProgress(final int value) {
-        if (!mDialogShell.isDisposed()) {
-            mDialogShell.getDisplay().syncExec(new Runnable() {
-                public void run() {
-                    if (!mProgressBar.isDisposed()) {
-                        mProgressBar.setSelection(value);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Returns the current value of the progress bar,
-     * between 0 and up to {@link #setProgressMax(int)} - 1.
-     * This method can be invoked from a non-UI thread.
-     */
-    public int getProgress() {
-        final int[] result = new int[] { 0 };
-
-        if (!mDialogShell.isDisposed()) {
-            mDialogShell.getDisplay().syncExec(new Runnable() {
-                public void run() {
-                    if (!mProgressBar.isDisposed()) {
-                        result[0] = mProgressBar.getSelection();
-                    }
-                }
-            });
-        }
-
-        return result[0];
-    }
-
-    /**
-     * Starts the thread that runs the task.
-     * This is deferred till the UI is created.
-     */
-    private void startThread() {
-        if (mTaskThread != null) {
-            mTaskThread.start();
-        }
-    }
-
-    /**
-     * Centers the dialog in its parent shell.
-     */
-    private void positionShell() {
-        // Centers the dialog in its parent shell
-        Shell child = mDialogShell;
-        Shell parent = getParent();
-        if (child != null && parent != null) {
-
-            // get the parent client area with a location relative to the display
-            Rectangle parentArea = parent.getClientArea();
-            Point parentLoc = parent.getLocation();
-            int px = parentLoc.x;
-            int py = parentLoc.y;
-            int pw = parentArea.width;
-            int ph = parentArea.height;
-
-            // Reuse the last size if there's one, otherwise use the default
-            Point childSize = sLastSize != null ? sLastSize : child.getSize();
-            int cw = childSize.x;
-            int ch = childSize.y;
-
-            int x = px + (pw - cw) / 2;
-            if (x < 0) x = 0;
-
-            int y = py + (ph - ch) / 2;
-            if (y < MIN_Y) y = MIN_Y;
-
-            child.setLocation(x, y);
-            child.setSize(cw, ch);
-        }
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java
deleted file mode 100755
index f958a40..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.tasks;
-
-import com.android.sdklib.internal.repository.ITask;
-import com.android.sdklib.internal.repository.ITaskMonitor;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.ProgressBar;
-import org.eclipse.swt.widgets.Shell;
-
-
-/**
- * An {@link ITaskMonitor} that displays a {@link ProgressDialog}.
- */
-public final class ProgressTask implements ITaskMonitor {
-
-    private static final double MAX_COUNT = 10000.0;
-
-    private final ProgressDialog mDialog;
-    private boolean mAutomaticallyCloseOnTaskCompletion = true;
-    private double mIncCoef = 0;
-    private double mValue = 0;
-
-
-    /**
-     * Creates a new {@link ProgressTask} with the given title.
-     * The given task will execute in a separate thread (not the UI thread).
-     *
-     * This blocks till the thread ends.
-     */
-    public ProgressTask(Shell parent, String title, ITask task) {
-        mDialog = new ProgressDialog(parent, createTaskThread(title, task));
-        mDialog.setText(title);
-        mDialog.open();
-    }
-
-    /**
-     * Sets the description in the current task dialog.
-     * This method can be invoked from a non-UI thread.
-     */
-    public void setDescription(String descriptionFormat, Object...args) {
-        mDialog.setDescription(descriptionFormat, args);
-    }
-
-    /**
-     * Sets the description in the current task dialog.
-     * This method can be invoked from a non-UI thread.
-     */
-    public void setResult(String resultFormat, Object...args) {
-        mAutomaticallyCloseOnTaskCompletion = false;
-        mDialog.setResult(resultFormat, args);
-    }
-
-    /**
-     * Sets the max value of the progress bar.
-     * This method can be invoked from a non-UI thread.
-     *
-     * Weird things will happen if setProgressMax is called multiple times
-     * *after* {@link #incProgress(int)}: we don't try to adjust it on the
-     * fly.
-     *
-     * @see ProgressBar#setMaximum(int)
-     */
-    public void setProgressMax(int max) {
-        assert max > 0;
-        // Always set the dialog's progress max to 10k since it only handles
-        // integers and we want to have a better inner granularity. Instead
-        // we use the max to compute a coefficient for inc deltas.
-        mDialog.setProgressMax((int) MAX_COUNT);
-        mIncCoef = max > 0 ? MAX_COUNT / max : 0;
-        assert mIncCoef > 0;
-    }
-
-    /**
-     * Increments the current value of the progress bar.
-     *
-     * This method can be invoked from a non-UI thread.
-     */
-    public void incProgress(int delta) {
-        assert mIncCoef > 0;
-        assert delta > 0;
-        internalIncProgress(delta * mIncCoef);
-    }
-
-    private void internalIncProgress(double realDelta) {
-        mValue += realDelta;
-        mDialog.setProgress((int)mValue);
-    }
-
-    /**
-     * Returns the current value of the progress bar,
-     * between 0 and up to {@link #setProgressMax(int)} - 1.
-     *
-     * This method can be invoked from a non-UI thread.
-     */
-    public int getProgress() {
-        assert mIncCoef > 0;
-        return mIncCoef > 0 ? (int)(mDialog.getProgress() / mIncCoef) : 0;
-    }
-
-    /**
-     * Returns true if the "Cancel" button was selected.
-     * It is up to the task thread to pool this and exit.
-     */
-    public boolean isCancelRequested() {
-        return mDialog.isCancelRequested();
-    }
-
-    /**
-     * Creates a thread to run the task. The thread has not been started yet.
-     * When the task completes, requests to close the dialog.
-     * @return A new thread that will run the task. The thread has not been started yet.
-     */
-    private Thread createTaskThread(String title, final ITask task) {
-        if (task != null) {
-            return new Thread(title) {
-                @Override
-                public void run() {
-                    task.run(ProgressTask.this);
-                    if (mAutomaticallyCloseOnTaskCompletion) {
-                        mDialog.setAutoCloseRequested();
-                    } else {
-                        mDialog.setManualCloseRequested();
-                    }
-                }
-            };
-        }
-        return null;
-    }
-
-    /**
-     * Display a yes/no question dialog box.
-     *
-     * This implementation allow this to be called from any thread, it
-     * makes sure the dialog is opened synchronously in the ui thread.
-     *
-     * @param title The title of the dialog box
-     * @param message The error message
-     * @return true if YES was clicked.
-     */
-    public boolean displayPrompt(final String title, final String message) {
-        final Shell shell = mDialog.getParent();
-        Display display = shell.getDisplay();
-
-        // we need to ask the user what he wants to do.
-        final boolean[] result = new boolean[] { false };
-        display.syncExec(new Runnable() {
-            public void run() {
-                result[0] = MessageDialog.openQuestion(shell, title, message);
-            }
-        });
-        return result[0];
-    }
-
-    /**
-     * Creates a sub-monitor that will use up to tickCount on the progress bar.
-     * tickCount must be 1 or more.
-     */
-    public ITaskMonitor createSubMonitor(int tickCount) {
-        assert mIncCoef > 0;
-        assert tickCount > 0;
-        return new SubTaskMonitor(this, null, mValue, tickCount * mIncCoef);
-    }
-
-    private interface ISubTaskMonitor extends ITaskMonitor {
-        public void subIncProgress(double realDelta);
-    }
-
-    private static class SubTaskMonitor implements ISubTaskMonitor {
-
-        private final ProgressTask mRoot;
-        private final ISubTaskMonitor mParent;
-        private final double mStart;
-        private final double mSpan;
-        private double mSubValue;
-        private double mSubCoef;
-
-        /**
-         * Creates a new sub task monitor which will work for the given range [start, start+span]
-         * in its parent.
-         *
-         * @param root The ProgressTask root
-         * @param parent The immediate parent. Can be the null or another sub task monitor.
-         * @param start The start value in the root's coordinates
-         * @param span The span value in the root's coordinates
-         */
-        public SubTaskMonitor(ProgressTask root,
-                ISubTaskMonitor parent,
-                double start,
-                double span) {
-            mRoot = root;
-            mParent = parent;
-            mStart = start;
-            mSpan = span;
-            mSubValue = start;
-        }
-
-        public boolean isCancelRequested() {
-            return mRoot.isCancelRequested();
-        }
-
-        public void setDescription(String descriptionFormat, Object... args) {
-            mRoot.setDescription(descriptionFormat, args);
-        }
-
-        public void setResult(String resultFormat, Object... args) {
-            mRoot.setResult(resultFormat, args);
-        }
-
-        public void setProgressMax(int max) {
-            assert max > 0;
-            mSubCoef = max > 0 ? mSpan / max : 0;
-            assert mSubCoef > 0;
-        }
-
-        public int getProgress() {
-            assert mSubCoef > 0;
-            return mSubCoef > 0 ? (int)((mSubValue - mStart) / mSubCoef) : 0;
-        }
-
-        public void incProgress(int delta) {
-            assert mSubCoef > 0;
-            subIncProgress(delta * mSubCoef);
-        }
-
-        public void subIncProgress(double realDelta) {
-            mSubValue += realDelta;
-            if (mParent != null) {
-                mParent.subIncProgress(realDelta);
-            } else {
-                mRoot.internalIncProgress(realDelta);
-            }
-        }
-
-        public boolean displayPrompt(String title, String message) {
-            return mRoot.displayPrompt(title, message);
-        }
-
-        public ITaskMonitor createSubMonitor(int tickCount) {
-            assert mSubCoef > 0;
-            assert tickCount > 0;
-            return new SubTaskMonitor(mRoot,
-                    this,
-                    mSubValue,
-                    tickCount * mSubCoef);
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java
deleted file mode 100755
index c90df26..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.tasks;
-
-import com.android.sdklib.internal.repository.ITask;
-import com.android.sdklib.internal.repository.ITaskFactory;
-
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * An {@link ITaskFactory} that creates a new {@link ProgressTask} dialog
- * for each new task.
- */
-public final class ProgressTaskFactory implements ITaskFactory {
-
-    private final Shell mShell;
-
-    public ProgressTaskFactory(Shell shell) {
-        mShell = shell;
-    }
-
-    public void start(String title, ITask task) {
-        new ProgressTask(mShell, title, task);
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
deleted file mode 100644
index 20bdfad..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
+++ /dev/null
@@ -1,931 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.widgets;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.avd.HardwareProperties;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty;
-import com.android.sdkuilib.internal.repository.icons.ImageFactory;
-import com.android.sdkuilib.internal.widgets.AvdSelector.SdkLog;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.CellLabelProvider;
-import org.eclipse.jface.viewers.ComboBoxCellEditor;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.TextCellEditor;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerCell;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-
-/**
- * AVD creator dialog.
- *
- * TODO:
- * - use SdkTargetSelector instead of Combo
- * - tooltips on widgets.
- *
- */
-final class AvdCreationDialog extends GridDialog {
-
-    private final AvdManager mAvdManager;
-    private final TreeMap<String, IAndroidTarget> mCurrentTargets =
-        new TreeMap<String, IAndroidTarget>();
-
-    private final Map<String, HardwareProperty> mHardwareMap;
-    private final Map<String, String> mProperties = new HashMap<String, String>();
-    // a list of user-edited properties.
-    private final ArrayList<String> mEditedProperties = new ArrayList<String>();
-
-    private Text mAvdName;
-    private Combo mTargetCombo;
-
-    private Button mSdCardSizeRadio;
-    private Text mSdCardSize;
-    private Combo mSdCardSizeCombo;
-
-    private Text mSdCardFile;
-    private Button mBrowseSdCard;
-    private Button mSdCardFileRadio;
-
-    private Button mSkinListRadio;
-    private Combo mSkinCombo;
-
-    private Button mSkinSizeRadio;
-    private Text mSkinSizeWidth;
-    private Text mSkinSizeHeight;
-
-    private TableViewer mHardwareViewer;
-    private Button mDeleteHardwareProp;
-
-    private Button mForceCreation;
-    private Button mOkButton;
-    private Label mStatusIcon;
-    private Label mStatusLabel;
-    private Composite mStatusComposite;
-    private final ImageFactory mImageFactory;
-
-    /**
-     * {@link VerifyListener} for {@link Text} widgets that should only contains numbers.
-     */
-    private final VerifyListener mDigitVerifier = new VerifyListener() {
-        public void verifyText(VerifyEvent event) {
-            int count = event.text.length();
-            for (int i = 0 ; i < count ; i++) {
-                char c = event.text.charAt(i);
-                if (c < '0' || c > '9') {
-                    event.doit = false;
-                    return;
-                }
-            }
-        }
-    };
-
-    /**
-     * Callback when the AVD name is changed.
-     * Enables the force checkbox if the name is a duplicate.
-     */
-    private class CreateNameModifyListener implements ModifyListener {
-        public void modifyText(ModifyEvent e) {
-            String name = mAvdName.getText().trim();
-            AvdInfo avdMatch = mAvdManager.getAvd(name, false /*validAvdOnly*/);
-            if (avdMatch != null) {
-                mForceCreation.setEnabled(true);
-            } else {
-                mForceCreation.setEnabled(false);
-                mForceCreation.setSelection(false);
-            }
-
-            validatePage();
-        }
-    }
-
-    /**
-     * {@link ModifyListener} used for live-validation of the fields content.
-     */
-    private class ValidateListener extends SelectionAdapter implements ModifyListener {
-        public void modifyText(ModifyEvent e) {
-            validatePage();
-        }
-
-        @Override
-        public void widgetSelected(SelectionEvent e) {
-            super.widgetSelected(e);
-            validatePage();
-        }
-    }
-
-    protected AvdCreationDialog(Shell parentShell, AvdManager avdManager,
-            ImageFactory imageFactory) {
-        super(parentShell, 2, false);
-        mAvdManager = avdManager;
-        mImageFactory = imageFactory;
-
-        File hardwareDefs = new File (avdManager.getSdkManager().getLocation() + File.separator +
-                SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI);
-        mHardwareMap = HardwareProperties.parseHardwareDefinitions(
-                hardwareDefs, null /*sdkLog*/);
-    }
-
-    @Override
-    public void create() {
-        super.create();
-
-        Point p = getShell().getSize();
-        if (p.x < 400) {
-            p.x = 400;
-        }
-        getShell().setSize(p);
-    }
-
-    @Override
-    protected Control createContents(Composite parent) {
-        Control control = super.createContents(parent);
-        getShell().setText("Create new AVD");
-
-        mOkButton = getButton(IDialogConstants.OK_ID);
-        validatePage();
-
-        return control;
-    }
-
-    @Override
-    public void createDialogContent(final Composite parent) {
-        GridData gd;
-        GridLayout gl;
-
-        Label label = new Label(parent, SWT.NONE);
-        label.setText("Name:");
-
-        mAvdName = new Text(parent, SWT.BORDER);
-        mAvdName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mAvdName.addModifyListener(new CreateNameModifyListener());
-
-        label = new Label(parent, SWT.NONE);
-        label.setText("Target:");
-
-        mTargetCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN);
-        mTargetCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mTargetCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                super.widgetSelected(e);
-                reloadSkinCombo();
-                validatePage();
-            }
-        });
-
-        // --- sd card group
-        label = new Label(parent, SWT.NONE);
-        label.setText("SD Card:");
-        label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING,
-                false, false));
-
-        final Group sdCardGroup = new Group(parent, SWT.NONE);
-        sdCardGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        sdCardGroup.setLayout(new GridLayout(3, false));
-
-        mSdCardSizeRadio = new Button(sdCardGroup, SWT.RADIO);
-        mSdCardSizeRadio.setText("Size:");
-        mSdCardSizeRadio.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                boolean sizeMode = mSdCardSizeRadio.getSelection();
-                enableSdCardWidgets(sizeMode);
-                validatePage();
-            }
-        });
-
-        ValidateListener validateListener = new ValidateListener();
-
-        mSdCardSize = new Text(sdCardGroup, SWT.BORDER);
-        mSdCardSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mSdCardSize.addVerifyListener(mDigitVerifier);
-
-        mSdCardSizeCombo = new Combo(sdCardGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mSdCardSizeCombo.add("KiB");
-        mSdCardSizeCombo.add("MiB");
-        mSdCardSizeCombo.select(1);
-
-        mSdCardFileRadio = new Button(sdCardGroup, SWT.RADIO);
-        mSdCardFileRadio.setText("File:");
-
-        mSdCardFile = new Text(sdCardGroup, SWT.BORDER);
-        mSdCardFile.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mSdCardFile.addModifyListener(validateListener);
-
-        mBrowseSdCard = new Button(sdCardGroup, SWT.PUSH);
-        mBrowseSdCard.setText("Browse...");
-        mBrowseSdCard.addSelectionListener(new SelectionAdapter() {
-           @Override
-            public void widgetSelected(SelectionEvent arg0) {
-               onBrowseSdCard();
-               validatePage();
-            }
-        });
-
-        mSdCardSizeRadio.setSelection(true);
-        enableSdCardWidgets(true);
-
-        // --- skin group
-        label = new Label(parent, SWT.NONE);
-        label.setText("Skin:");
-        label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING,
-                false, false));
-
-        final Group skinGroup = new Group(parent, SWT.NONE);
-        skinGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        skinGroup.setLayout(new GridLayout(4, false));
-
-        mSkinListRadio = new Button(skinGroup, SWT.RADIO);
-        mSkinListRadio.setText("Built-in:");
-        mSkinListRadio.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                boolean listMode = mSkinListRadio.getSelection();
-                enableSkinWidgets(listMode);
-                validatePage();
-            }
-        });
-
-        mSkinCombo = new Combo(skinGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
-        mSkinCombo.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 3;
-        mSkinCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                // get the skin info
-                loadSkin();
-            }
-        });
-
-        mSkinSizeRadio = new Button(skinGroup, SWT.RADIO);
-        mSkinSizeRadio.setText("Resolution:");
-
-        mSkinSizeWidth = new Text(skinGroup, SWT.BORDER);
-        mSkinSizeWidth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mSkinSizeWidth.addVerifyListener(mDigitVerifier);
-        mSkinSizeWidth.addModifyListener(validateListener);
-
-        new Label(skinGroup, SWT.NONE).setText("x");
-
-        mSkinSizeHeight = new Text(skinGroup, SWT.BORDER);
-        mSkinSizeHeight.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mSkinSizeHeight.addVerifyListener(mDigitVerifier);
-        mSkinSizeHeight.addModifyListener(validateListener);
-
-        mSkinListRadio.setSelection(true);
-        enableSkinWidgets(true);
-
-        // --- hardware group
-        label = new Label(parent, SWT.NONE);
-        label.setText("Hardware:");
-        label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING,
-                false, false));
-
-        final Group hwGroup = new Group(parent, SWT.NONE);
-        hwGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        hwGroup.setLayout(new GridLayout(2, false));
-
-        createHardwareTable(hwGroup);
-
-        // composite for the side buttons
-        Composite hwButtons = new Composite(hwGroup, SWT.NONE);
-        hwButtons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-        hwButtons.setLayout(gl = new GridLayout(1, false));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        Button b = new Button(hwButtons, SWT.PUSH | SWT.FLAT);
-        b.setText("New...");
-        b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        b.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent event) {
-                HardwarePropertyChooser dialog = new HardwarePropertyChooser(parent.getShell(),
-                        mHardwareMap, mProperties.keySet());
-                if (dialog.open() == Window.OK) {
-                    HardwareProperty choice = dialog.getProperty();
-                    if (choice != null) {
-                        mProperties.put(choice.getName(), choice.getDefault());
-                        mHardwareViewer.refresh();
-                    }
-                }
-            }
-        });
-        mDeleteHardwareProp = new Button(hwButtons, SWT.PUSH | SWT.FLAT);
-        mDeleteHardwareProp.setText("Delete");
-        mDeleteHardwareProp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mDeleteHardwareProp.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                ISelection selection = mHardwareViewer.getSelection();
-                if (selection instanceof IStructuredSelection) {
-                    String hwName = (String)((IStructuredSelection)selection).getFirstElement();
-                    mProperties.remove(hwName);
-                    mHardwareViewer.refresh();
-                }
-            }
-        });
-        mDeleteHardwareProp.setEnabled(false);
-
-        // --- end hardware group
-
-        mForceCreation = new Button(parent, SWT.CHECK);
-        mForceCreation.setText("Force create");
-        mForceCreation.setToolTipText("Select this to override any existing AVD");
-        mForceCreation.setLayoutData(new GridData(GridData.END, GridData.CENTER,
-                true, false, 2, 1));
-        mForceCreation.setEnabled(false);
-        mForceCreation.addSelectionListener(validateListener);
-
-        // add a separator to separate from the ok/cancel button
-        label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
-        label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1));
-
-        // add stuff for the error display
-        mStatusComposite = new Composite(parent, SWT.NONE);
-        mStatusComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER,
-                true, false, 3, 1));
-        mStatusComposite.setLayout(gl = new GridLayout(2, false));
-        gl.marginHeight = gl.marginWidth = 0;
-
-        mStatusIcon = new Label(mStatusComposite, SWT.NONE);
-        mStatusIcon.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING,
-                false, false));
-        mStatusLabel = new Label(mStatusComposite, SWT.NONE);
-        mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mStatusLabel.setText(" \n "); //$NON-NLS-1$
-
-        reloadTargetCombo();
-    }
-
-    /**
-     * Creates the UI for the hardware properties table.
-     * This creates the {@link Table}, and several viewers ({@link TableViewer},
-     * {@link TableViewerColumn}) and adds edit support for the 2nd column
-     */
-    private void createHardwareTable(Composite parent) {
-        final Table hardwareTable = new Table(parent, SWT.SINGLE | SWT.FULL_SELECTION);
-        GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
-        gd.widthHint = 200;
-        gd.heightHint = 100;
-        hardwareTable.setLayoutData(gd);
-        hardwareTable.setHeaderVisible(true);
-        hardwareTable.setLinesVisible(true);
-
-        // -- Table viewer
-        mHardwareViewer = new TableViewer(hardwareTable);
-        mHardwareViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            public void selectionChanged(SelectionChangedEvent event) {
-                // it's a single selection mode, we can just access the selection index
-                // from the table directly.
-                mDeleteHardwareProp.setEnabled(hardwareTable.getSelectionIndex() != -1);
-            }
-        });
-
-        // only a content provider. Use viewers per column below (for editing support)
-        mHardwareViewer.setContentProvider(new IStructuredContentProvider() {
-            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-                // we can just ignore this. we just use mProperties directly.
-            }
-
-            public Object[] getElements(Object arg0) {
-                return mProperties.keySet().toArray();
-            }
-
-            public void dispose() {
-                // pass
-            }
-        });
-
-        // -- column 1: prop abstract name
-        TableColumn col1 = new TableColumn(hardwareTable, SWT.LEFT);
-        col1.setText("Property");
-        col1.setWidth(150);
-        TableViewerColumn tvc1 = new TableViewerColumn(mHardwareViewer, col1);
-        tvc1.setLabelProvider(new CellLabelProvider() {
-            @Override
-            public void update(ViewerCell cell) {
-                HardwareProperty prop = mHardwareMap.get(cell.getElement());
-                cell.setText(prop != null ? prop.getAbstract() : "");
-            }
-        });
-
-        // -- column 2: prop value
-        TableColumn col2 = new TableColumn(hardwareTable, SWT.LEFT);
-        col2.setText("Value");
-        col2.setWidth(50);
-        TableViewerColumn tvc2 = new TableViewerColumn(mHardwareViewer, col2);
-        tvc2.setLabelProvider(new CellLabelProvider() {
-            @Override
-            public void update(ViewerCell cell) {
-                String value = mProperties.get(cell.getElement());
-                cell.setText(value != null ? value : "");
-            }
-        });
-
-        // add editing support to the 2nd column
-        tvc2.setEditingSupport(new EditingSupport(mHardwareViewer) {
-            @Override
-            protected void setValue(Object element, Object value) {
-                String hardwareName = (String)element;
-                HardwareProperty property = mHardwareMap.get(hardwareName);
-                switch (property.getType()) {
-                    case INTEGER:
-                        mProperties.put((String)element, (String)value);
-                        break;
-                    case DISKSIZE:
-                        if (HardwareProperties.DISKSIZE_PATTERN.matcher((String)value).matches()) {
-                            mProperties.put((String)element, (String)value);
-                        }
-                        break;
-                    case BOOLEAN:
-                        int index = (Integer)value;
-                        mProperties.put((String)element, HardwareProperties.BOOLEAN_VALUES[index]);
-                        break;
-                }
-                mHardwareViewer.refresh(element);
-            }
-
-            @Override
-            protected Object getValue(Object element) {
-                String hardwareName = (String)element;
-                HardwareProperty property = mHardwareMap.get(hardwareName);
-                String value = mProperties.get(hardwareName);
-                switch (property.getType()) {
-                    case INTEGER:
-                        // intended fall-through.
-                    case DISKSIZE:
-                        return value;
-                    case BOOLEAN:
-                        return HardwareProperties.getBooleanValueIndex(value);
-                }
-
-                return null;
-            }
-
-            @Override
-            protected CellEditor getCellEditor(Object element) {
-                String hardwareName = (String)element;
-                HardwareProperty property = mHardwareMap.get(hardwareName);
-                switch (property.getType()) {
-                    // TODO: custom TextCellEditor that restrict input.
-                    case INTEGER:
-                        // intended fall-through.
-                    case DISKSIZE:
-                        return new TextCellEditor(hardwareTable);
-                    case BOOLEAN:
-                        return new ComboBoxCellEditor(hardwareTable,
-                                HardwareProperties.BOOLEAN_VALUES,
-                                SWT.READ_ONLY | SWT.DROP_DOWN);
-                }
-                return null;
-            }
-
-            @Override
-            protected boolean canEdit(Object element) {
-                String hardwareName = (String)element;
-                HardwareProperty property = mHardwareMap.get(hardwareName);
-                return property != null;
-            }
-        });
-
-
-        mHardwareViewer.setInput(mProperties);
-    }
-
-    @Override
-    protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
-        if (id == IDialogConstants.OK_ID) {
-            label = "Create AVD";
-        }
-
-        return super.createButton(parent, id, label, defaultButton);
-    }
-
-    @Override
-    protected void okPressed() {
-        if (createAvd()) {
-            super.okPressed();
-        }
-    }
-
-    /**
-     * Enable or disable the sd card widgets.
-     * @param sizeMode if true the size-based widgets are to be enabled, and the file-based ones
-     * disabled.
-     */
-    private void enableSdCardWidgets(boolean sizeMode) {
-        mSdCardSize.setEnabled(sizeMode);
-        mSdCardSizeCombo.setEnabled(sizeMode);
-
-        mSdCardFile.setEnabled(!sizeMode);
-        mBrowseSdCard.setEnabled(!sizeMode);
-    }
-
-    /**
-     * Enable or disable the skin widgets.
-     * @param listMode if true the list-based widgets are to be enabled, and the size-based ones
-     * disabled.
-     */
-    private void enableSkinWidgets(boolean listMode) {
-        mSkinCombo.setEnabled(listMode);
-
-        mSkinSizeWidth.setEnabled(!listMode);
-        mSkinSizeHeight.setEnabled(!listMode);
-    }
-
-
-    private void onBrowseSdCard() {
-        FileDialog dlg = new FileDialog(getContents().getShell(), SWT.OPEN);
-        dlg.setText("Choose SD Card image file.");
-
-        String fileName = dlg.open();
-        if (fileName != null) {
-            mSdCardFile.setText(fileName);
-        }
-    }
-
-    private void reloadTargetCombo() {
-        String selected = null;
-        int index = mTargetCombo.getSelectionIndex();
-        if (index >= 0) {
-            selected = mTargetCombo.getItem(index);
-        }
-
-        mCurrentTargets.clear();
-        mTargetCombo.removeAll();
-
-        boolean found = false;
-        index = -1;
-
-        SdkManager sdkManager = mAvdManager.getSdkManager();
-        if (sdkManager != null) {
-            for (IAndroidTarget target : sdkManager.getTargets()) {
-                String name;
-                if (target.isPlatform()) {
-                    name = String.format("%s - API Level %s",
-                            target.getName(),
-                            target.getVersion().getApiString());
-                } else {
-                    name = String.format("%s (%s) - API Level %s",
-                            target.getName(),
-                            target.getVendor(),
-                            target.getVersion().getApiString());
-                }
-                mCurrentTargets.put(name, target);
-                mTargetCombo.add(name);
-                if (!found) {
-                    index++;
-                    found = name.equals(selected);
-                }
-            }
-        }
-
-        mTargetCombo.setEnabled(mCurrentTargets.size() > 0);
-
-        if (found) {
-            mTargetCombo.select(index);
-        }
-
-        reloadSkinCombo();
-    }
-
-    private void reloadSkinCombo() {
-        String selected = null;
-        int index = mSkinCombo.getSelectionIndex();
-        if (index >= 0) {
-            selected = mSkinCombo.getItem(index);
-        }
-
-        mSkinCombo.removeAll();
-        mSkinCombo.setEnabled(false);
-
-        index = mTargetCombo.getSelectionIndex();
-        if (index >= 0) {
-
-            String targetName = mTargetCombo.getItem(index);
-
-            boolean found = false;
-            IAndroidTarget target = mCurrentTargets.get(targetName);
-            if (target != null) {
-                mSkinCombo.add(String.format("Default (%s)", target.getDefaultSkin()));
-
-                index = -1;
-                for (String skin : target.getSkins()) {
-                    mSkinCombo.add(skin);
-                    if (!found) {
-                        index++;
-                        found = skin.equals(selected);
-                    }
-                }
-
-                mSkinCombo.setEnabled(true);
-
-                if (found) {
-                    mSkinCombo.select(index);
-                } else {
-                    mSkinCombo.select(0);  // default
-                    loadSkin();
-                }
-            }
-        }
-    }
-
-    /**
-     * Validates the fields, displays errors and warnings.
-     * Enables the finish button if there are no errors.
-     */
-    private void validatePage() {
-        String error = null;
-
-        // Validate AVD name
-        String avdName = mAvdName.getText().trim();
-        boolean hasAvdName = avdName.length() > 0;
-        if (hasAvdName && !AvdManager.RE_AVD_NAME.matcher(avdName).matches()) {
-            error = String.format(
-                "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
-                avdName, AvdManager.CHARS_AVD_NAME);
-        }
-
-        // Validate target
-        if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() < 0) {
-            error = "A target must be selected in order to create an AVD.";
-        }
-
-        // Validate SDCard path or value
-        if (error == null) {
-            // get the mode. We only need to check the file since the
-            // verifier on the size Text will prevent invalid input
-            boolean sdcardFileMode = mSdCardFileRadio.getSelection();
-            if (sdcardFileMode) {
-                String sdName = mSdCardFile.getText().trim();
-                if (sdName.length() > 0 && !new File(sdName).isFile()) {
-                    error = "SD Card path isn't valid.";
-                }
-            }
-        }
-
-        // validate the skin
-        if (error == null) {
-            // get the mode, we should only check if it's in size mode since
-            // the built-in list mode is always valid.
-            if (mSkinSizeRadio.getSelection()) {
-                // need both with and heigh to be non null
-                String width = mSkinSizeWidth.getText();   // no need for trim, since the verifier
-                String height = mSkinSizeHeight.getText(); // rejects non digit.
-
-                if (width.length() == 0 || height.length() == 0) {
-                    error = "Skin size is incorrect.\nBoth dimensions must be > 0";
-                }
-            }
-        }
-
-        // Check for duplicate AVD name
-        if (hasAvdName && error == null) {
-            AvdInfo avdMatch = mAvdManager.getAvd(avdName, false /*validAvdOnly*/);
-            if (avdMatch != null && !mForceCreation.getSelection()) {
-                error = String.format(
-                        "The AVD name '%s' is already used.\n" +
-                        "Check \"Force create\" to override existing AVD.",
-                        avdName);
-            }
-        }
-
-        // Validate the create button
-        boolean can_create = hasAvdName && error == null;
-        if (can_create) {
-            can_create &= mTargetCombo.getSelectionIndex() >= 0;
-        }
-        mOkButton.setEnabled(can_create);
-
-        // -- update UI
-        if (error != null) {
-            mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png"));
-            mStatusLabel.setText(error);
-        } else {
-            mStatusIcon.setImage(null);
-            mStatusLabel.setText(" \n "); //$NON-NLS-1$
-        }
-
-        mStatusComposite.pack(true);
-    }
-
-    private void loadSkin() {
-        int targetIndex = mTargetCombo.getSelectionIndex();
-        if (targetIndex < 0) {
-            return;
-        }
-
-        // resolve the target.
-        String targetName = mTargetCombo.getItem(targetIndex);
-        IAndroidTarget target = mCurrentTargets.get(targetName);
-        if (target == null) {
-            return;
-        }
-
-        // get the skin name
-        String skinName = null;
-        int skinIndex = mSkinCombo.getSelectionIndex();
-        if (skinIndex < 0) {
-            return;
-        } else if (skinIndex == 0) { // default skin for the target
-            skinName = target.getDefaultSkin();
-        } else {
-            skinName = mSkinCombo.getItem(skinIndex);
-        }
-
-        // load the skin properties
-        String path = target.getPath(IAndroidTarget.SKINS);
-        File skin = new File(path, skinName);
-        if (skin.isDirectory() == false && target.isPlatform() == false) {
-            // it's possible the skin is in the parent target
-            path = target.getParent().getPath(IAndroidTarget.SKINS);
-            skin = new File(path, skinName);
-        }
-
-        if (skin.isDirectory() == false) {
-            return;
-        }
-
-        // now get the hardware.ini from the add-on (if applicable) and from the skin
-        // (if applicable)
-        HashMap<String, String> hardwareValues = new HashMap<String, String>();
-        if (target.isPlatform() == false) {
-            File targetHardwareFile = new File(target.getLocation(), AvdManager.HARDWARE_INI);
-            if (targetHardwareFile.isFile()) {
-                Map<String, String> targetHardwareConfig = SdkManager.parsePropertyFile(
-                        targetHardwareFile, null /*log*/);
-                if (targetHardwareConfig != null) {
-                    hardwareValues.putAll(targetHardwareConfig);
-                }
-            }
-        }
-
-        // from the skin
-        File skinHardwareFile = new File(skin, AvdManager.HARDWARE_INI);
-        if (skinHardwareFile.isFile()) {
-            Map<String, String> skinHardwareConfig = SdkManager.parsePropertyFile(
-                    skinHardwareFile, null /*log*/);
-            if (skinHardwareConfig != null) {
-                hardwareValues.putAll(skinHardwareConfig);
-            }
-        }
-
-        // now set those values in the list of properties for the AVD.
-        // We just check that none of those properties have been edited by the user yet.
-        for (Entry<String, String> entry : hardwareValues.entrySet()) {
-            if (mEditedProperties.contains(entry.getKey()) == false) {
-                mProperties.put(entry.getKey(), entry.getValue());
-            }
-        }
-
-        mHardwareViewer.refresh();
-    }
-
-    /**
-     * Creates an AVD from the values in the UI. Called when the user presses the OK button.
-     */
-    private boolean createAvd() {
-        String avdName = mAvdName.getText().trim();
-        int targetIndex = mTargetCombo.getSelectionIndex();
-
-        // quick check on the name and the target selection
-        if (avdName.length() == 0 || targetIndex < 0) {
-            return false;
-        }
-
-        // resolve the target.
-        String targetName = mTargetCombo.getItem(targetIndex);
-        IAndroidTarget target = mCurrentTargets.get(targetName);
-        if (target == null) {
-            return false;
-        }
-
-        // get the SD card data from the UI.
-        String sdName = null;
-        if (mSdCardSizeRadio.getSelection()) {
-            // size mode
-            String value = mSdCardSize.getText().trim();
-            if (value.length() > 0) {
-                sdName = value;
-                // add the unit
-                switch (mSdCardSizeCombo.getSelectionIndex()) {
-                    case 0:
-                        sdName += "K";
-                        break;
-                    case 1:
-                        sdName += "M";
-                        break;
-                    default:
-                        // shouldn't be here
-                        assert false;
-                }
-            }
-        } else {
-            // file mode.
-            sdName = mSdCardFile.getText().trim();
-        }
-
-        // get the Skin data from the UI
-        String skinName = null;
-        if (mSkinListRadio.getSelection()) {
-            // built-in list provides the skin
-            int skinIndex = mSkinCombo.getSelectionIndex();
-            if (skinIndex > 0) {
-                // index 0 is the default, we don't use it
-                skinName = mSkinCombo.getItem(skinIndex);
-            }
-        } else {
-            // size mode. get both size and writes it as a skin name
-            // thanks to validatePage() we know the content of the fields is correct
-            skinName = mSkinSizeWidth.getText() + "x" + mSkinSizeHeight.getText(); //$NON-NLS-1$
-        }
-
-        SdkLog log = new SdkLog(String.format("Result of creating AVD '%s':", avdName),
-                getContents().getDisplay());
-
-        File avdFolder;
-        try {
-            avdFolder = new File(
-                    AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
-                    avdName + AvdManager.AVD_FOLDER_EXTENSION);
-        } catch (AndroidLocationException e) {
-            return false;
-        }
-
-        boolean force = mForceCreation.getSelection();
-
-        boolean success = false;
-        AvdInfo avdInfo = mAvdManager.createAvd(
-                avdFolder,
-                avdName,
-                target,
-                skinName,
-                sdName,
-                mProperties,
-                force,
-                log);
-
-        success = avdInfo != null;
-
-        log.displayResult(success);
-        return success;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java
deleted file mode 100644
index a845056..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.widgets;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Dialog displaying the details of an AVD.
- */
-final class AvdDetailsDialog extends Dialog {
-
-    /** Last dialog size for this session. */
-    private static Point sLastSize;
-
-    private Shell mDialogShell;
-    private final AvdInfo mAvdInfo;
-
-    private Composite mRootComposite;
-
-    public AvdDetailsDialog(Shell shell, AvdInfo avdInfo) {
-        super(shell, SWT.APPLICATION_MODAL);
-        mAvdInfo = avdInfo;
-
-        setText("AVD details");
-    }
-
-    /**
-     * Open the dialog and blocks till it gets closed
-     */
-    public void open() {
-        createContents();
-        positionShell();            //$hide$ (hide from SWT designer)
-        mDialogShell.open();
-        mDialogShell.layout();
-
-        Display display = getParent().getDisplay();
-        while (!mDialogShell.isDisposed()) {
-            if (!display.readAndDispatch()) {
-                display.sleep();
-            }
-        }
-
-        if (!mDialogShell.isDisposed()) {
-            sLastSize = mDialogShell.getSize();
-            mDialogShell.close();
-        }
-    }
-
-    /**
-     * Create contents of the dialog.
-     */
-    private void createContents() {
-        mDialogShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE);
-        mDialogShell.setLayout(new GridLayout(1, false));
-        mDialogShell.setSize(450, 300);
-        mDialogShell.setText(getText());
-
-        mRootComposite = new Composite(mDialogShell, SWT.NONE);
-        mRootComposite.setLayout(new GridLayout(2, false));
-        mRootComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        GridLayout gl;
-
-        Composite c = new Composite(mRootComposite, SWT.NONE);
-        c.setLayout(gl = new GridLayout(2, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        if (mAvdInfo != null) {
-            displayValue(c, "Name:", mAvdInfo.getName());
-            displayValue(c, "Path:", mAvdInfo.getPath());
-
-            if (mAvdInfo.getStatus() != AvdStatus.OK) {
-                displayValue(c, "Error:", mAvdInfo.getErrorMessage());
-            } else {
-                IAndroidTarget target = mAvdInfo.getTarget();
-                AndroidVersion version = target.getVersion();
-                displayValue(c, "Target:", String.format("%s (API level %s)",
-                        target.getName(), version.getApiString()));
-
-                // display some extra values.
-                Map<String, String> properties = mAvdInfo.getProperties();
-                if (properties != null) {
-                    String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME);
-                    if (skin != null) {
-                        displayValue(c, "Skin:", skin);
-                    }
-
-                    String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE);
-                    if (sdcard == null) {
-                        sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
-                    }
-                    if (sdcard != null) {
-                        displayValue(c, "SD Card:", sdcard);
-                    }
-
-                    // display other hardware
-                    HashMap<String, String> copy = new HashMap<String, String>(properties);
-                    // remove stuff we already displayed (or that we don't want to display)
-                    copy.remove(AvdManager.AVD_INI_SKIN_NAME);
-                    copy.remove(AvdManager.AVD_INI_SKIN_PATH);
-                    copy.remove(AvdManager.AVD_INI_SDCARD_SIZE);
-                    copy.remove(AvdManager.AVD_INI_SDCARD_PATH);
-                    copy.remove(AvdManager.AVD_INI_IMAGES_1);
-                    copy.remove(AvdManager.AVD_INI_IMAGES_2);
-
-                    if (copy.size() > 0) {
-                        Label l = new Label(mRootComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
-                        l.setLayoutData(new GridData(
-                                GridData.FILL, GridData.CENTER, false, false, 2, 1));
-
-                        c = new Composite(mRootComposite, SWT.NONE);
-                        c.setLayout(gl = new GridLayout(2, false));
-                        gl.marginHeight = gl.marginWidth = 0;
-                        c.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-                        Set<String> keys = copy.keySet();
-                        for (String key : keys) {
-                            displayValue(c, key + ":", copy.get(key));
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    // -- Start of internal part ----------
-    // Hide everything down-below from SWT designer
-    //$hide>>$
-
-    /**
-     * Displays a value with a label.
-     *
-     * @param parent the parent Composite in which to display the value. This Composite must use a
-     * {@link GridLayout} with 2 columns.
-     * @param label the label of the value to display.
-     * @param value the string value to display.
-     */
-    private void displayValue(Composite parent, String label, String value) {
-        Label l = new Label(parent, SWT.NONE);
-        l.setText(label);
-        l.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
-
-        l = new Label(parent, SWT.NONE);
-        l.setText(value);
-        l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
-    }
-
-    /**
-     * Centers the dialog in its parent shell.
-     */
-    private void positionShell() {
-        // Centers the dialog in its parent shell
-        Shell child = mDialogShell;
-        Shell parent = getParent();
-        if (child != null && parent != null) {
-
-            // get the parent client area with a location relative to the display
-            Rectangle parentArea = parent.getClientArea();
-            Point parentLoc = parent.getLocation();
-            int px = parentLoc.x;
-            int py = parentLoc.y;
-            int pw = parentArea.width;
-            int ph = parentArea.height;
-
-            // Reuse the last size if there's one, otherwise use the default
-            Point childSize = sLastSize != null ? sLastSize : child.getSize();
-            int cw = childSize.x;
-            int ch = childSize.y;
-
-            child.setLocation(px + (pw - cw) / 2, py + (ph - ch) / 2);
-            child.setSize(cw, ch);
-        }
-    }
-
-    // End of hiding from SWT Designer
-    //$hide<<$
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java
deleted file mode 100644
index 5338717..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.widgets;
-
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.NullSdkLog;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus;
-import com.android.sdklib.internal.repository.ITask;
-import com.android.sdklib.internal.repository.ITaskMonitor;
-import com.android.sdkuilib.internal.repository.SettingsController;
-import com.android.sdkuilib.internal.repository.icons.ImageFactory;
-import com.android.sdkuilib.internal.tasks.ProgressTask;
-import com.android.sdkuilib.repository.UpdaterWindow;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-
-
-/**
- * The AVD selector is a table that is added to the given parent composite.
- * <p/>
- * After using one of the constructors, call {@link #setSelection(AvdInfo)},
- * {@link #setSelectionListener(SelectionListener)} and finally use
- * {@link #getSelected()} to retrieve the selection.
- */
-public final class AvdSelector {
-    private static int NUM_COL = 2;
-
-    private final DisplayMode mDisplayMode;
-
-    private AvdManager mAvdManager;
-    private final String mOsSdkPath;
-
-    private Table mTable;
-    private Button mDeleteButton;
-    private Button mDetailsButton;
-    private Button mNewButton;
-    private Button mRefreshButton;
-    private Button mManagerButton;
-    private Button mRepairButton;
-    private Button mStartButton;
-
-    private SelectionListener mSelectionListener;
-    private IAvdFilter mTargetFilter;
-
-    /** Defaults to true. Changed by the {@link #setEnabled(boolean)} method to represent the
-     * "global" enabled state on this composite. */
-    private boolean mIsEnabled = true;
-
-    private ImageFactory mImageFactory;
-    private Image mOkImage;
-    private Image mBrokenImage;
-
-    private SettingsController mController;
-
-
-    /**
-     * The display mode of the AVD Selector.
-     */
-    public static enum DisplayMode {
-        /**
-         * Manager mode. Invalid AVDs are displayed. Buttons to create/delete AVDs
-         */
-        MANAGER,
-
-        /**
-         * Non manager mode. Only valid AVDs are displayed. Cannot create/delete AVDs, but
-         * there is a button to open the AVD Manager.
-         * In the "check" selection mode, checkboxes are displayed on each line
-         * and {@link AvdSelector#getSelected()} returns the line that is checked
-         * even if it is not the currently selected line. Only one line can
-         * be checked at once.
-         */
-        SIMPLE_CHECK,
-
-        /**
-         * Non manager mode. Only valid AVDs are displayed. Cannot create/delete AVDs, but
-         * there is a button to open the AVD Manager.
-         * In the "select" selection mode, there are no checkboxes and
-         * {@link AvdSelector#getSelected()} returns the line currently selected.
-         * Only one line can be selected at once.
-         */
-        SIMPLE_SELECTION,
-    }
-
-    /**
-     * A filter to control the whether or not an AVD should be displayed by the AVD Selector.
-     */
-    public interface IAvdFilter {
-        /**
-         * Called before {@link #accept(AvdInfo)} is called for any AVD.
-         */
-        void prepare();
-
-        /**
-         * Called to decided whether an AVD should be displayed.
-         * @param avd the AVD to test.
-         * @return true if the AVD should be displayed.
-         */
-        boolean accept(AvdInfo avd);
-
-        /**
-         * Called after {@link #accept(AvdInfo)} has been called on all the AVDs.
-         */
-        void cleanup();
-    }
-
-    /**
-     * Internal implementation of {@link IAvdFilter} to filter out the AVDs that are not
-     * running an image compatible with a specific target.
-     */
-    private final static class TargetBasedFilter implements IAvdFilter {
-        private final IAndroidTarget mTarget;
-
-        TargetBasedFilter(IAndroidTarget target) {
-            mTarget = target;
-        }
-
-        public void prepare() {
-            // nothing to prepare
-        }
-
-        public boolean accept(AvdInfo avd) {
-            if (avd != null) {
-                return mTarget.isCompatibleBaseFor(avd.getTarget());
-            }
-
-            return false;
-        }
-
-        public void cleanup() {
-            // nothing to clean up
-        }
-    }
-
-    /**
-     * Creates a new SDK Target Selector, and fills it with a list of {@link AvdInfo}, filtered
-     * by a {@link IAndroidTarget}.
-     * <p/>Only the {@link AvdInfo} able to run application developed for the given
-     * {@link IAndroidTarget} will be displayed.
-     *
-     * @param parent The parent composite where the selector will be added.
-     * @param osSdkPath The SDK root path. When not null, enables the start button to start
-     *                  an emulator on a given AVD.
-     * @param manager the AVD manager.
-     * @param filter When non-null, will allow filtering the AVDs to display.
-     * @param displayMode The display mode ({@link DisplayMode}).
-     *
-     * TODO: pass an ISdkLog and use it when reloading, starting the emulator, etc.
-     */
-    public AvdSelector(Composite parent,
-            String osSdkPath,
-            AvdManager manager,
-            IAvdFilter filter,
-            DisplayMode displayMode) {
-        mOsSdkPath = osSdkPath;
-        mAvdManager = manager;
-        mTargetFilter = filter;
-        mDisplayMode = displayMode;
-
-        // get some bitmaps.
-        mImageFactory = new ImageFactory(parent.getDisplay());
-        mOkImage = mImageFactory.getImageByName("accept_icon16.png");
-        mBrokenImage = mImageFactory.getImageByName("reject_icon16.png");
-
-        // Layout has 2 columns
-        Composite group = new Composite(parent, SWT.NONE);
-        GridLayout gl;
-        group.setLayout(gl = new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/));
-        gl.marginHeight = gl.marginWidth = 0;
-        group.setLayoutData(new GridData(GridData.FILL_BOTH));
-        group.setFont(parent.getFont());
-        group.addDisposeListener(new DisposeListener() {
-            public void widgetDisposed(DisposeEvent arg0) {
-                mImageFactory.dispose();
-            }
-        });
-
-        int style = SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER;
-        if (displayMode == DisplayMode.SIMPLE_CHECK) {
-            style |= SWT.CHECK;
-        }
-        mTable = new Table(group, style);
-        mTable.setHeaderVisible(true);
-        mTable.setLinesVisible(false);
-        setTableHeightHint(0);
-
-        Composite buttons = new Composite(group, SWT.NONE);
-        buttons.setLayout(gl = new GridLayout(1, false /*makeColumnsEqualWidth*/));
-        gl.marginHeight = gl.marginWidth = 0;
-        buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-        buttons.setFont(group.getFont());
-
-        if (displayMode == DisplayMode.MANAGER) {
-            mNewButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-            mNewButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mNewButton.setText("New...");
-            mNewButton.setToolTipText("Creates a new AVD.");
-            mNewButton.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent arg0) {
-                    onNew();
-                }
-            });
-
-            mDeleteButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-            mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mDeleteButton.setText("Delete...");
-            mDeleteButton.setToolTipText("Deletes the selected AVD.");
-            mDeleteButton.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent arg0) {
-                    onDelete();
-                }
-            });
-
-            mRepairButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-            mRepairButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mRepairButton.setText("Repair...");
-            mRepairButton.setToolTipText("Repairs the selected AVD.");
-            mRepairButton.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent arg0) {
-                    onRepair();
-                }
-            });
-
-            Label l = new Label(buttons, SWT.SEPARATOR | SWT.HORIZONTAL);
-            l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        }
-
-        mDetailsButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-        mDetailsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mDetailsButton.setText("Details...");
-        mDetailsButton.setToolTipText("Diplays details of the selected AVD.");
-        mDetailsButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                onDetails();
-            }
-        });
-
-        mStartButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-        mStartButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mStartButton.setText("Start...");
-        mStartButton.setToolTipText("Starts the selected AVD.");
-        mStartButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                onStart();
-            }
-        });
-
-        Composite padding = new Composite(buttons, SWT.NONE);
-        padding.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-
-        mRefreshButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-        mRefreshButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mRefreshButton.setText("Refresh");
-        mRefreshButton.setToolTipText("Reloads the list of AVD.\nUse this if you create AVDs from the command line.");
-        mRefreshButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                refresh(true);
-            }
-        });
-
-        if (displayMode != DisplayMode.MANAGER) {
-            mManagerButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
-            mManagerButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-            mManagerButton.setText("Manager...");
-            mManagerButton.setToolTipText("Launches the AVD manager.");
-            mManagerButton.addSelectionListener(new SelectionAdapter() {
-                @Override
-                public void widgetSelected(SelectionEvent e) {
-                    onManager();
-                }
-            });
-        } else {
-            Composite legend = new Composite(group, SWT.NONE);
-            legend.setLayout(gl = new GridLayout(2, false /*makeColumnsEqualWidth*/));
-            gl.marginHeight = gl.marginWidth = 0;
-            legend.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false,
-                    NUM_COL, 1));
-            legend.setFont(group.getFont());
-
-            new Label(legend, SWT.NONE).setImage(mOkImage);
-            new Label(legend, SWT.NONE).setText("A valid Android Virtual Device.");
-            new Label(legend, SWT.NONE).setImage(mBrokenImage);
-            new Label(legend, SWT.NONE).setText(
-                    "An Android Virtual Device that failed to load. Click 'Details' to see the error.");
-        }
-
-        // create the table columns
-        final TableColumn column0 = new TableColumn(mTable, SWT.NONE);
-        column0.setText("AVD Name");
-        final TableColumn column1 = new TableColumn(mTable, SWT.NONE);
-        column1.setText("Target Name");
-        final TableColumn column2 = new TableColumn(mTable, SWT.NONE);
-        column2.setText("Platform");
-        final TableColumn column3 = new TableColumn(mTable, SWT.NONE);
-        column3.setText("API Level");
-
-        adjustColumnsWidth(mTable, column0, column1, column2, column3);
-        setupSelectionListener(mTable);
-        fillTable(mTable);
-    }
-
-    /**
-     * Creates a new SDK Target Selector, and fills it with a list of {@link AvdInfo}.
-     *
-     * @param parent The parent composite where the selector will be added.
-     * @param manager the AVD manager.
-     * @param displayMode The display mode ({@link DisplayMode}).
-     */
-    public AvdSelector(Composite parent,
-            String osSdkPath,
-            AvdManager manager,
-            DisplayMode displayMode) {
-        this(parent, osSdkPath, manager, (IAvdFilter)null /* filter */, displayMode);
-    }
-
-    /**
-     * Creates a new SDK Target Selector, and fills it with a list of {@link AvdInfo}, filtered
-     * by an {@link IAndroidTarget}.
-     * <p/>Only the {@link AvdInfo} able to run applications developed for the given
-     * {@link IAndroidTarget} will be displayed.
-     *
-     * @param parent The parent composite where the selector will be added.
-     * @param manager the AVD manager.
-     * @param filter Only shows the AVDs matching this target (must not be null).
-     * @param displayMode The display mode ({@link DisplayMode}).
-     */
-    public AvdSelector(Composite parent,
-            String osSdkPath,
-            AvdManager manager,
-            IAndroidTarget filter,
-            DisplayMode displayMode) {
-        this(parent, osSdkPath, manager, new TargetBasedFilter(filter), displayMode);
-    }
-
-    /**
-     * Sets an optional SettingsController.
-     * @param controller the controller.
-     */
-    public void setSettingsController(SettingsController controller) {
-        mController = controller;
-    }
-    /**
-     * Sets the table grid layout data.
-     *
-     * @param heightHint If > 0, the height hint is set to the requested value.
-     */
-    public void setTableHeightHint(int heightHint) {
-        GridData data = new GridData();
-        if (heightHint > 0) {
-            data.heightHint = heightHint;
-        }
-        data.grabExcessVerticalSpace = true;
-        data.grabExcessHorizontalSpace = true;
-        data.horizontalAlignment = GridData.FILL;
-        data.verticalAlignment = GridData.FILL;
-        mTable.setLayoutData(data);
-    }
-
-    /**
-     * Refresh the display of Android Virtual Devices.
-     * Tries to keep the selection.
-     * <p/>
-     * This must be called from the UI thread.
-     *
-     * @param reload if true, the AVD manager will reload the AVD from the disk.
-     * @return false if the reloading failed. This is always true if <var>reload</var> is
-     * <code>false</code>.
-     */
-    public boolean refresh(boolean reload) {
-        if (reload) {
-            try {
-                mAvdManager.reloadAvds(NullSdkLog.getLogger());
-            } catch (AndroidLocationException e) {
-                return false;
-            }
-        }
-
-        AvdInfo selected = getSelected();
-
-        fillTable(mTable);
-
-        setSelection(selected);
-
-        return true;
-    }
-
-    /**
-     * Sets a new AVD manager
-     * This does not refresh the display. Call {@link #refresh(boolean)} to do so.
-     * @param manager the AVD manager.
-     */
-    public void setManager(AvdManager manager) {
-        mAvdManager = manager;
-    }
-
-    /**
-     * Sets a new AVD filter.
-     * This does not refresh the display. Call {@link #refresh(boolean)} to do so.
-     * @param filter An IAvdFilter. If non-null, this will filter out the AVD to not display.
-     */
-    public void setFilter(IAvdFilter filter) {
-        mTargetFilter = filter;
-    }
-
-    /**
-     * Sets a new Android Target-based AVD filter.
-     * This does not refresh the display. Call {@link #refresh(boolean)} to do so.
-     * @param target An IAndroidTarget. If non-null, only AVD whose target are compatible with the
-     * filter target will displayed an available for selection.
-     */
-    public void setFilter(IAndroidTarget target) {
-        if (target != null) {
-            mTargetFilter = new TargetBasedFilter(target);
-        } else {
-            mTargetFilter = null;
-        }
-    }
-
-    /**
-     * Sets a selection listener. Set it to null to remove it.
-     * The listener will be called <em>after</em> this table processed its selection
-     * events so that the caller can see the updated state.
-     * <p/>
-     * The event's item contains a {@link TableItem}.
-     * The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
-     * <p/>
-     * It is recommended that the caller uses the {@link #getSelected()} method instead.
-     * <p/>
-     * The default behavior for double click (when not in {@link DisplayMode#SIMPLE_CHECK}) is to
-     * display the details of the selected AVD.<br>
-     * To disable it (when you provide your own double click action), set
-     * {@link SelectionEvent#doit} to false in
-     * {@link SelectionListener#widgetDefaultSelected(SelectionEvent)}
-     *
-     * @param selectionListener The new listener or null to remove it.
-     */
-    public void setSelectionListener(SelectionListener selectionListener) {
-        mSelectionListener = selectionListener;
-    }
-
-    /**
-     * Sets the current target selection.
-     * <p/>
-     * If the selection is actually changed, this will invoke the selection listener
-     * (if any) with a null event.
-     *
-     * @param target the target to be selected. Use null to deselect everything.
-     * @return true if the target could be selected, false otherwise.
-     */
-    public boolean setSelection(AvdInfo target) {
-        boolean found = false;
-        boolean modified = false;
-
-        int selIndex = mTable.getSelectionIndex();
-        int index = 0;
-        for (TableItem i : mTable.getItems()) {
-            if (mDisplayMode == DisplayMode.SIMPLE_CHECK) {
-                if ((AvdInfo) i.getData() == target) {
-                    found = true;
-                    if (!i.getChecked()) {
-                        modified = true;
-                        i.setChecked(true);
-                    }
-                } else if (i.getChecked()) {
-                    modified = true;
-                    i.setChecked(false);
-                }
-            } else {
-                if ((AvdInfo) i.getData() == target) {
-                    found = true;
-                    if (index != selIndex) {
-                        mTable.setSelection(index);
-                        modified = true;
-                    }
-                    break;
-                }
-
-                index++;
-            }
-        }
-
-        if (modified && mSelectionListener != null) {
-            mSelectionListener.widgetSelected(null);
-        }
-
-        enableActionButtons();
-
-        return found;
-    }
-
-    /**
-     * Returns the currently selected item. In {@link DisplayMode#SIMPLE_CHECK} mode this will
-     * return the {@link AvdInfo} that is checked instead of the list selection.
-     *
-     * @return The currently selected item or null.
-     */
-    public AvdInfo getSelected() {
-        if (mDisplayMode == DisplayMode.SIMPLE_CHECK) {
-            for (TableItem i : mTable.getItems()) {
-                if (i.getChecked()) {
-                    return (AvdInfo) i.getData();
-                }
-            }
-        } else {
-            int selIndex = mTable.getSelectionIndex();
-            if (selIndex >= 0) {
-                return (AvdInfo) mTable.getItem(selIndex).getData();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Enables the receiver if the argument is true, and disables it otherwise.
-     * A disabled control is typically not selectable from the user interface
-     * and draws with an inactive or "grayed" look.
-     *
-     * @param enabled the new enabled state.
-     */
-    public void setEnabled(boolean enabled) {
-        mIsEnabled = enabled;
-
-        mTable.setEnabled(mIsEnabled);
-        mRefreshButton.setEnabled(mIsEnabled);
-
-        if (mNewButton != null) {
-            mNewButton.setEnabled(mIsEnabled);
-        }
-        if (mManagerButton != null) {
-            mManagerButton.setEnabled(mIsEnabled);
-        }
-
-        enableActionButtons();
-    }
-
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    /**
-     * Adds a listener to adjust the columns width when the parent is resized.
-     * <p/>
-     * If we need something more fancy, we might want to use this:
-     * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
-     */
-    private void adjustColumnsWidth(final Table table,
-            final TableColumn column0,
-            final TableColumn column1,
-            final TableColumn column2,
-            final TableColumn column3) {
-        // Add a listener to resize the column to the full width of the table
-        table.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Rectangle r = table.getClientArea();
-                column0.setWidth(r.width * 25 / 100); // 25%
-                column1.setWidth(r.width * 45 / 100); // 45%
-                column2.setWidth(r.width * 15 / 100); // 15%
-                column3.setWidth(r.width * 15 / 100); // 15%
-            }
-        });
-    }
-
-    /**
-     * Creates a selection listener that will check or uncheck the whole line when
-     * double-clicked (aka "the default selection").
-     */
-    private void setupSelectionListener(final Table table) {
-        // Add a selection listener that will check/uncheck items when they are double-clicked
-        table.addSelectionListener(new SelectionListener() {
-
-            /**
-             * Handles single-click selection on the table.
-             * {@inheritDoc}
-             */
-            public void widgetSelected(SelectionEvent e) {
-                if (e.item instanceof TableItem) {
-                    TableItem i = (TableItem) e.item;
-                    enforceSingleSelection(i);
-                }
-
-                if (mSelectionListener != null) {
-                    mSelectionListener.widgetSelected(e);
-                }
-
-                enableActionButtons();
-            }
-
-            /**
-             * Handles double-click selection on the table.
-             * Note that the single-click handler will probably already have been called.
-             *
-             * On double-click, <em>always</em> check the table item.
-             *
-             * {@inheritDoc}
-             */
-            public void widgetDefaultSelected(SelectionEvent e) {
-                if (e.item instanceof TableItem) {
-                    TableItem i = (TableItem) e.item;
-                    if (mDisplayMode == DisplayMode.SIMPLE_CHECK) {
-                        i.setChecked(true);
-                    }
-                    enforceSingleSelection(i);
-
-                }
-
-                // whether or not we display details. default: true when not in SIMPLE_CHECK mode.
-                boolean showDetails = mDisplayMode != DisplayMode.SIMPLE_CHECK;
-
-                if (mSelectionListener != null) {
-                    mSelectionListener.widgetDefaultSelected(e);
-                    showDetails &= e.doit; // enforce false in SIMPLE_CHECK
-                }
-
-                if (showDetails) {
-                    onDetails();
-                }
-
-                enableActionButtons();
-            }
-
-            /**
-             * To ensure single selection, uncheck all other items when this one is selected.
-             * This makes the chekboxes act as radio buttons.
-             */
-            private void enforceSingleSelection(TableItem item) {
-                if (mDisplayMode == DisplayMode.SIMPLE_CHECK) {
-                    if (item.getChecked()) {
-                        Table parentTable = item.getParent();
-                        for (TableItem i2 : parentTable.getItems()) {
-                            if (i2 != item && i2.getChecked()) {
-                                i2.setChecked(false);
-                            }
-                        }
-                    }
-                } else {
-                    // pass
-                }
-            }
-        });
-    }
-
-    /**
-     * Fills the table with all AVD.
-     * The table columns are:
-     * <ul>
-     * <li>column 0: sdk name
-     * <li>column 1: sdk vendor
-     * <li>column 2: sdk api name
-     * <li>column 3: sdk version
-     * </ul>
-     */
-    private void fillTable(final Table table) {
-        table.removeAll();
-
-        // get the AVDs
-        AvdInfo avds[] = null;
-        if (mAvdManager != null) {
-            if (mDisplayMode == DisplayMode.MANAGER) {
-                avds = mAvdManager.getAllAvds();
-            } else {
-                avds = mAvdManager.getValidAvds();
-            }
-        }
-
-        if (avds != null && avds.length > 0) {
-            table.setEnabled(true);
-
-            if (mTargetFilter != null) {
-                mTargetFilter.prepare();
-            }
-
-            for (AvdInfo avd : avds) {
-                if (mTargetFilter == null || mTargetFilter.accept(avd)) {
-                    TableItem item = new TableItem(table, SWT.NONE);
-                    item.setData(avd);
-                    item.setText(0, avd.getName());
-                    if (mDisplayMode == DisplayMode.MANAGER) {
-                        item.setImage(0, avd.getStatus() == AvdStatus.OK ? mOkImage : mBrokenImage);
-                    }
-                    IAndroidTarget target = avd.getTarget();
-                    if (target != null) {
-                        item.setText(1, target.getFullName());
-                        item.setText(2, target.getVersionName());
-                        item.setText(3, target.getVersion().getApiString());
-                    } else {
-                        item.setText(1, "?");
-                        item.setText(2, "?");
-                        item.setText(3, "?");
-                    }
-                }
-            }
-
-            if (mTargetFilter != null) {
-                mTargetFilter.cleanup();
-            }
-        }
-
-        if (table.getItemCount() == 0) {
-            table.setEnabled(false);
-            TableItem item = new TableItem(table, SWT.NONE);
-            item.setData(null);
-            item.setText(0, "--");
-            item.setText(1, "No AVD available");
-            item.setText(2, "--");
-            item.setText(3, "--");
-        }
-    }
-
-    /**
-     * Returns the currently selected AVD in the table.
-     * <p/>
-     * Unlike {@link #getSelected()} this will always return the item being selected
-     * in the list, ignoring the check boxes state in {@link DisplayMode#SIMPLE_CHECK} mode.
-     */
-    private AvdInfo getTableSelection() {
-        int selIndex = mTable.getSelectionIndex();
-        if (selIndex >= 0) {
-            return (AvdInfo) mTable.getItem(selIndex).getData();
-        }
-
-        return null;
-    }
-
-    /**
-     * Updates the enable state of the Details, Start, Delete and Update buttons.
-     */
-    private void enableActionButtons() {
-        if (mIsEnabled == false) {
-            mDetailsButton.setEnabled(false);
-            mStartButton.setEnabled(false);
-
-            if (mDeleteButton != null) {
-                mDeleteButton.setEnabled(false);
-            }
-            if (mRepairButton != null) {
-                mRepairButton.setEnabled(false);
-            }
-        } else {
-            AvdInfo selection = getTableSelection();
-            boolean hasSelection = selection != null;
-
-            mDetailsButton.setEnabled(hasSelection);
-            mStartButton.setEnabled(mOsSdkPath != null &&
-                    hasSelection &&
-                    selection.getStatus() == AvdStatus.OK);
-
-            if (mDeleteButton != null) {
-                mDeleteButton.setEnabled(hasSelection);
-            }
-            if (mRepairButton != null) {
-                mRepairButton.setEnabled(hasSelection &&
-                        selection.getStatus() == AvdStatus.ERROR_IMAGE_DIR);
-            }
-        }
-    }
-
-    private void onNew() {
-        AvdCreationDialog dlg = new AvdCreationDialog(mTable.getShell(), mAvdManager,
-                mImageFactory);
-        if (dlg.open() == Window.OK) {
-            refresh(false /*reload*/);
-        }
-    }
-
-    private void onDetails() {
-        final AvdInfo avdInfo = getTableSelection();
-
-        AvdDetailsDialog dlg = new AvdDetailsDialog(mTable.getShell(), avdInfo);
-        dlg.open();
-    }
-
-    private void onDelete() {
-        final AvdInfo avdInfo = getTableSelection();
-
-        // get the current Display
-        final Display display = mTable.getDisplay();
-
-        // Confirm you want to delete this AVD
-        final boolean[] result = new boolean[1];
-        display.syncExec(new Runnable() {
-            public void run() {
-                Shell shell = display.getActiveShell();
-                result[0] = MessageDialog.openQuestion(shell,
-                        "Delete Android Virtual Device",
-                        String.format(
-                                "Please confirm that you want to delete the Android Virtual Device named '%s'. This operation cannot be reverted.",
-                                avdInfo.getName()));
-            }
-        });
-
-        if (result[0] == false) {
-            return;
-        }
-
-        // log for this action.
-        SdkLog log = new SdkLog(
-                String.format("Result of deleting AVD '%s':", avdInfo.getName()),
-                display);
-
-        // delete the AVD
-        boolean success = mAvdManager.deleteAvd(avdInfo, log);
-
-        // display the result
-        log.displayResult(success);
-
-        if (success) {
-            refresh(false /*reload*/);
-        }
-    }
-
-    /**
-     * Repairs the selected AVD.
-     * <p/>
-     * For now this only supports fixing the wrong value in image.sysdir.*
-     */
-    private void onRepair() {
-        final AvdInfo avdInfo = getTableSelection();
-
-        // get the current Display
-        final Display display = mTable.getDisplay();
-
-        // log for this action.
-        SdkLog log = new SdkLog(
-                String.format("Result of updating AVD '%s':", avdInfo.getName()),
-                display);
-
-        // delete the AVD
-        try {
-            mAvdManager.updateAvd(avdInfo, log);
-
-            // display the result
-            log.displayResult(true /* success */);
-
-            refresh(false /*reload*/);
-        } catch (IOException e) {
-            log.error(e, null);
-            log.displayResult(false /* success */);
-        }
-    }
-
-    private void onManager() {
-        UpdaterWindow window = new UpdaterWindow(
-                mTable.getShell(),
-                null /*sdk log*/,
-                mAvdManager.getSdkManager().getLocation(),
-                false /*userCanChangeSdkRoot*/);
-        window.open();
-        refresh(true /*reload*/); // UpdaterWindow uses its own AVD manager so this one must reload.
-    }
-
-    private void onStart() {
-        AvdInfo avdInfo = getTableSelection();
-
-        if (avdInfo == null || mOsSdkPath == null) {
-            return;
-        }
-
-        AvdStartDialog dialog = new AvdStartDialog(mTable.getShell(), avdInfo, mOsSdkPath,
-                mController);
-        if (dialog.open() == Window.OK) {
-            String path = mOsSdkPath +
-                File.separator +
-                SdkConstants.OS_SDK_TOOLS_FOLDER +
-                SdkConstants.FN_EMULATOR;
-
-            final String avdName = avdInfo.getName();
-
-            // build the command line based on the available parameters.
-            ArrayList<String> list = new ArrayList<String>();
-            list.add(path);
-            list.add("-avd");                             //$NON-NLS-1$
-            list.add(avdName);
-            if (dialog.getWipeData()) {
-                list.add("-wipe-data");                   //$NON-NLS-1$
-            }
-            float scale = dialog.getScale();
-            if (scale != 0.f) {
-                // do the rounding ourselves. This is because %.1f will write .4899 as .4
-                scale = Math.round(scale * 100);
-                scale /=  100.f;
-                list.add("-scale");                       //$NON-NLS-1$
-                list.add(String.format("%.2f", scale));   //$NON-NLS-1$
-            }
-
-            // convert the list into an array for the call to exec.
-            final String[] command = list.toArray(new String[list.size()]);
-
-            // launch the emulator
-            new ProgressTask(mTable.getShell(),
-                    "Starting Android Emulator",
-                    new ITask() {
-                        public void run(ITaskMonitor monitor) {
-                            try {
-                                monitor.setDescription("Starting emulator for AVD '%1$s'",
-                                        avdName);
-                                int n = 10;
-                                monitor.setProgressMax(n);
-                                Process process = Runtime.getRuntime().exec(command);
-                                grabEmulatorOutput(process, monitor);
-
-                                // This small wait prevents the dialog from closing too fast:
-                                // When it works, the emulator returns immediately, even if
-                                // no UI is shown yet. And when it fails (because the AVD is
-                                // locked/running)
-                                // if we don't have a wait we don't capture the error for
-                                // some reason.
-                                for (int i = 0; i < n; i++) {
-                                    try {
-                                        Thread.sleep(100);
-                                        monitor.incProgress(1);
-                                    } catch (InterruptedException e) {
-                                        // ignore
-                                    }
-                                }
-                            } catch (IOException e) {
-                                monitor.setResult("Failed to start emulator: %1$s",
-                                        e.getMessage());
-                            }
-                        }
-            });
-        }
-    }
-
-    /**
-     * Get the stderr/stdout outputs of a process and return when the process is done.
-     * Both <b>must</b> be read or the process will block on windows.
-     * @param process The process to get the output from.
-     * @param monitor An {@link ISdkLog} to capture errors.
-     */
-    private void grabEmulatorOutput(final Process process, final ITaskMonitor monitor) {
-        // read the lines as they come. if null is returned, it's because the process finished
-        new Thread("emu-stderr") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                // create a buffer to read the stderr output
-                InputStreamReader is = new InputStreamReader(process.getErrorStream());
-                BufferedReader errReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = errReader.readLine();
-                        if (line != null) {
-                            monitor.setResult("%1$s", line);    //$NON-NLS-1$
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        }.start();
-
-        new Thread("emu-stdout") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                InputStreamReader is = new InputStreamReader(process.getInputStream());
-                BufferedReader outReader = new BufferedReader(is);
-
-                try {
-                    while (true) {
-                        String line = outReader.readLine();
-                        if (line != null) {
-                            monitor.setResult("%1$s", line);    //$NON-NLS-1$
-                        } else {
-                            break;
-                        }
-                    }
-                } catch (IOException e) {
-                    // do nothing.
-                }
-            }
-        }.start();
-    }
-
-    /**
-     * Collects all log from the AVD action and displays it in a dialog.
-     */
-    static class SdkLog implements ISdkLog {
-
-        final ArrayList<String> logMessages = new ArrayList<String>();
-        private final String mMessage;
-        private final Display mDisplay;
-
-        public SdkLog(String message, Display display) {
-            mMessage = message;
-            mDisplay = display;
-        }
-
-        public void error(Throwable throwable, String errorFormat, Object... arg) {
-            if (errorFormat != null) {
-                logMessages.add(String.format("Error: " + errorFormat, arg));
-            }
-
-            if (throwable != null) {
-                logMessages.add(throwable.getMessage());
-            }
-        }
-
-        public void warning(String warningFormat, Object... arg) {
-            logMessages.add(String.format("Warning: " + warningFormat, arg));
-        }
-
-        public void printf(String msgFormat, Object... arg) {
-            logMessages.add(String.format(msgFormat, arg));
-        }
-
-        /**
-         * Displays the log if anything was captured.
-         */
-        public void displayResult(final boolean success) {
-            if (logMessages.size() > 0) {
-                final StringBuilder sb = new StringBuilder(mMessage + "\n\n");
-                for (String msg : logMessages) {
-                    sb.append(msg);
-                }
-
-                // display the message
-                // dialog box only run in ui thread..
-                mDisplay.asyncExec(new Runnable() {
-                    public void run() {
-                        Shell shell = mDisplay.getActiveShell();
-                        if (success) {
-                            MessageDialog.openInformation(shell, "Android Virtual Devices Manager",
-                                    sb.toString());
-                        } else {
-                            MessageDialog.openError(shell, "Android Virtual Devices Manager",
-                                    sb.toString());
-
-                        }
-                    }
-                });
-            }
-        }
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdStartDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdStartDialog.java
deleted file mode 100644
index 720ee12..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdStartDialog.java
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.widgets;
-
-import com.android.sdklib.internal.avd.AvdManager;
-import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
-import com.android.sdkuilib.internal.repository.SettingsController;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.awt.Toolkit;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Dialog dealing with emulator launch options. The following options are supported:
- * <ul>
- * <li>-wipe-data</li>
- * <li>-scale</li>
- * </ul>
- *
- * Values are stored (in the class as static field) to be reused while the app is still running.
- * The Monitor dpi is stored in the settings if availabe.
- */
-final class AvdStartDialog extends GridDialog {
-    // static field to reuse values during the same session.
-    private static boolean sWipeData = false;
-    private static int sMonitorDpi = 72; // used if there's no setting controller.
-    private static final Map<String, String> sSkinScaling = new HashMap<String, String>();
-
-    private static final Pattern sScreenSizePattern = Pattern.compile("\\d*(\\.\\d?)?");
-
-    private final AvdInfo mAvd;
-    private final String mSdkLocation;
-    private final SettingsController mSettingsController;
-
-    private Text mScreenSize;
-    private Text mMonitorDpi;
-    private Button mScaleButton;
-
-    private float mScale = 0.f;
-    private boolean mWipeData = false;
-    private int mDensity = 160; // medium density
-    private int mSize1 = -1;
-    private int mSize2 = -1;
-    private String mSkinDisplay;
-    private boolean mEnableScaling = true;
-    private Label mScaleField;
-
-    AvdStartDialog(Shell parentShell, AvdInfo avd, String sdkLocation,
-            SettingsController settingsController) {
-        super(parentShell, 2, false);
-        mAvd = avd;
-        mSdkLocation = sdkLocation;
-        mSettingsController = settingsController;
-        if (mAvd == null) {
-            throw new IllegalArgumentException("avd cannot be null");
-        }
-        if (mSdkLocation == null) {
-            throw new IllegalArgumentException("sdkLocation cannot be null");
-        }
-
-        computeSkinData();
-    }
-
-    public boolean getWipeData() {
-        return mWipeData;
-    }
-
-    /**
-     * Returns the scaling factor, or 0.f if none are set.
-     */
-    public float getScale() {
-        return mScale;
-    }
-
-    @Override
-    public void createDialogContent(final Composite parent) {
-        GridData gd;
-
-        Label l = new Label(parent, SWT.NONE);
-        l.setText("Skin:");
-
-        l = new Label(parent, SWT.NONE);
-        l.setText(mSkinDisplay == null ? "None" : mSkinDisplay);
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        l = new Label(parent, SWT.NONE);
-        l.setText("Density:");
-
-        l = new Label(parent, SWT.NONE);
-        l.setText(getDensityText());
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        mScaleButton = new Button(parent, SWT.CHECK);
-        mScaleButton.setText("Scale display to real size");
-        mScaleButton.setEnabled(mEnableScaling);
-        boolean defaultState = mEnableScaling && sSkinScaling.get(mAvd.getName()) != null;
-        mScaleButton.setSelection(defaultState);
-        mScaleButton.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-        final Group scaleGroup = new Group(parent, SWT.NONE);
-        scaleGroup.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalIndent = 30;
-        gd.horizontalSpan = 2;
-        scaleGroup.setLayout(new GridLayout(3, false));
-
-        l = new Label(scaleGroup, SWT.NONE);
-        l.setText("Screen Size (in):");
-        mScreenSize = new Text(scaleGroup, SWT.BORDER);
-        mScreenSize.setText(getScreenSize());
-        mScreenSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mScreenSize.addVerifyListener(new VerifyListener() {
-            public void verifyText(VerifyEvent event) {
-                // combine the current content and the new text
-                String text = mScreenSize.getText();
-                text = text.substring(0, event.start) + event.text + text.substring(event.end);
-
-                // now make sure it's a match for the regex
-                event.doit = sScreenSizePattern.matcher(text).matches();
-            }
-        });
-        mScreenSize.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent event) {
-                onScaleChange();
-            }
-        });
-
-        // empty composite, only 2 widgets on this line.
-        new Composite(scaleGroup, SWT.NONE).setLayoutData(gd = new GridData());
-        gd.widthHint = gd.heightHint = 0;
-
-        l = new Label(scaleGroup, SWT.NONE);
-        l.setText("Monitor dpi:");
-        mMonitorDpi = new Text(scaleGroup, SWT.BORDER);
-        mMonitorDpi.setText(Integer.toString(getMonitorDpi()));
-        mMonitorDpi.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.widthHint = 50;
-        mMonitorDpi.addVerifyListener(new VerifyListener() {
-            public void verifyText(VerifyEvent event) {
-                // check for digit only.
-                for (int i = 0 ; i < event.text.length(); i++) {
-                    char letter = event.text.charAt(i);
-                    if (letter < '0' || letter > '9') {
-                        event.doit = false;
-                        return;
-                    }
-                }
-            }
-        });
-        mMonitorDpi.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent event) {
-                onScaleChange();
-            }
-        });
-
-        Button button = new Button(scaleGroup, SWT.PUSH | SWT.FLAT);
-        button.setText("?");
-        button.setToolTipText("Click to figure out your monitor's pixel density");
-        button.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                ResolutionChooserDialog dialog = new ResolutionChooserDialog(parent.getShell());
-                if (dialog.open() == Window.OK) {
-                    mMonitorDpi.setText(Integer.toString(dialog.getDensity()));
-                }
-            }
-        });
-
-        l = new Label(scaleGroup, SWT.NONE);
-        l.setText("Scale:");
-        mScaleField = new Label(scaleGroup, SWT.NONE);
-        mScaleField.setLayoutData(new GridData(GridData.FILL, GridData.CENTER,
-                true /*grabExcessHorizontalSpace*/,
-                true /*grabExcessVerticalSpace*/,
-                2 /*horizontalSpan*/,
-                1 /*verticalSpan*/));
-        setScale(mScale); // set initial text value
-
-        enableGroup(scaleGroup, defaultState);
-
-        mScaleButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent event) {
-                boolean enabled = mScaleButton.getSelection();
-                enableGroup(scaleGroup, enabled);
-                if (enabled) {
-                    onScaleChange();
-                } else {
-                    setScale(0);
-                }
-            }
-        });
-
-        final Button wipeButton = new Button(parent, SWT.CHECK);
-        wipeButton.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-        wipeButton.setText("Wipe user data");
-        wipeButton.setSelection(mWipeData = sWipeData);
-        wipeButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                mWipeData = wipeButton.getSelection();
-            }
-        });
-
-        l = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
-        l.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-        gd.horizontalSpan = 2;
-
-        // if the scaling is enabled by default, we must initialize the value of mScale
-        if (defaultState) {
-            onScaleChange();
-        }
-    }
-
-    /** On Windows we need to manually enable/disable the children of a group */
-    private void enableGroup(final Group group, boolean enabled) {
-        group.setEnabled(enabled);
-        for (Control c : group.getChildren()) {
-            c.setEnabled(enabled);
-        }
-    }
-
-    @Override
-    protected void configureShell(Shell newShell) {
-        super.configureShell(newShell);
-        newShell.setText("Launch Options");
-    }
-
-    @Override
-    protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
-        if (id == IDialogConstants.OK_ID) {
-            label = "Launch";
-        }
-
-        return super.createButton(parent, id, label, defaultButton);
-    }
-
-    @Override
-    protected void okPressed() {
-        // override ok to store some info
-        // first the monitor dpi
-        String dpi = mMonitorDpi.getText();
-        if (dpi.length() > 0) {
-            sMonitorDpi = Integer.parseInt(dpi);
-
-            // if there is a setting controller, save it
-            if (mSettingsController != null) {
-                mSettingsController.setMonitorDensity(sMonitorDpi);
-                mSettingsController.saveSettings();
-            }
-        }
-
-        // now the scale factor
-        String key = mAvd.getName();
-        sSkinScaling.remove(key);
-        if (mScaleButton.getSelection()) {
-            String size = mScreenSize.getText();
-            if (size.length() > 0) {
-                sSkinScaling.put(key, size);
-            }
-        }
-
-        // and then the wipe-data checkbox
-        sWipeData = mWipeData;
-
-        // finally continue with the ok action
-        super.okPressed();
-    }
-
-    private void computeSkinData() {
-        Map<String, String> prop = mAvd.getProperties();
-        String dpi = prop.get("hw.lcd.density");
-        if (dpi != null && dpi.length() > 0) {
-            mDensity  = Integer.parseInt(dpi);
-        }
-
-        findSkinResolution();
-    }
-
-    private void onScaleChange() {
-        String sizeStr = mScreenSize.getText();
-        if (sizeStr.length() == 0) {
-            setScale(0);
-            return;
-        }
-
-        String dpiStr = mMonitorDpi.getText();
-        if (dpiStr.length() == 0) {
-            setScale(0);
-            return;
-        }
-
-        int dpi = Integer.parseInt(dpiStr);
-        float size = Float.parseFloat(sizeStr);
-        /*
-         * We are trying to emulate the following device:
-         * resolution: 'mSize1'x'mSize2'
-         * density: 'mDensity'
-         * screen diagonal: 'size'
-         * ontop a monitor running at 'dpi'
-         */
-        // We start by computing the screen diagonal in pixels, if the density was really mDensity
-        float diagonalPx = (float)Math.sqrt(mSize1*mSize1+mSize2*mSize2);
-        // Now we would convert this in actual inches:
-        //    diagonalIn = diagonal / mDensity
-        // the scale factor is a mix of adapting to the new density and to the new size.
-        //    (size/diagonalIn) * (dpi/mDensity)
-        // this can be simplified to:
-        setScale((size * dpi) / diagonalPx);
-    }
-
-    private void setScale(float scale) {
-        mScale = scale;
-
-        // Do the rounding exactly like AvdSelector will do.
-        scale = Math.round(scale * 100);
-        scale /=  100.f;
-
-        if (scale == 0.f) {
-            mScaleField.setText("default");  //$NON-NLS-1$
-        } else {
-            mScaleField.setText(String.format("%.2f", scale));  //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Returns the monitor dpi to start with.
-     * This can be coming from the settings, the session-based storage, or the from whatever Java
-     * can tell us.
-     */
-    private int getMonitorDpi() {
-        if (mSettingsController != null) {
-            sMonitorDpi = mSettingsController.getMonitorDensity();
-        }
-
-        if (sMonitorDpi == -1) { // first time? try to get a value
-             sMonitorDpi = Toolkit.getDefaultToolkit().getScreenResolution();
-        }
-
-        return sMonitorDpi;
-    }
-
-    /**
-     * Returns the screen size to start with.
-     * <p/>If an emulator with the same skin was already launched, scaled, the size used is reused.
-     * <p/>Otherwise the default is returned (3)
-     */
-    private String getScreenSize() {
-        String size = sSkinScaling.get(mAvd.getName());
-        if (size != null) {
-            return size;
-        }
-
-        return "3";
-    }
-
-    /**
-     * Returns a display string for the density.
-     */
-    private String getDensityText() {
-        switch (mDensity) {
-            case 120:
-                return "Low (120)";
-            case 160:
-                return "Medium (160)";
-            case 240:
-                return "High (240)";
-        }
-
-        return Integer.toString(mDensity);
-    }
-
-    /**
-     * Finds the skin resolution and sets it in {@link #mSize1} and {@link #mSize2}.
-     */
-    private void findSkinResolution() {
-        Map<String, String> prop = mAvd.getProperties();
-        String skinName = prop.get(AvdManager.AVD_INI_SKIN_NAME);
-
-        if (skinName != null) {
-            Matcher m = AvdManager.NUMERIC_SKIN_SIZE.matcher(skinName);
-            if (m != null && m.matches()) {
-                mSize1 = Integer.parseInt(m.group(1));
-                mSize2 = Integer.parseInt(m.group(2));
-                mSkinDisplay = skinName;
-                mEnableScaling = true;
-                return;
-            }
-        }
-
-        // The resolution is inside the layout file of the skin.
-        mEnableScaling = false; // default to false for now.
-
-        // path to the skin layout file.
-        String skinPath = prop.get(AvdManager.AVD_INI_SKIN_PATH);
-        if (skinPath != null) {
-            File skinFolder = new File(mSdkLocation, skinPath);
-            if (skinFolder.isDirectory()) {
-                File layoutFile = new File(skinFolder, "layout");
-                if (layoutFile.isFile()) {
-                    if (parseLayoutFile(layoutFile)) {
-                        mSkinDisplay = String.format("%1$s (%2$dx%3$d)", skinName, mSize1, mSize2);
-                        mEnableScaling = true;
-                    } else {
-                        mSkinDisplay = skinName;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Parses a layout file.
-     * <p/>
-     * the format is relatively easy. It's a collection of items defined as
-     * &lg;name&gt; {
-     *     &lg;content&gt;
-     * }
-     *
-     * content is either 1+ items or 1+ properties
-     * properties are defined as
-     * &lg;name&gt;&lg;whitespace&gt;&lg;value&gt;
-     *
-     * We're going to look for an item called display, with 2 properties height and width.
-     * This is very basic parser.
-     *
-     * @param layoutFile the file to parse
-     * @return true if both sizes where found.
-     */
-    private boolean parseLayoutFile(File layoutFile) {
-        try {
-            BufferedReader input = new BufferedReader(new FileReader(layoutFile));
-            String line;
-
-            while ((line = input.readLine()) != null) {
-                // trim to remove whitespace
-                line = line.trim();
-                int len = line.length();
-                if (len == 0) continue;
-
-                // check if this is a new item
-                if (line.charAt(len-1) == '{') {
-                    // this is the start of a node
-                    String[] tokens = line.split(" ");
-                    if ("display".equals(tokens[0])) {
-                        // this is the one we're looking for!
-                        while ((mSize1 == -1 || mSize2 == -1) &&
-                                (line = input.readLine()) != null) {
-                            // trim to remove whitespace
-                            line = line.trim();
-                            len = line.length();
-                            if (len == 0) continue;
-
-                            if ("}".equals(line)) { // looks like we're done with the item.
-                                break;
-                            }
-
-                            tokens = line.split(" ");
-                            if (tokens.length >= 2) {
-                                // there can be multiple space between the name and value
-                                // in which case we'll get an extra empty token in the middle.
-                                if ("width".equals(tokens[0])) {
-                                    mSize1 = Integer.parseInt(tokens[tokens.length-1]);
-                                } else if ("height".equals(tokens[0])) {
-                                    mSize2 = Integer.parseInt(tokens[tokens.length-1]);
-                                }
-                            }
-                        }
-
-                        return mSize1 != -1 && mSize2 != -1;
-                    }
-                }
-
-            }
-            // if it reaches here, display was not found.
-            // false is returned below.
-        } catch (IOException e) {
-            // ignore.
-        }
-
-        return false;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/HardwarePropertyChooser.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/HardwarePropertyChooser.java
deleted file mode 100644
index 5184442..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/HardwarePropertyChooser.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.widgets;
-
-import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty;
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Dialog to choose a hardware property
- */
-class HardwarePropertyChooser extends GridDialog {
-
-    private final Map<String, HardwareProperty> mProperties;
-    private final Collection<String> mExceptProperties;
-    private HardwareProperty mChosenProperty;
-    private Label mTypeLabel;
-    private Label mDescriptionLabel;
-
-    HardwarePropertyChooser(Shell parentShell, Map<String, HardwareProperty> properties,
-            Collection<String> exceptProperties) {
-        super(parentShell, 2, false);
-        mProperties = properties;
-        mExceptProperties = exceptProperties;
-    }
-
-    public HardwareProperty getProperty() {
-        return mChosenProperty;
-    }
-
-    @Override
-    public void createDialogContent(Composite parent) {
-        Label l = new Label(parent, SWT.NONE);
-        l.setText("Property:");
-
-        final Combo c = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
-        // simple list for index->name resolution.
-        final ArrayList<String> indexToName = new ArrayList<String>();
-        for (Entry<String, HardwareProperty> entry : mProperties.entrySet()) {
-            if (mExceptProperties.contains(entry.getKey()) == false) {
-                c.add(entry.getValue().getAbstract());
-                indexToName.add(entry.getKey());
-            }
-        }
-        boolean hasValues = true;
-        if (indexToName.size() == 0) {
-            hasValues = false;
-            c.add("No properties");
-            c.select(0);
-            c.setEnabled(false);
-        }
-
-        c.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent event) {
-                int index = c.getSelectionIndex();
-                String name = indexToName.get(index);
-                processSelection(name, true /* pack */);
-            }
-        });
-
-        l = new Label(parent, SWT.NONE);
-        l.setText("Type:");
-
-        mTypeLabel = new Label(parent, SWT.NONE);
-
-        l = new Label(parent, SWT.NONE);
-        l.setText("Description:");
-
-        mDescriptionLabel = new Label(parent, SWT.NONE);
-
-        if (hasValues) {
-            c.select(0);
-            processSelection(indexToName.get(0), false /* pack */);
-        }
-    }
-
-    private void processSelection(String name, boolean pack) {
-        mChosenProperty = mProperties.get(name);
-        mTypeLabel.setText(mChosenProperty.getType().getValue());
-        String desc = mChosenProperty.getDescription();
-        if (desc != null) {
-            mDescriptionLabel.setText(mChosenProperty.getDescription());
-        } else {
-            mDescriptionLabel.setText("N/A");
-        }
-
-        if (pack) {
-            getShell().pack();
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ResolutionChooserDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ResolutionChooserDialog.java
deleted file mode 100644
index 60888e6..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ResolutionChooserDialog.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.widgets;
-
-import com.android.sdkuilib.ui.GridDialog;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Monitor;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Small dialog to let a user choose a screen size (from a fixed list) and a resolution
- * (as returned by {@link Display#getMonitors()}).
-
- * After the dialog as returned, one can query {@link #getDensity()} to get the chosen monitor
- * pixel density.
- */
-class ResolutionChooserDialog extends GridDialog {
-    public final static float[] MONITOR_SIZES = new float[] {
-            13.3f, 14, 15.4f, 15.6f, 17, 19, 20, 21, 24, 30,
-    };
-
-    private Button mButton;
-    private Combo mScreenSizeCombo;
-    private Combo mMonitorCombo;
-
-    private Monitor[] mMonitors;
-    private int mScreenSizeIndex = -1;
-    private int mMonitorIndex = 0;
-
-    ResolutionChooserDialog(Shell parentShell) {
-        super(parentShell, 2, false);
-    }
-
-    /**
-     * Returns the pixel density of the user-chosen monitor.
-     */
-    int getDensity() {
-        float size = MONITOR_SIZES[mScreenSizeIndex];
-        Rectangle rect = mMonitors[mMonitorIndex].getBounds();
-
-        // compute the density
-        double d = Math.sqrt(rect.width * rect.width + rect.height * rect.height) / size;
-        return (int)Math.round(d);
-    }
-
-    @Override
-    protected void configureShell(Shell newShell) {
-        newShell.setText("Monitor Density");
-        super.configureShell(newShell);
-    }
-
-    @Override
-    protected Control createContents(Composite parent) {
-        Control control = super.createContents(parent);
-        mButton = getButton(IDialogConstants.OK_ID);
-        mButton.setEnabled(false);
-        return control;
-    }
-
-    @Override
-    public void createDialogContent(Composite parent) {
-        Label l = new Label(parent, SWT.NONE);
-        l.setText("Screen Size:");
-
-        mScreenSizeCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
-        for (float size : MONITOR_SIZES) {
-            if (Math.round(size) == size) {
-                mScreenSizeCombo.add(String.format("%.0f\"", size));
-            } else {
-                mScreenSizeCombo.add(String.format("%.1f\"", size));
-            }
-        }
-        mScreenSizeCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent arg0) {
-                mScreenSizeIndex = mScreenSizeCombo.getSelectionIndex();
-                mButton.setEnabled(mScreenSizeIndex != -1);
-            }
-        });
-
-        l = new Label(parent, SWT.NONE);
-        l.setText("Resolution:");
-
-        mMonitorCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
-        mMonitors = parent.getDisplay().getMonitors();
-        for (Monitor m : mMonitors) {
-            Rectangle r = m.getBounds();
-            mMonitorCombo.add(String.format("%d x %d", r.width, r.height));
-        }
-        mMonitorCombo.select(mMonitorIndex);
-        mMonitorCombo.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetDefaultSelected(SelectionEvent arg0) {
-                mMonitorIndex = mMonitorCombo.getSelectionIndex();
-            }
-        });
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/SdkTargetSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/SdkTargetSelector.java
deleted file mode 100644
index e82eb29..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/SdkTargetSelector.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.widgets;
-
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-
-
-/**
- * The SDK target selector is a table that is added to the given parent composite.
- * <p/>
- * To use, create it using {@link #SdkTargetSelector(Composite, IAndroidTarget[], boolean)} then
- * call {@link #setSelection(IAndroidTarget)}, {@link #setSelectionListener(SelectionListener)}
- * and finally use {@link #getSelected()} to retrieve the
- * selection.
- */
-public class SdkTargetSelector {
-
-    private IAndroidTarget[] mTargets;
-    private final boolean mAllowSelection;
-    private SelectionListener mSelectionListener;
-    private Table mTable;
-    private Label mDescription;
-    private Composite mInnerGroup;
-
-    /**
-     * Creates a new SDK Target Selector.
-     *
-     * @param parent The parent composite where the selector will be added.
-     * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
-     *                Targets can be null or an empty array, in which case the table is disabled.
-     */
-    public SdkTargetSelector(Composite parent, IAndroidTarget[] targets) {
-        this(parent, targets, true /*allowSelection*/);
-    }
-
-    /**
-     * Creates a new SDK Target Selector.
-     *
-     * @param parent The parent composite where the selector will be added.
-     * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
-     *                Targets can be null or an empty array, in which case the table is disabled.
-     * @param allowSelection True if selection is enabled.
-     */
-    public SdkTargetSelector(Composite parent, IAndroidTarget[] targets, boolean allowSelection) {
-        // Layout has 1 column
-        mInnerGroup = new Composite(parent, SWT.NONE);
-        mInnerGroup.setLayout(new GridLayout());
-        mInnerGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
-        mInnerGroup.setFont(parent.getFont());
-
-        mAllowSelection = allowSelection;
-        int style = SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION;
-        if (allowSelection) {
-            style |= SWT.CHECK;
-        }
-        mTable = new Table(mInnerGroup, style);
-        mTable.setHeaderVisible(true);
-        mTable.setLinesVisible(false);
-
-        GridData data = new GridData();
-        data.grabExcessVerticalSpace = true;
-        data.grabExcessHorizontalSpace = true;
-        data.horizontalAlignment = GridData.FILL;
-        data.verticalAlignment = GridData.FILL;
-        mTable.setLayoutData(data);
-
-        mDescription = new Label(mInnerGroup, SWT.WRAP);
-        mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        // create the table columns
-        final TableColumn column0 = new TableColumn(mTable, SWT.NONE);
-        column0.setText("Target Name");
-        final TableColumn column1 = new TableColumn(mTable, SWT.NONE);
-        column1.setText("Vendor");
-        final TableColumn column2 = new TableColumn(mTable, SWT.NONE);
-        column2.setText("Platform");
-        final TableColumn column3 = new TableColumn(mTable, SWT.NONE);
-        column3.setText("API Level");
-
-        adjustColumnsWidth(mTable, column0, column1, column2, column3);
-        setupSelectionListener(mTable);
-        setTargets(targets);
-        setupTooltip(mTable);
-    }
-
-    /**
-     * Returns the layout data of the inner composite widget that contains the target selector.
-     * By default the layout data is set to a {@link GridData} with a {@link GridData#FILL_BOTH}
-     * mode.
-     * <p/>
-     * This can be useful if you want to change the {@link GridData#horizontalSpan} for example.
-     */
-    public Object getLayoutData() {
-        return mInnerGroup.getLayoutData();
-    }
-
-    /**
-     * Returns the list of known targets.
-     * <p/>
-     * This is not a copy. Callers must <em>not</em> modify this array.
-     */
-    public IAndroidTarget[] getTargets() {
-        return mTargets;
-    }
-
-    /**
-     * Changes the targets of the SDK Target Selector.
-     *
-     * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
-     */
-    public void setTargets(IAndroidTarget[] targets) {
-        mTargets = targets;
-        fillTable(mTable);
-    }
-
-    /**
-     * Sets a selection listener. Set it to null to remove it.
-     * The listener will be called <em>after</em> this table processed its selection
-     * events so that the caller can see the updated state.
-     * <p/>
-     * The event's item contains a {@link TableItem}.
-     * The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
-     * <p/>
-     * It is recommended that the caller uses the {@link #getSelected()} method instead.
-     *
-     * @param selectionListener The new listener or null to remove it.
-     */
-    public void setSelectionListener(SelectionListener selectionListener) {
-        mSelectionListener = selectionListener;
-    }
-
-    /**
-     * Sets the current target selection.
-     * <p/>
-     * If the selection is actually changed, this will invoke the selection listener
-     * (if any) with a null event.
-     *
-     * @param target the target to be selection
-     * @return true if the target could be selected, false otherwise.
-     */
-    public boolean setSelection(IAndroidTarget target) {
-        if (!mAllowSelection) {
-            return false;
-        }
-
-        boolean found = false;
-        boolean modified = false;
-
-        if (mTable != null && !mTable.isDisposed()) {
-            for (TableItem i : mTable.getItems()) {
-                if ((IAndroidTarget) i.getData() == target) {
-                    found = true;
-                    if (!i.getChecked()) {
-                        modified = true;
-                        i.setChecked(true);
-                    }
-                } else if (i.getChecked()) {
-                    modified = true;
-                    i.setChecked(false);
-                }
-            }
-        }
-
-        if (modified && mSelectionListener != null) {
-            mSelectionListener.widgetSelected(null);
-        }
-
-        return found;
-    }
-
-    /**
-     * Returns the selected item.
-     *
-     * @return The selected item or null.
-     */
-    public IAndroidTarget getSelected() {
-        if (mTable == null || mTable.isDisposed()) {
-            return null;
-        }
-
-        for (TableItem i : mTable.getItems()) {
-            if (i.getChecked()) {
-                return (IAndroidTarget) i.getData();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Adds a listener to adjust the columns width when the parent is resized.
-     * <p/>
-     * If we need something more fancy, we might want to use this:
-     * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
-     */
-    private void adjustColumnsWidth(final Table table,
-            final TableColumn column0,
-            final TableColumn column1,
-            final TableColumn column2,
-            final TableColumn column3) {
-        // Add a listener to resize the column to the full width of the table
-        table.addControlListener(new ControlAdapter() {
-            @Override
-            public void controlResized(ControlEvent e) {
-                Rectangle r = table.getClientArea();
-                column0.setWidth(r.width * 30 / 100); // 30%
-                column1.setWidth(r.width * 45 / 100); // 45%
-                column2.setWidth(r.width * 15 / 100); // 15%
-                column3.setWidth(r.width * 10 / 100); // 10%
-            }
-        });
-    }
-
-
-    /**
-     * Creates a selection listener that will check or uncheck the whole line when
-     * double-clicked (aka "the default selection").
-     */
-    private void setupSelectionListener(final Table table) {
-        if (!mAllowSelection) {
-            return;
-        }
-
-        // Add a selection listener that will check/uncheck items when they are double-clicked
-        table.addSelectionListener(new SelectionListener() {
-            /** Default selection means double-click on "most" platforms */
-            public void widgetDefaultSelected(SelectionEvent e) {
-                if (e.item instanceof TableItem) {
-                    TableItem i = (TableItem) e.item;
-                    i.setChecked(!i.getChecked());
-                    enforceSingleSelection(i);
-                    updateDescription(i);
-                }
-
-                if (mSelectionListener != null) {
-                    mSelectionListener.widgetDefaultSelected(e);
-                }
-            }
-
-            public void widgetSelected(SelectionEvent e) {
-                if (e.item instanceof TableItem) {
-                    TableItem i = (TableItem) e.item;
-                    enforceSingleSelection(i);
-                    updateDescription(i);
-                }
-
-                if (mSelectionListener != null) {
-                    mSelectionListener.widgetSelected(e);
-                }
-            }
-
-            /**
-             * If we're not in multiple selection mode, uncheck all other
-             * items when this one is selected.
-             */
-            private void enforceSingleSelection(TableItem item) {
-                if (item.getChecked()) {
-                    Table parentTable = item.getParent();
-                    for (TableItem i2 : parentTable.getItems()) {
-                        if (i2 != item && i2.getChecked()) {
-                            i2.setChecked(false);
-                        }
-                    }
-                }
-            }
-        });
-    }
-
-
-    /**
-     * Fills the table with all SDK targets.
-     * The table columns are:
-     * <ul>
-     * <li>column 0: sdk name
-     * <li>column 1: sdk vendor
-     * <li>column 2: sdk api name
-     * <li>column 3: sdk version
-     * </ul>
-     */
-    private void fillTable(final Table table) {
-
-        if (table == null || table.isDisposed()) {
-            return;
-        }
-
-        table.removeAll();
-
-        if (mTargets != null && mTargets.length > 0) {
-            table.setEnabled(true);
-            for (IAndroidTarget target : mTargets) {
-                TableItem item = new TableItem(table, SWT.NONE);
-                item.setData(target);
-                item.setText(0, target.getName());
-                item.setText(1, target.getVendor());
-                item.setText(2, target.getVersionName());
-                item.setText(3, target.getVersion().getApiString());
-            }
-        } else {
-            table.setEnabled(false);
-            TableItem item = new TableItem(table, SWT.NONE);
-            item.setData(null);
-            item.setText(0, "--");
-            item.setText(1, "No target available");
-            item.setText(2, "--");
-            item.setText(3, "--");
-        }
-    }
-
-    /**
-     * Sets up a tooltip that displays the current item description.
-     * <p/>
-     * Displaying a tooltip over the table looks kind of odd here. Instead we actually
-     * display the description in a label under the table.
-     */
-    private void setupTooltip(final Table table) {
-
-        if (table == null || table.isDisposed()) {
-            return;
-        }
-
-        /*
-         * Reference:
-         * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
-         */
-
-        final Listener listener = new Listener() {
-            public void handleEvent(Event event) {
-
-                switch(event.type) {
-                case SWT.KeyDown:
-                case SWT.MouseExit:
-                case SWT.MouseDown:
-                    return;
-
-                case SWT.MouseHover:
-                    updateDescription(table.getItem(new Point(event.x, event.y)));
-                    break;
-
-                case SWT.Selection:
-                    if (event.item instanceof TableItem) {
-                        updateDescription((TableItem) event.item);
-                    }
-                    break;
-
-                default:
-                    return;
-                }
-
-            }
-        };
-
-        table.addListener(SWT.Dispose, listener);
-        table.addListener(SWT.KeyDown, listener);
-        table.addListener(SWT.MouseMove, listener);
-        table.addListener(SWT.MouseHover, listener);
-    }
-
-    /**
-     * Updates the description label with the description of the item's android target, if any.
-     */
-    private void updateDescription(TableItem item) {
-        if (item != null) {
-            Object data = item.getData();
-            if (data instanceof IAndroidTarget) {
-                String newTooltip = ((IAndroidTarget) data).getDescription();
-                mDescription.setText(newTooltip == null ? "" : newTooltip);  //$NON-NLS-1$
-            }
-        }
-    }
-
-    /** Enables or disables the controls. */
-    public void setEnabled(boolean enabled) {
-        if (mInnerGroup != null && mTable != null && !mTable.isDisposed()) {
-            enableControl(mInnerGroup, enabled);
-        }
-    }
-
-    /** Enables or disables controls; recursive for composite controls. */
-    private void enableControl(Control c, boolean enabled) {
-        c.setEnabled(enabled);
-        if (c instanceof Composite)
-        for (Control c2 : ((Composite) c).getChildren()) {
-            enableControl(c2, enabled);
-        }
-    }
-
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/UpdaterWindow.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/UpdaterWindow.java
deleted file mode 100755
index 7b56067..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/UpdaterWindow.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.repository;
-
-import com.android.sdklib.ISdkLog;
-import com.android.sdkuilib.internal.repository.UpdaterWindowImpl;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Opens an SDK Updater Window.
- *
- * This is the public interface for using the window.
- */
-public class UpdaterWindow {
-
-    private UpdaterWindowImpl mWindow;
-
-    /**
-     * Interface for listeners on SDK modifications (ie new installed compoments, or deleted
-     * components)
-     */
-    public interface ISdkListener {
-        /**
-         * Sent when the content of the SDK changed
-         */
-        void onSdkChange();
-    }
-
-    /**
-     * Creates a new window. Caller must call open(), which will block.
-     * @param sdkLog
-     * @param osSdkRoot The OS path to the SDK root.
-     * @param userCanChangeSdkRoot If true, the window lets the user change the SDK path
-     *                             being browsed.
-     */
-    public UpdaterWindow(Shell parentShell, ISdkLog sdkLog, String osSdkRoot,
-            boolean userCanChangeSdkRoot) {
-        mWindow = new UpdaterWindowImpl(parentShell, sdkLog, osSdkRoot, userCanChangeSdkRoot);
-    }
-
-    /**
-     * Registers an extra page for the updater window.
-     * <p/>
-     * Pages must derive from {@link Composite} and implement a constructor that takes
-     * a single parent {@link Composite} argument.
-     * <p/>
-     * All pages must be registered before the call to {@link #open()}.
-     *
-     * @param title The title of the page.
-     * @param pageClass The {@link Composite}-derived class that will implement the page.
-     */
-    public void registerPage(String title, Class<? extends Composite> pageClass) {
-        mWindow.registerExtraPage(title, pageClass);
-    }
-
-    /**
-     * Indicate the initial page that should be selected when the window opens.
-     * <p/>
-     * This must be called before the call to {@link #open()}.
-     * If null or if the page class is not found, the first page will be selected.
-     */
-    public void setInitialPage(Class<? extends Composite> pageClass) {
-        mWindow.setInitialPage(pageClass);
-    }
-
-    /**
-     * Sets whether the auto-update wizard will be shown when opening the window.
-     * <p/>
-     * This must be called before the call to {@link #open()}.
-     */
-    public void setRequestAutoUpdate(boolean requestAutoUpdate) {
-        mWindow.setRequestAutoUpdate(requestAutoUpdate);
-    }
-
-    /**
-     * Adds a new listener to be notified when a change is made to the content of the SDK.
-     */
-    public void addListeners(ISdkListener listener) {
-        mWindow.addListeners(listener);
-    }
-
-    /**
-     * Removes a new listener to be notified anymore when a change is made to the content of
-     * the SDK.
-     */
-    public void removeListener(ISdkListener listener) {
-        mWindow.removeListener(listener);
-    }
-
-    /**
-     * Opens the window.
-     */
-    public void open() {
-        mWindow.open();
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java
deleted file mode 100644
index 8329fd6..0000000
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.ui;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * jface-based dialog that properly sets up a {@link GridLayout} top composite with the proper
- * margin.
- *
- * Implementing dialog must create the content of the dialog in
- * {@link #createDialogContent(Composite)}.
- *
- */
-public abstract class GridDialog extends Dialog {
-
-    private final int mNumColumns;
-    private final boolean mMakeColumnsEqualWidth;
-
-    /**
-     * Creates the dialog
-     * @param parentShell the parent {@link Shell}.
-     * @param numColumns the number of columns in the grid
-     * @param makeColumnsEqualWidth whether or not the columns will have equal width
-     */
-    public GridDialog(Shell parentShell, int numColumns, boolean makeColumnsEqualWidth) {
-        super(parentShell);
-        mNumColumns = numColumns;
-        mMakeColumnsEqualWidth = makeColumnsEqualWidth;
-    }
-
-    /**
-     * Creates the content of the dialog. The <var>parent</var> composite is a {@link GridLayout}
-     * created with the <var>numColumn</var> and <var>makeColumnsEqualWidth</var> parameters
-     * passed to {@link #GridDialog(Shell, int, boolean)}.
-     * @param parent the parent composite.
-     */
-    public abstract void createDialogContent(Composite parent);
-
-    @Override
-    protected Control createDialogArea(Composite parent) {
-        Composite top = new Composite(parent, SWT.NONE);
-        GridLayout layout = new GridLayout(mNumColumns, mMakeColumnsEqualWidth);
-        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
-        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
-        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
-        layout.horizontalSpacing = convertHorizontalDLUsToPixels(
-                IDialogConstants.HORIZONTAL_SPACING);
-        top.setLayout(layout);
-        top.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        createDialogContent(top);
-
-        applyDialogFont(top);
-        return top;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java b/tools/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java
deleted file mode 100755
index 3e22b35..0000000
--- a/tools/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository;
-
-import com.android.sdklib.internal.repository.Archive;
-import com.android.sdklib.internal.repository.MockAddonPackage;
-import com.android.sdklib.internal.repository.MockPlatformPackage;
-import com.android.sdklib.internal.repository.MockToolPackage;
-import com.android.sdklib.internal.repository.Package;
-import com.android.sdklib.internal.repository.RepoSource;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import junit.framework.TestCase;
-
-public class UpdaterLogicTest extends TestCase {
-
-    private static class MockUpdaterLogic extends UpdaterLogic {
-        private final Package[] mRemotePackages;
-
-        public MockUpdaterLogic(Package[] remotePackages) {
-            mRemotePackages = remotePackages;
-        }
-
-        @Override
-        protected void fetchRemotePackages(ArrayList<Package> remotePkgs,
-                RepoSource[] remoteSources) {
-            // Ignore remoteSources and instead uses the remotePackages list given to the
-            // constructor.
-            if (mRemotePackages != null) {
-                remotePkgs.addAll(Arrays.asList(mRemotePackages));
-            }
-        }
-    }
-
-    public void testFindAddonDependency() throws Exception {
-        MockUpdaterLogic mul = new MockUpdaterLogic(null);
-
-        MockPlatformPackage p1 = new MockPlatformPackage(1, 1);
-        MockPlatformPackage p2 = new MockPlatformPackage(2, 1);
-
-        MockAddonPackage a1 = new MockAddonPackage(p1, 1);
-        MockAddonPackage a2 = new MockAddonPackage(p2, 2);
-
-        ArrayList<ArchiveInfo> out = new ArrayList<ArchiveInfo>();
-        ArrayList<Archive> selected = new ArrayList<Archive>();
-        ArrayList<Package> remote = new ArrayList<Package>();
-
-        // a2 depends on p2, which is not in the locals
-        Package[] locals = { p1, a1 };
-        RepoSource[] sources = null;
-        assertNull(mul.findPlatformDependency(a2, out, selected, remote, sources, locals));
-        assertEquals(0, out.size());
-
-        // p2 is now selected, and should be scheduled for install in out
-        Archive p2_archive = p2.getArchives()[0];
-        selected.add(p2_archive);
-        ArchiveInfo ai2 = mul.findPlatformDependency(a2, out, selected, remote, sources, locals);
-        assertNotNull(ai2);
-        assertSame(p2_archive, ai2.getNewArchive());
-        assertEquals(1, out.size());
-        assertSame(p2_archive, out.get(0).getNewArchive());
-    }
-
-    public void testFindPlatformDependency() throws Exception {
-        MockUpdaterLogic mul = new MockUpdaterLogic(null);
-
-        MockToolPackage t1 = new MockToolPackage(1);
-        MockToolPackage t2 = new MockToolPackage(2);
-
-        MockPlatformPackage p2 = new MockPlatformPackage(2, 1, 2);
-
-        ArrayList<ArchiveInfo> out = new ArrayList<ArchiveInfo>();
-        ArrayList<Archive> selected = new ArrayList<Archive>();
-        ArrayList<Package> remote = new ArrayList<Package>();
-
-        // p2 depends on t2, which is not locally installed
-        Package[] locals = { t1 };
-        RepoSource[] sources = null;
-        assertNull(mul.findToolsDependency(p2, out, selected, remote, sources, locals));
-        assertEquals(0, out.size());
-
-        // t2 is now selected and can be used as a dependency
-        Archive t2_archive = t2.getArchives()[0];
-        selected.add(t2_archive);
-        ArchiveInfo ai2 = mul.findToolsDependency(p2, out, selected, remote, sources, locals);
-        assertNotNull(ai2);
-        assertSame(t2_archive, ai2.getNewArchive());
-        assertEquals(1, out.size());
-        assertSame(t2_archive, out.get(0).getNewArchive());
-    }
-}
diff --git a/tools/sdkstats/.classpath b/tools/sdkstats/.classpath
deleted file mode 100644
index 73b1af5..0000000
--- a/tools/sdkstats/.classpath
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/sdkstats/.gitignore b/tools/sdkstats/.gitignore
deleted file mode 100644
index fe99505..0000000
--- a/tools/sdkstats/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin
-
diff --git a/tools/sdkstats/.project b/tools/sdkstats/.project
deleted file mode 100644
index 4dbfa87..0000000
--- a/tools/sdkstats/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>SdkStatsService</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/sdkstats/Android.mk b/tools/sdkstats/Android.mk
deleted file mode 100644
index f4cabdc..0000000
--- a/tools/sdkstats/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-SDKSTATS_LOCAL_DIR := $(call my-dir)
-include $(SDKSTATS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkstats/README b/tools/sdkstats/README
deleted file mode 100644
index 8ed0880..0000000
--- a/tools/sdkstats/README
+++ /dev/null
@@ -1,11 +0,0 @@
-How to use the Eclipse projects for SdkStats.
-
-SdkStats requires SWT to compile.
-
-SWT is available in the depot under //device/prebuild/<platform>/swt
-
-Because the build path cannot contain relative path that are not inside the project directory,
-the .classpath file references a user library called ANDROID_SWT.
-
-In order to compile the project, make a user library called ANDROID_SWT containing the jar
-available at //device/prebuild/<platform>/swt.
diff --git a/tools/sdkstats/src/Android.mk b/tools/sdkstats/src/Android.mk
deleted file mode 100644
index e95e67a..0000000
--- a/tools/sdkstats/src/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_LIBRARIES := \
-	androidprefs \
-	swt \
-	org.eclipse.jface_3.4.2.M20090107-0800 \
-	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
-	org.eclipse.core.commands_3.4.0.I20080509-2000
-LOCAL_MODULE := sdkstats
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java b/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
deleted file mode 100644
index c98fc94..0000000
--- a/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * 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.android.sdkstats;
-
-import com.android.prefs.AndroidLocation;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-
-import org.eclipse.jface.preference.PreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.program.Program;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.Random;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/** Utility class to send "ping" usage reports to the server. */
-public class SdkStatsService {
-
-    /** Minimum interval between ping, in milliseconds. */
-    private static final long PING_INTERVAL_MSEC = 86400 * 1000;  // 1 day
-
-    /* Text strings displayed in the opt-out dialog. */
-    private static final String WINDOW_TITLE_TEXT =
-        "Android SDK";
-
-    private static final String HEADER_TEXT =
-        "Thanks for using the Android SDK!";
-
-    private static final String NOTICE_TEXT =
-        "We know you just want to get started but please read this first.";
-
-    /** Used in the preference pane (PrefsDialog) as well. */
-    public static final String BODY_TEXT =
-        "By choosing to send certain usage statistics to Google, you can " +
-        "help us improve the Android SDK.  These usage statistics let us " +
-        "measure things like active usage of the SDK and let us know things " +
-        "like which versions of the SDK are in use and which tools are the " +
-        "most popular with developers.  This limited data is not associated " +
-        "with personal information about you, is examined on an aggregate " +
-        "basis, and is maintained in accordance with the " +
-        "<a href=\"http://www.google.com/intl/en/privacy.html\">Google " +
-        "Privacy Policy</a>.";
-
-    /** Used in the preference pane (PrefsDialog) as well. */
-    public static final String CHECKBOX_TEXT =
-        "Send usage statistics to Google.";
-
-    private static final String FOOTER_TEXT =
-        "If you later decide to change this setting, you can do so in the " +
-        "\"ddms\" tool under \"File\" > \"Preferences\" > \"Usage Stats\".";
-
-    private static final String BUTTON_TEXT =
-        "   Proceed   ";
-
-    /** List of Linux browser commands to try, in order (see openUrl). */
-    private static final String[] LINUX_BROWSERS = new String[] {
-        "firefox -remote openurl(%URL%,new-window)",  // $NON-NLS-1$ running FF
-        "mozilla -remote openurl(%URL%,new-window)",  // $NON-NLS-1$ running Moz
-        "firefox %URL%",                              // $NON-NLS-1$ new FF
-        "mozilla %URL%",                              // $NON-NLS-1$ new Moz
-        "kfmclient openURL %URL%",                    // $NON-NLS-1$ Konqueror
-        "opera -newwindow %URL%",                     // $NON-NLS-1$ Opera
-    };
-
-    public final static String PING_OPT_IN = "pingOptIn"; //$NON-NLS-1$
-    public final static String PING_TIME = "pingTime"; //$NON-NLS-1$
-    public final static String PING_ID = "pingId"; //$NON-NLS-1$
-
-
-    private static PreferenceStore sPrefStore;
-
-    /**
-     * Send a "ping" to the Google toolbar server, if enough time has
-     * elapsed since the last ping, and if the user has not opted out.
-     * If this is the first time, notify the user and offer an opt-out.
-     * Note: UI operations (if any) are synchronous, but the actual ping
-     * (if any) is sent in a <i>non-daemon</i> background thread.
-     *
-     * @param app name to report in the ping
-     * @param version to report in the ping
-     * @param display an optional {@link Display} object to use, or null, if a new one should be
-     * created.
-     */
-    public static void ping(final String app, final String version, final Display display) {
-        // Validate the application and version input.
-        final String normalVersion = normalizeVersion(app, version);
-
-        // Unique, randomly assigned ID for this installation.
-        PreferenceStore prefs = getPreferenceStore();
-        if (prefs != null) {
-            if (!prefs.contains(PING_ID)) {
-                // First time: make up a new ID.  TODO: Use something more random?
-                prefs.setValue(PING_ID, new Random().nextLong());
-
-                // Also give them a chance to opt out.
-                prefs.setValue(PING_OPT_IN, getUserPermission(display));
-                try {
-                    prefs.save();
-                }
-                catch (IOException ioe) {
-                }
-            }
-
-            // If the user has not opted in, do nothing and quietly return.
-            if (!prefs.getBoolean(PING_OPT_IN)) {
-                // user opted out.
-                return;
-            }
-
-            // If the last ping *for this app* was too recent, do nothing.
-            String timePref = PING_TIME + "." + app;  // $NON-NLS-1$
-            long now = System.currentTimeMillis();
-            long then = prefs.getLong(timePref);
-            if (now - then < PING_INTERVAL_MSEC) {
-                // too soon after a ping.
-                return;
-            }
-
-            // Record the time of the attempt, whether or not it succeeds.
-            prefs.setValue(timePref, now);
-            try {
-                prefs.save();
-            }
-            catch (IOException ioe) {
-            }
-
-            // Send the ping itself in the background (don't block if the
-            // network is down or slow or confused).
-            final long id = prefs.getLong(PING_ID);
-            new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        actuallySendPing(app, normalVersion, id);
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }.start();
-        }
-    }
-
-    /**
-     * Returns the DDMS {@link PreferenceStore}.
-     */
-    public static synchronized PreferenceStore getPreferenceStore() {
-        if (sPrefStore == null) {
-            // get the location of the preferences
-            String homeDir = null;
-            try {
-                homeDir = AndroidLocation.getFolder();
-            } catch (AndroidLocationException e1) {
-                // pass, we'll do a dummy store since homeDir is null
-            }
-
-            if (homeDir != null) {
-                String rcFileName = homeDir + "ddms.cfg"; //$NON-NLS-1$
-
-                // also look for an old pref file in the previous location
-                String oldPrefPath = System.getProperty("user.home") //$NON-NLS-1$
-                    + File.separator + ".ddmsrc"; //$NON-NLS-1$
-                File oldPrefFile = new File(oldPrefPath);
-                if (oldPrefFile.isFile()) {
-                    try {
-                        PreferenceStore oldStore = new PreferenceStore(oldPrefPath);
-                        oldStore.load();
-
-                        oldStore.save(new FileOutputStream(rcFileName), "");
-                        oldPrefFile.delete();
-
-                        PreferenceStore newStore = new PreferenceStore(rcFileName);
-                        newStore.load();
-                        sPrefStore = newStore;
-                    } catch (IOException e) {
-                        // create a new empty store.
-                        sPrefStore = new PreferenceStore(rcFileName);
-                    }
-                } else {
-                    sPrefStore = new PreferenceStore(rcFileName);
-
-                    try {
-                        sPrefStore.load();
-                    } catch (IOException e) {
-                        System.err.println("Error Loading Preferences");
-                    }
-                }
-            } else {
-                sPrefStore = new PreferenceStore();
-            }
-        }
-
-        return sPrefStore;
-    }
-
-    /**
-     * Unconditionally send a "ping" request to the Google toolbar server.
-     *
-     * @param app name to report in the ping
-     * @param version to report in the ping (dotted numbers, no more than four)
-     * @param id of the local installation
-     * @throws IOException if the ping failed
-     */
-    @SuppressWarnings("deprecation")
-    private static void actuallySendPing(String app, String version, long id)
-        throws IOException {
-        // Detect and report the host OS.
-        String os = System.getProperty("os.name");          // $NON-NLS-1$
-        if (os.startsWith("Mac OS")) {                      // $NON-NLS-1$
-            os = "mac";                                     // $NON-NLS-1$
-            String osVers = getVersion();
-            if (osVers != null) {
-                os = os + "-" + osVers;                     // $NON-NLS-1$
-            }
-        } else if (os.startsWith("Windows")) {              // $NON-NLS-1$
-            os = "win";                                     // $NON-NLS-1$
-            String osVers = getVersion();
-            if (osVers != null) {
-                os = os + "-" + osVers;                     // $NON-NLS-1$
-            }
-        } else if (os.startsWith("Linux")) {                // $NON-NLS-1$
-            os = "linux";                                   // $NON-NLS-1$
-        } else {
-            // Unknown -- surprising -- send it verbatim so we can see it.
-            os = URLEncoder.encode(os);
-        }
-
-        // Include the application's name as part of the as= value.
-        // Share the user ID for all apps, to allow unified activity reports.
-
-        URL url = new URL(
-            "http",                                         // $NON-NLS-1$
-            "tools.google.com",                             // $NON-NLS-1$
-            "/service/update?as=androidsdk_" + app +        // $NON-NLS-1$
-                "&id=" + Long.toHexString(id) +             // $NON-NLS-1$
-                "&version=" + version +                     // $NON-NLS-1$
-                "&os=" + os);                               // $NON-NLS-1$
-
-        // Discard the actual response, but make sure it reads OK
-        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-
-        // Believe it or not, a 404 response indicates success:
-        // the ping was logged, but no update is configured.
-        if (conn.getResponseCode() != HttpURLConnection.HTTP_OK &&
-            conn.getResponseCode() != HttpURLConnection.HTTP_NOT_FOUND) {
-            throw new IOException(
-                conn.getResponseMessage() + ": " + url);    // $NON-NLS-1$
-        }
-    }
-
-    /**
-     * Returns the version of the os if it is defined as X.Y, or null otherwise.
-     * <p/>
-     * Example of returned versions can be found at http://lopica.sourceforge.net/os.html
-     * <p/>
-     * This method removes any exiting micro versions.
-     */
-    private static String getVersion() {
-        Pattern p = Pattern.compile("(\\d+)\\.(\\d+).*"); // $NON-NLS-1$
-        String osVers = System.getProperty("os.version"); // $NON-NLS-1$
-        Matcher m = p.matcher(osVers);
-        if (m.matches()) {
-            return m.group(1) + "." + m.group(2);         // $NON-NLS-1$
-        }
-
-        return null;
-    }
-
-    /**
-     * Prompt the user for whether they want to opt out of reporting.
-     * @return whether the user allows reporting (they do not opt out).
-     */
-    private static boolean getUserPermission(Display display) {
-        // Whether the user gave permission (size-1 array for writing to).
-        // Initialize to false, set when the user clicks the button.
-        final boolean[] permission = new boolean[] { false };
-
-        boolean dispose = false;
-        if (display == null) {
-            display = new Display();
-            dispose = true;
-        }
-
-        final Display currentDisplay = display;
-        final boolean disposeDisplay = dispose;
-
-        display.syncExec(new Runnable() {
-            public void run() {
-                final Shell shell = new Shell(currentDisplay, SWT.TITLE | SWT.BORDER);
-                shell.setText(WINDOW_TITLE_TEXT);
-                shell.setLayout(new GridLayout(1, false)); // 1 column
-
-                // Take the default font and scale it up for the title.
-                final Label title = new Label(shell, SWT.CENTER | SWT.WRAP);
-                final FontData[] fontdata = title.getFont().getFontData();
-                for (int i = 0; i < fontdata.length; i++) {
-                    fontdata[i].setHeight(fontdata[i].getHeight() * 4 / 3);
-                }
-                title.setFont(new Font(currentDisplay, fontdata));
-                title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-                title.setText(HEADER_TEXT);
-
-                final Label notice = new Label(shell, SWT.WRAP);
-                notice.setFont(title.getFont());
-                notice.setForeground(new Color(currentDisplay, 255, 0, 0));
-                notice.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-                notice.setText(NOTICE_TEXT);
-
-                final Link text = new Link(shell, SWT.WRAP);
-                text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-                text.setText(BODY_TEXT);
-                text.addSelectionListener(new SelectionAdapter() {
-                    @Override
-                    public void widgetSelected(SelectionEvent event) {
-                        openUrl(event.text);
-                    }
-                });
-
-                final Button checkbox = new Button(shell, SWT.CHECK);
-                checkbox.setSelection(true); // Opt-in by default.
-                checkbox.setText(CHECKBOX_TEXT);
-
-                final Link footer = new Link(shell, SWT.WRAP);
-                footer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-                footer.setText(FOOTER_TEXT);
-
-                final Button button = new Button(shell, SWT.PUSH);
-                button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
-                button.setText(BUTTON_TEXT);
-                button.addSelectionListener(new SelectionAdapter() {
-                    @Override
-                    public void widgetSelected(SelectionEvent event) {
-                        permission[0] = checkbox.getSelection();
-                        shell.close();
-                    }
-                });
-
-                // Size the window to a fixed width, as high as necessary,
-                // centered.
-                final Point size = shell.computeSize(450, SWT.DEFAULT, true);
-                final Rectangle screen = currentDisplay.getClientArea();
-                shell.setBounds(screen.x + screen.width / 2 - size.x / 2, screen.y + screen.height
-                        / 2 - size.y / 2, size.x, size.y);
-
-                shell.open();
-                while (!shell.isDisposed()) {
-                    if (!currentDisplay.readAndDispatch())
-                        currentDisplay.sleep();
-                }
-
-                if (disposeDisplay) {
-                    currentDisplay.dispose();
-                }
-            }
-        });
-
-        return permission[0];
-    }
-
-    /**
-     * Open a URL in an external browser.
-     * @param url to open - MUST be sanitized and properly formed!
-     */
-    public static void openUrl(final String url) {
-        // TODO: consider using something like BrowserLauncher2
-        // (http://browserlaunch2.sourceforge.net/) instead of these hacks.
-
-        // SWT's Program.launch() should work on Mac, Windows, and GNOME
-        // (because the OS shell knows how to launch a default browser).
-        if (!Program.launch(url)) {
-            // Must be Linux non-GNOME (or something else broke).
-            // Try a few Linux browser commands in the background.
-            new Thread() {
-                @Override
-                public void run() {
-                    for (String cmd : LINUX_BROWSERS) {
-                        cmd = cmd.replaceAll("%URL%", url);  // $NON-NLS-1$
-                        try {
-                            Process proc = Runtime.getRuntime().exec(cmd);
-                            if (proc.waitFor() == 0) break;  // Success!
-                        } catch (InterruptedException e) {
-                            // Should never happen!
-                            throw new RuntimeException(e);
-                        } catch (IOException e) {
-                            // Swallow the exception and try the next browser.
-                        }
-                    }
-
-                    // TODO: Pop up some sort of error here?
-                    // (We're in a new thread; can't use the existing Display.)
-                }
-            }.start();
-        }
-    }
-
-    /**
-     * Validate the supplied application version, and normalize the version.
-     * @param app to report
-     * @param version supplied by caller
-     * @return normalized dotted quad version
-     */
-    private static String normalizeVersion(String app, String version) {
-        // Application name must contain only word characters (no punctuaation)
-        if (!app.matches("\\w+")) {
-            throw new IllegalArgumentException("Bad app name: " + app);
-        }
-
-        // Version must be between 1 and 4 dotted numbers
-        String[] numbers = version.split("\\.");
-        if (numbers.length > 4) {
-            throw new IllegalArgumentException("Bad version: " + version);
-        }
-        for (String part: numbers) {
-            if (!part.matches("\\d+")) {
-                throw new IllegalArgumentException("Bad version: " + version);
-            }
-        }
-
-        // Always output 4 numbers, even if fewer were supplied (pad with .0)
-        StringBuffer normal = new StringBuffer(numbers[0]);
-        for (int i = 1; i < 4; i++) {
-            normal.append(".").append(i < numbers.length ? numbers[i] : "0");
-        }
-        return normal.toString();
-    }
-}
diff --git a/tools/traceview/.classpath b/tools/traceview/.classpath
deleted file mode 100644
index e71cb61..0000000
--- a/tools/traceview/.classpath
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/SdkStatsService"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/traceview/.gitignore b/tools/traceview/.gitignore
deleted file mode 100644
index ba077a4..0000000
--- a/tools/traceview/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/tools/traceview/.project b/tools/traceview/.project
deleted file mode 100644
index 692297f..0000000
--- a/tools/traceview/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>traceview</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/traceview/Android.mk b/tools/traceview/Android.mk
deleted file mode 100644
index 2ce7b80..0000000
--- a/tools/traceview/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-TRACEVIEW_LOCAL_DIR := $(call my-dir)
-include $(TRACEVIEW_LOCAL_DIR)/etc/Android.mk
-include $(TRACEVIEW_LOCAL_DIR)/src/Android.mk
diff --git a/tools/traceview/README b/tools/traceview/README
deleted file mode 100644
index 6f4576a..0000000
--- a/tools/traceview/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Using the Eclipse projects for traceview.
-
-traceview requires SWT to compile.
-
-SWT is available in the depot under //device/prebuild/<platform>/swt
-
-Because the build path cannot contain relative path that are not inside the project directory,
-the .classpath file references a user library called ANDROID_SWT.
-
-In order to compile the project, make a user library called ANDROID_SWT containing the jar
-available at //device/prebuild/<platform>/swt.
diff --git a/tools/traceview/etc/Android.mk b/tools/traceview/etc/Android.mk
deleted file mode 100644
index f26b19e..0000000
--- a/tools/traceview/etc/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := traceview
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/traceview/etc/manifest.txt b/tools/traceview/etc/manifest.txt
deleted file mode 100644
index 6cdbc7e..0000000
--- a/tools/traceview/etc/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Main-Class: com.android.traceview.MainWindow
-Class-Path: swt.jar org.eclipse.equinox.common_3.2.0.v20060603.jar org.eclipse.jface_3.2.0.I20060605-1400.jar org.eclipse.core.commands_3.2.0.I20060605-1400.jar
diff --git a/tools/traceview/etc/traceview b/tools/traceview/etc/traceview
deleted file mode 100755
index 065cd0f..0000000
--- a/tools/traceview/etc/traceview
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2005-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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-progname=`basename "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/"${progname}"
-cd "${oldwd}"
-
-jarfile=traceview.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/tools/lib
-    libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    frameworkdir=`dirname "$progdir"`/framework
-    libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
-    echo "${progname}: can't find $jarfile"
-    exit 1
-fi
-
-javaCmd="java"
-
-os=`uname`
-if [ $os == 'Darwin' ]; then
-  javaOpts="-Xmx1600M -XstartOnFirstThread"
-else
-  javaOpts="-Xmx1600M"
-fi
-
-if [ `uname` = "Linux" ]; then
-    export GDK_NATIVE_WINDOWS=true
-fi
-
-while expr "x$1" : 'x-J' >/dev/null; do
-    opt=`expr "$1" : '-J\(.*\)'`
-    javaOpts="${javaOpts} -${opt}"
-    shift
-done
-
-jarpath="$frameworkdir/$jarfile"
-
-# Figure out the path to the swt.jar for the current architecture.
-# if ANDROID_SWT is defined, then just use this.
-# else, if running in the Android source tree, then look for the correct swt folder in prebuilt
-# else, look for the correct swt folder in the SDK under tools/lib/
-swtpath=""
-if [ -n "$ANDROID_SWT" ]; then
-    swtpath="$ANDROID_SWT"
-else
-    vmarch=`${javaCmd} -jar "${frameworkdir}"/archquery.jar`
-    if [ -n "$ANDROID_BUILD_TOP" ]; then
-        osname=`uname -s | tr A-Z a-z`
-        swtpath="${ANDROID_BUILD_TOP}/prebuilt/${osname}-${vmarch}/swt"
-    else
-        swtpath="${frameworkdir}/${vmarch}"
-    fi
-fi
-
-# Combine the swtpath and the framework dir path.
-if [ -d "$swtpath" ]; then
-    frameworkdir="${swtpath}:${frameworkdir}"
-else
-    echo "SWT folder '${swtpath}' does not exist."
-    echo "Please export ANDROID_SWT to point to the folder containing swt.jar for your platform."
-    exit 1
-fi
-
-exec "${javaCmd}" $javaOpts -Djava.ext.dirs="$frameworkdir" -Dcom.android.traceview.toolsdir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/traceview/etc/traceview.bat b/tools/traceview/etc/traceview.bat
deleted file mode 100755
index 02fbe85..0000000
--- a/tools/traceview/etc/traceview.bat
+++ /dev/null
@@ -1,58 +0,0 @@
-@echo off
-rem Copyright (C) 2007 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-set jarfile=traceview.jar
-set frameworkdir=
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=lib\
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
-    set frameworkdir=..\framework\
-
-:JarFileOk
-
-set jarpath=%frameworkdir%%jarfile%
-
-if not defined ANDROID_SWT goto QueryArch
-    set swt_path=%ANDROID_SWT%
-    goto SwtDone
-
-:QueryArch
-
-    for /f %%a in ('java -jar %frameworkdir%archquery.jar') do set swt_path=%frameworkdir%%%a
-
-:SwtDone
-
-if exist %swt_path% goto SetPath
-    echo SWT folder '%swt_path%' does not exist.
-    echo Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.
-    exit /B
-
-:SetPath
-set javaextdirs=%swt_path%;%frameworkdir%
-
-call java -Djava.ext.dirs=%javaextdirs% -Dcom.android.traceview.toolsdir= -jar %jarpath% %*
diff --git a/tools/traceview/src/Android.mk b/tools/traceview/src/Android.mk
deleted file mode 100644
index fd901f1..0000000
--- a/tools/traceview/src/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
-	androidprefs \
-	sdkstats \
-	swt \
-	org.eclipse.jface_3.4.2.M20090107-0800 \
-	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
-	org.eclipse.core.commands_3.4.0.I20080509-2000
-LOCAL_MODULE := traceview
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/traceview/src/com/android/traceview/Call.java b/tools/traceview/src/com/android/traceview/Call.java
deleted file mode 100644
index 40ac244..0000000
--- a/tools/traceview/src/com/android/traceview/Call.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import org.eclipse.swt.graphics.Color;
-
-class Call implements TimeLineView.Block {
-    
-    // Values for bits within the mFlags field.
-    private static final int METHOD_ACTION_MASK = 0x3;
-    private static final int IS_RECURSIVE = 0x10;
-
-    private int mThreadId;
-    private int mFlags;
-    MethodData mMethodData;
-    
-    /** 0-based thread-local start time */
-    long mThreadStartTime;
-    
-    /**  global start time */
-    long mGlobalStartTime;
-
-    /** global end time */
-    long mGlobalEndTime;
-    
-    private String mName;
-
-    /**
-     * This constructor is used for the root of a Call tree. The name is
-     * the name of the corresponding thread. 
-     */
-    Call(String name, MethodData methodData) {
-        mName = name;
-        mMethodData = methodData;
-    }
-
-    Call() {
-    }
-    
-    Call(int threadId, MethodData methodData, long time, int methodAction) {
-        mThreadId = threadId;
-        mMethodData = methodData;
-        mThreadStartTime = time;
-        mFlags = methodAction & METHOD_ACTION_MASK;
-        mName = methodData.getProfileName();
-    }
-    
-    public void set(int threadId, MethodData methodData, long time, int methodAction) {
-        mThreadId = threadId;
-        mMethodData = methodData;
-        mThreadStartTime = time;
-        mFlags = methodAction & METHOD_ACTION_MASK;
-        mName = methodData.getProfileName();
-    }
-
-    public void updateName() {
-        mName = mMethodData.getProfileName();
-    }
-
-    public double addWeight(int x, int y, double weight) {
-        return mMethodData.addWeight(x, y, weight);
-    }
-
-    public void clearWeight() {
-        mMethodData.clearWeight();
-    }
-
-    public long getStartTime() {
-        return mGlobalStartTime;
-    }
-
-    public long getEndTime() {
-        return mGlobalEndTime;
-    }
-
-    public Color getColor() {
-        return mMethodData.getColor();
-    }
-
-    public void addExclusiveTime(long elapsed) {
-        mMethodData.addElapsedExclusive(elapsed);
-        if ((mFlags & IS_RECURSIVE) == 0) {
-            mMethodData.addTopExclusive(elapsed);
-        }
-    }
-
-    public void addInclusiveTime(long elapsed, Call parent) {
-        boolean isRecursive = (mFlags & IS_RECURSIVE) != 0;
-        mMethodData.addElapsedInclusive(elapsed, isRecursive, parent);
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public void setName(String name) {
-        mName = name;
-    }
-
-    int getThreadId() {
-        return mThreadId;
-    }
-
-    public MethodData getMethodData() {
-        return mMethodData;
-    }
-
-    int getMethodAction() {
-        return mFlags & METHOD_ACTION_MASK;
-    }
-
-    public void dump() {
-        System.out.printf("%s [%d, %d]\n", mName, mGlobalStartTime, mGlobalEndTime);
-    }
-
-    public void setRecursive(boolean isRecursive) {
-        if (isRecursive) {
-            mFlags |= IS_RECURSIVE;
-        } else {
-            mFlags &= ~IS_RECURSIVE;
-        }
-    }
-
-    public boolean isRecursive() {
-        return (mFlags & IS_RECURSIVE) != 0;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/ColorController.java b/tools/traceview/src/com/android/traceview/ColorController.java
deleted file mode 100644
index f5e4c0d..0000000
--- a/tools/traceview/src/com/android/traceview/ColorController.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.util.HashMap;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.widgets.Display;
-
-public class ColorController {
-    private static final int[] systemColors = { SWT.COLOR_BLUE, SWT.COLOR_RED,
-        SWT.COLOR_GREEN, SWT.COLOR_CYAN, SWT.COLOR_MAGENTA, SWT.COLOR_DARK_BLUE,
-        SWT.COLOR_DARK_RED, SWT.COLOR_DARK_GREEN, SWT.COLOR_DARK_YELLOW,
-        SWT.COLOR_DARK_CYAN, SWT.COLOR_DARK_MAGENTA, SWT.COLOR_BLACK };
-
-    private static RGB[] rgbColors = { new RGB(90, 90, 255), // blue
-            new RGB(0, 240, 0), // green
-            new RGB(255, 0, 0), // red
-            new RGB(0, 255, 255), // cyan
-            new RGB(255, 80, 255), // magenta
-            new RGB(200, 200, 0), // yellow
-            new RGB(40, 0, 200), // dark blue
-            new RGB(150, 255, 150), // light green
-            new RGB(150, 0, 0), // dark red
-            new RGB(30, 150, 150), // dark cyan
-            new RGB(200, 200, 255), // light blue
-            new RGB(0, 120, 0), // dark green
-            new RGB(255, 150, 150), // light red
-            new RGB(140, 80, 140), // dark magenta
-            new RGB(150, 100, 50), // brown
-            new RGB(70, 70, 70), // dark grey
-    };
-
-    private static HashMap<Integer, Color> colorCache = new HashMap<Integer, Color>();
-    private static HashMap<Integer, Image> imageCache = new HashMap<Integer, Image>();
-
-    public ColorController() {
-    }
-
-    public static Color requestColor(Display display, RGB rgb) {
-        return requestColor(display, rgb.red, rgb.green, rgb.blue);
-    }
-
-    public static Image requestColorSquare(Display display, RGB rgb) {
-        return requestColorSquare(display, rgb.red, rgb.green, rgb.blue);
-    }
-
-    public static Color requestColor(Display display, int red, int green, int blue) {
-        int key = (red << 16) | (green << 8) | blue;
-        Color color = colorCache.get(key);
-        if (color == null) {
-            color = new Color(display, red, green, blue);
-            colorCache.put(key, color);
-        }
-        return color;
-    }
-
-    public static Image requestColorSquare(Display display, int red, int green, int blue) {
-        int key = (red << 16) | (green << 8) | blue;
-        Image image = imageCache.get(key);
-        if (image == null) {
-            image = new Image(display, 8, 14);
-            GC gc = new GC(image);
-            Color color = requestColor(display, red, green, blue);
-            gc.setBackground(color);
-            gc.fillRectangle(image.getBounds());
-            gc.dispose();
-            imageCache.put(key, image);
-        }
-        return image;
-    }
-
-    public static void assignMethodColors(Display display, MethodData[] methods) {
-        int nextColorIndex = 0;
-        for (MethodData md : methods) {
-            RGB rgb = rgbColors[nextColorIndex];
-            if (++nextColorIndex == rgbColors.length)
-                nextColorIndex = 0;
-            Color color = requestColor(display, rgb);
-            Image image = requestColorSquare(display, rgb);
-            md.setColor(color);
-            md.setImage(image);
-
-            // Compute and set a faded color
-            int fadedRed = 150 + rgb.red / 4;
-            int fadedGreen = 150 + rgb.green / 4;
-            int fadedBlue = 150 + rgb.blue / 4;
-            RGB faded = new RGB(fadedRed, fadedGreen, fadedBlue);
-            color = requestColor(display, faded);
-            image = requestColorSquare(display, faded);
-            md.setFadedColor(color);
-            md.setFadedImage(image);
-        }
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/DmTraceReader.java b/tools/traceview/src/com/android/traceview/DmTraceReader.java
deleted file mode 100644
index 5a19c19..0000000
--- a/tools/traceview/src/com/android/traceview/DmTraceReader.java
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class DmTraceReader extends TraceReader {
-
-    private int mVersionNumber = 0;
-    private boolean mDebug = false;
-    private static final int TRACE_MAGIC = 0x574f4c53;
-    private boolean mRegression;
-    private ProfileProvider mProfileProvider;
-    private String mTraceFileName;
-    private MethodData mTopLevel;
-    private ArrayList<Call> mCallList;
-    private ArrayList<Call> mSwitchList;
-    private HashMap<Integer, MethodData> mMethodMap;
-    private HashMap<Integer, ThreadData> mThreadMap;
-    private ThreadData[] mSortedThreads;
-    private MethodData[] mSortedMethods;
-    private long mGlobalEndTime;
-    private MethodData mContextSwitch;
-    private int mOffsetToData;
-    private byte[] mBytes = new byte[8];
-
-    // A regex for matching the thread "id name" lines in the .key file
-    private static final Pattern mIdNamePattern = Pattern.compile("(\\d+)\t(.*)");  // $NON-NLS-1$
-
-    DmTraceReader(String traceFileName, boolean regression) {
-        mTraceFileName = traceFileName;
-        mRegression = regression;
-        mMethodMap = new HashMap<Integer, MethodData>();
-        mThreadMap = new HashMap<Integer, ThreadData>();
-
-        // Create a single top-level MethodData object to hold the profile data
-        // for time spent in the unknown caller.
-        mTopLevel = new MethodData(0, "(toplevel)");
-        mContextSwitch = new MethodData(-1, "(context switch)");
-        mMethodMap.put(0, mTopLevel);
-        generateTrees();
-        // dumpTrees();
-    }
-
-    void generateTrees() {
-        try {
-            long offset = parseKeys();
-            parseData(offset);
-            analyzeData();
-        } catch (IOException e) {
-            System.err.println(e.getMessage());
-            System.exit(1);
-        }
-    }
-
-    @Override
-    public ProfileProvider getProfileProvider() {
-        if (mProfileProvider == null)
-            mProfileProvider = new ProfileProvider(this);
-        return mProfileProvider;
-    }
-
-    Call readCall(MappedByteBuffer buffer, Call call) {
-        int threadId;
-        int methodId;
-        long time;
-        
-        try {
-            if (mVersionNumber == 1)
-                threadId = buffer.get();
-            else
-                threadId = buffer.getShort();
-            methodId = buffer.getInt();
-            time = buffer.getInt();
-        } catch (BufferUnderflowException ex) {
-            return null;
-        }
-        
-        int methodAction = methodId & 0x03;
-        methodId = methodId & ~0x03;
-        MethodData methodData = mMethodMap.get(methodId);
-        if (methodData == null) {
-            String name = String.format("(0x%1$x)", methodId);  // $NON-NLS-1$
-            methodData = new MethodData(methodId, name);
-        }
-        
-        if (call != null) {
-            call.set(threadId, methodData, time, methodAction);
-        } else {
-            call = new Call(threadId, methodData, time, methodAction);
-        }
-        return call;
-    }
-    
-    private MappedByteBuffer mapFile(String filename, long offset) {
-        MappedByteBuffer buffer = null;
-        try {
-            FileInputStream dataFile = new FileInputStream(filename);
-            File file = new File(filename);
-            FileChannel fc = dataFile.getChannel();
-            buffer = fc.map(FileChannel.MapMode.READ_ONLY, offset, file.length() - offset);
-            buffer.order(ByteOrder.LITTLE_ENDIAN);
-        } catch (FileNotFoundException ex) {
-            System.err.println(ex.getMessage());
-            System.exit(1);
-        } catch (IOException ex) {
-            System.err.println(ex.getMessage());
-            System.exit(1);
-        }
-        
-        return buffer;
-    }
-    
-    private void readDataFileHeader(MappedByteBuffer buffer) {
-        int magic = buffer.getInt();
-        if (magic != TRACE_MAGIC) {
-            System.err.printf(
-                    "Error: magic number mismatch; got 0x%x, expected 0x%x\n",
-                    magic, TRACE_MAGIC);
-            throw new RuntimeException();
-        }
-        // read version
-        int version = buffer.getShort();
-        
-        // read offset
-        mOffsetToData = buffer.getShort() - 16;
-        
-        // read startWhen
-        buffer.getLong();
-        
-        // Skip over "mOffsetToData" bytes
-        for (int ii = 0; ii < mOffsetToData; ii++) {
-            buffer.get();
-        }
-        
-        // Save this position so that we can re-read the data later
-        buffer.mark();
-    }
-
-    private void parseData(long offset) {
-        MappedByteBuffer buffer = mapFile(mTraceFileName, offset);
-        readDataFileHeader(buffer);
-        parseDataPass1(buffer);
-        
-        buffer.reset();
-        parseDataPass2(buffer);
-    }
-    
-    private void parseDataPass1(MappedByteBuffer buffer) {
-        mSwitchList = new ArrayList<Call>();
-
-        // Read the first call so that we can set "prevThreadData"
-        Call call = new Call();
-        call = readCall(buffer, call);
-        if (call == null)
-            return;
-        long callTime = call.mThreadStartTime;
-        long prevCallTime = 0;
-        ThreadData threadData = mThreadMap.get(call.getThreadId());
-        if (threadData == null) {
-            String name = String.format("[%1$d]", call.getThreadId());  // $NON-NLS-1$
-            threadData = new ThreadData(call.getThreadId(), name, mTopLevel);
-            mThreadMap.put(call.getThreadId(), threadData);
-        }
-        ThreadData prevThreadData = threadData;
-        while (true) {
-            // If a context switch occurred, then insert a placeholder "call"
-            // record so that we can do something reasonable with the global
-            // timestamps.
-            if (prevThreadData != threadData) {
-                Call switchEnter = new Call(prevThreadData.getId(),
-                        mContextSwitch, prevCallTime, 0);
-                prevThreadData.setLastContextSwitch(switchEnter);
-                mSwitchList.add(switchEnter);
-                Call contextSwitch = threadData.getLastContextSwitch();
-                if (contextSwitch != null) {
-                    long prevStartTime = contextSwitch.mThreadStartTime;
-                    long elapsed = callTime - prevStartTime;
-                    long beforeSwitch = elapsed / 2;
-                    long afterSwitch = elapsed - beforeSwitch;
-                    long exitTime = callTime - afterSwitch;
-                    contextSwitch.mThreadStartTime = prevStartTime + beforeSwitch;
-                    Call switchExit = new Call(threadData.getId(),
-                            mContextSwitch, exitTime, 1);
-                    
-                    mSwitchList.add(switchExit);
-                }
-                prevThreadData = threadData;
-            }
-
-            // Read the next call
-            call = readCall(buffer, call);
-            if (call == null) {
-                break;
-            }
-            prevCallTime = callTime;
-            callTime = call.mThreadStartTime;
-
-            threadData = mThreadMap.get(call.getThreadId());
-            if (threadData == null) {
-                String name = String.format("[%d]", call.getThreadId());
-                threadData = new ThreadData(call.getThreadId(), name, mTopLevel);
-                mThreadMap.put(call.getThreadId(), threadData);
-            }
-        }
-    }
-
-    void parseDataPass2(MappedByteBuffer buffer) {
-        mCallList = new ArrayList<Call>();
-
-        // Read the first call so that we can set "prevThreadData"
-        Call call = readCall(buffer, null);
-        long callTime = call.mThreadStartTime;
-        long prevCallTime = callTime;
-        ThreadData threadData = mThreadMap.get(call.getThreadId());
-        ThreadData prevThreadData = threadData;
-        threadData.setGlobalStartTime(0);
-        
-        int nthContextSwitch = 0;
-
-        // Assign a global timestamp to each event.
-        long globalTime = 0;
-        while (true) {
-            long elapsed = callTime - prevCallTime;
-            if (threadData != prevThreadData) {
-                // Get the next context switch.  This one is entered
-                // by the previous thread.
-                Call contextSwitch = mSwitchList.get(nthContextSwitch++);
-                mCallList.add(contextSwitch);
-                elapsed = contextSwitch.mThreadStartTime - prevCallTime;
-                globalTime += elapsed;
-                elapsed = 0;
-                contextSwitch.mGlobalStartTime = globalTime;
-                prevThreadData.handleCall(contextSwitch, globalTime);
-                
-                if (!threadData.isEmpty()) {
-                    // This context switch is exited by the current thread.
-                    contextSwitch = mSwitchList.get(nthContextSwitch++);
-                    mCallList.add(contextSwitch);
-                    contextSwitch.mGlobalStartTime = globalTime;
-                    elapsed = callTime - contextSwitch.mThreadStartTime;
-                    threadData.handleCall(contextSwitch, globalTime);
-                }
-
-                // If the thread's global start time has not been set yet,
-                // then set it.
-                if (threadData.getGlobalStartTime() == -1)
-                    threadData.setGlobalStartTime(globalTime);
-                prevThreadData = threadData;
-            }
-
-            globalTime += elapsed;
-            call.mGlobalStartTime = globalTime;
-            
-            threadData.handleCall(call, globalTime);
-            mCallList.add(call);
-            
-            // Read the next call
-            call = readCall(buffer, null);
-            if (call == null) {
-                break;
-            }
-            prevCallTime = callTime;
-            callTime = call.mThreadStartTime;
-            threadData = mThreadMap.get(call.getThreadId());
-        }
-
-        // Allow each thread to do any cleanup of the call stack.
-        // Also add the elapsed time for each thread to the toplevel
-        // method's inclusive time.
-        for (int id : mThreadMap.keySet()) {
-            threadData = mThreadMap.get(id);
-            long endTime = threadData.endTrace();
-            if (endTime > 0)
-                mTopLevel.addElapsedInclusive(endTime, false, null);
-        }
-
-        mGlobalEndTime = globalTime;
-        
-        if (mRegression) {
-            dumpCallTimes();
-        }
-    }
-
-    static final int PARSE_VERSION = 0;
-    static final int PARSE_THREADS = 1;
-    static final int PARSE_METHODS = 2;
-    static final int PARSE_OPTIONS = 4;
-
-    long parseKeys() throws IOException {
-        BufferedReader in = null;
-        try {
-            in = new BufferedReader(new FileReader(mTraceFileName));
-        } catch (FileNotFoundException ex) {
-            System.err.println(ex.getMessage());
-        }
-
-        long offset = 0;
-        int mode = PARSE_VERSION;
-        String line = null;
-        while (true) {
-            line = in.readLine();
-            if (line == null) {
-                throw new IOException("Key section does not have an *end marker");
-            }
-            
-            // Calculate how much we have read from the file so far.  The
-            // extra byte is for the line ending not included by readLine().
-            offset += line.length() + 1;
-            if (line.startsWith("*")) {
-                if (line.equals("*version")) {
-                    mode = PARSE_VERSION;
-                    continue;
-                }
-                if (line.equals("*threads")) {
-                    mode = PARSE_THREADS;
-                    continue;
-                }
-                if (line.equals("*methods")) {
-                    mode = PARSE_METHODS;
-                    continue;
-                }
-                if (line.equals("*end")) {
-                    return offset;
-                }
-            }
-            switch (mode) {
-            case PARSE_VERSION:
-                mVersionNumber = Integer.decode(line);
-                mode = PARSE_OPTIONS;
-                break;
-            case PARSE_THREADS:
-                parseThread(line);
-                break;
-            case PARSE_METHODS:
-                parseMethod(line);
-                break;
-            case PARSE_OPTIONS:
-                break;
-            }
-        }
-    }
-
-    void parseThread(String line) {
-        String idStr = null;
-        String name = null;
-        Matcher matcher = mIdNamePattern.matcher(line);
-        if (matcher.find()) {
-            idStr = matcher.group(1);
-            name = matcher.group(2);
-        }
-        if (idStr == null) return;
-        if (name == null) name = "(unknown)";
-
-        int id = Integer.decode(idStr);
-        mThreadMap.put(id, new ThreadData(id, name, mTopLevel));
-    }
-
-    void parseMethod(String line) {
-        String[] tokens = line.split("\t");
-        int id = Long.decode(tokens[0]).intValue();
-        String className = tokens[1];
-        String methodName = null;
-        String signature = null;
-        String pathname = null;
-        int lineNumber = -1;
-        if (tokens.length == 6) {
-            methodName = tokens[2];
-            signature = tokens[3];
-            pathname = tokens[4];
-            lineNumber = Integer.decode(tokens[5]);
-            pathname = constructPathname(className, pathname);
-        } else if (tokens.length > 2) {
-            if (tokens[3].startsWith("(")) {
-                methodName = tokens[2];
-                signature = tokens[3];
-            } else {
-                pathname = tokens[2];
-                lineNumber = Integer.decode(tokens[3]);
-            }
-        }
-
-        mMethodMap.put(id, new MethodData(id, className, methodName, signature,
-                pathname, lineNumber));
-    }
-
-    private String constructPathname(String className, String pathname) {
-        int index = className.lastIndexOf('/');
-        if (index > 0 && index < className.length() - 1
-                && pathname.endsWith(".java"))
-            pathname = className.substring(0, index + 1) + pathname;
-        return pathname;
-    }
-
-    private void analyzeData() {
-        // Sort the threads into decreasing cpu time
-        Collection<ThreadData> tv = mThreadMap.values();
-        mSortedThreads = tv.toArray(new ThreadData[tv.size()]);
-        Arrays.sort(mSortedThreads, new Comparator<ThreadData>() {
-            public int compare(ThreadData td1, ThreadData td2) {
-                if (td2.getCpuTime() > td1.getCpuTime())
-                    return 1;
-                if (td2.getCpuTime() < td1.getCpuTime())
-                    return -1;
-                return td2.getName().compareTo(td1.getName());
-            }
-        });
-
-        // Analyze the call tree so that we can label the "worst" children.
-        // Also set all the root pointers in each node in the call tree.
-        long sum = 0;
-        for (ThreadData t : mSortedThreads) {
-            if (t.isEmpty() == false) {
-                Call root = t.getCalltreeRoot();
-                root.mGlobalStartTime = t.getGlobalStartTime();
-            }
-        }
-
-        // Sort the methods into decreasing inclusive time
-        Collection<MethodData> mv = mMethodMap.values();
-        MethodData[] methods;
-        methods = mv.toArray(new MethodData[mv.size()]);
-        Arrays.sort(methods, new Comparator<MethodData>() {
-            public int compare(MethodData md1, MethodData md2) {
-                if (md2.getElapsedInclusive() > md1.getElapsedInclusive())
-                    return 1;
-                if (md2.getElapsedInclusive() < md1.getElapsedInclusive())
-                    return -1;
-                return md1.getName().compareTo(md2.getName());
-            }
-        });
-
-        // Count the number of methods with non-zero inclusive time
-        int nonZero = 0;
-        for (MethodData md : methods) {
-            if (md.getElapsedInclusive() == 0)
-                break;
-            nonZero += 1;
-        }
-
-        // Copy the methods with non-zero time
-        mSortedMethods = new MethodData[nonZero];
-        int ii = 0;
-        for (MethodData md : methods) {
-            if (md.getElapsedInclusive() == 0)
-                break;
-            md.setRank(ii);
-            mSortedMethods[ii++] = md;
-        }
-
-        // Let each method analyze its profile data
-        for (MethodData md : mSortedMethods) {
-            md.analyzeData();
-        }
-
-        // Update all the calls to include the method rank in
-        // their name.
-        for (Call call : mCallList) {
-            call.updateName();
-        }
-        
-        if (mRegression) {
-            dumpMethodStats();
-        }
-    }
-
-    /*
-     * This method computes a list of records that describe the the execution
-     * timeline for each thread. Each record is a pair: (row, block) where: row:
-     * is the ThreadData object block: is the call (containing the start and end
-     * times)
-     */
-    @Override
-    public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
-        TimeLineView.Record record;
-        ArrayList<TimeLineView.Record> timeRecs;
-        timeRecs = new ArrayList<TimeLineView.Record>();
-
-        // For each thread, push a "toplevel" call that encompasses the
-        // entire execution of the thread.
-        for (ThreadData threadData : mSortedThreads) {
-            if (!threadData.isEmpty() && threadData.getId() != 0) {
-                Call call = new Call(threadData.getId(), mTopLevel,
-                        threadData.getGlobalStartTime(), 0);
-                call.mGlobalStartTime = threadData.getGlobalStartTime();
-                call.mGlobalEndTime = threadData.getGlobalEndTime();
-                record = new TimeLineView.Record(threadData, call);
-                timeRecs.add(record);
-            }
-        }
-
-        for (Call call : mCallList) {
-            if (call.getMethodAction() != 0 || call.getThreadId() == 0)
-                continue;
-            ThreadData threadData = mThreadMap.get(call.getThreadId());
-            record = new TimeLineView.Record(threadData, call);
-            timeRecs.add(record);
-        }
-        
-        if (mRegression) {
-            dumpTimeRecs(timeRecs);
-            System.exit(0);
-        }
-        return timeRecs;
-    }
-        
-    private void dumpCallTimes() {
-        String action;
-        
-        System.out.format("id thread  global start,end   method\n");
-        for (Call call : mCallList) {
-            if (call.getMethodAction() == 0) {
-                action = "+";
-            } else {
-                action = " ";
-            }
-            long callTime = call.mThreadStartTime;
-            System.out.format("%2d %6d %8d %8d %s %s\n",
-                    call.getThreadId(), callTime, call.mGlobalStartTime,
-                    call.mGlobalEndTime, action, call.getMethodData().getName());
-//            if (call.getMethodAction() == 0 && call.getGlobalEndTime() < call.getGlobalStartTime()) {
-//                System.out.printf("endtime %d < startTime %d\n",
-//                        call.getGlobalEndTime(), call.getGlobalStartTime());
-//            }
-        }
-    }
-    
-    private void dumpMethodStats() {
-        System.out.format("\nExclusive Inclusive     Calls  Method\n");
-        for (MethodData md : mSortedMethods) {
-            System.out.format("%9d %9d %9s  %s\n",
-                    md.getElapsedExclusive(), md.getElapsedInclusive(),
-                    md.getCalls(), md.getProfileName());
-        }
-    }
-
-    private void dumpTimeRecs(ArrayList<TimeLineView.Record> timeRecs) {
-        System.out.format("\nid thread  global start,end  method\n");
-        for (TimeLineView.Record record : timeRecs) {
-            Call call = (Call) record.block;
-            long callTime = call.mThreadStartTime;
-            System.out.format("%2d %6d %8d %8d  %s\n",
-                    call.getThreadId(), callTime,
-                    call.mGlobalStartTime, call.mGlobalEndTime,
-                    call.getMethodData().getName());
-        }
-    }
-
-    @Override
-    public HashMap<Integer, String> getThreadLabels() {
-        HashMap<Integer, String> labels = new HashMap<Integer, String>();
-        for (ThreadData t : mThreadMap.values()) {
-            labels.put(t.getId(), t.getName());
-        }
-        return labels;
-    }
-
-    @Override
-    public MethodData[] getMethods() {
-        return mSortedMethods;
-    }
-
-    @Override
-    public ThreadData[] getThreads() {
-        return mSortedThreads;
-    }
-
-    @Override
-    public long getEndTime() {
-        return mGlobalEndTime;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/MainWindow.java b/tools/traceview/src/com/android/traceview/MainWindow.java
deleted file mode 100644
index 00fcc8b..0000000
--- a/tools/traceview/src/com/android/traceview/MainWindow.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import com.android.sdkstats.SdkStatsService;
-
-import org.eclipse.jface.window.ApplicationWindow;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.util.HashMap;
-import java.util.Properties;
-
-public class MainWindow extends ApplicationWindow {
-
-    private final static String PING_NAME = "Traceview";
-    private final static String PING_VERSION = "1.0";
-
-    private TraceReader mReader;
-    private String mTraceName;
-
-    // A global cache of string names.
-    public static HashMap<String, String> sStringCache = new HashMap<String, String>();
-
-    public MainWindow(String traceName, TraceReader reader) {
-        super(null);
-        mReader = reader;
-        mTraceName = traceName;
-    }
-
-    public void run() {
-        setBlockOnOpen(true);
-        open();
-        Display.getCurrent().dispose();
-    }
-
-    @Override
-    protected void configureShell(Shell shell) {
-        super.configureShell(shell);
-        shell.setText("Traceview: " + mTraceName);
-        shell.setBounds(100, 10, 1282, 900);
-    }
-
-    @Override
-    protected Control createContents(Composite parent) {
-        ColorController.assignMethodColors(parent.getDisplay(), mReader.getMethods());
-        SelectionController selectionController = new SelectionController();
-
-        GridLayout gridLayout = new GridLayout(1, false);
-        gridLayout.marginWidth = 0;
-        gridLayout.marginHeight = 0;
-        gridLayout.horizontalSpacing = 0;
-        gridLayout.verticalSpacing = 0;
-        parent.setLayout(gridLayout);
-
-        Display display = parent.getDisplay();
-        Color darkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
-
-        // Create a sash form to separate the timeline view (on top)
-        // and the profile view (on bottom)
-        SashForm sashForm1 = new SashForm(parent, SWT.VERTICAL);
-        sashForm1.setBackground(darkGray);
-        sashForm1.SASH_WIDTH = 3;
-        GridData data = new GridData(GridData.FILL_BOTH);
-        sashForm1.setLayoutData(data);
-
-        // Create the timeline view
-        new TimeLineView(sashForm1, mReader, selectionController);
-
-        // Create the profile view
-        new ProfileView(sashForm1, mReader, selectionController);
-        return sashForm1;
-    }
-
-    /**
-     * Convert the old two-file format into the current concatenated one.
-     *
-     * @param base Base path of the two files, i.e. base.key and base.data
-     * @return Path to a temporary file that will be deleted on exit.
-     * @throws IOException
-     */
-    private static String makeTempTraceFile(String base) throws IOException {
-        // Make a temporary file that will go away on exit and prepare to
-        // write into it.
-        File temp = File.createTempFile(base, ".trace");
-        temp.deleteOnExit();
-        FileChannel dstChannel = new FileOutputStream(temp).getChannel();
-
-        // First copy the contents of the key file into our temp file.
-        FileChannel srcChannel = new FileInputStream(base + ".key").getChannel();
-        long size = dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
-        srcChannel.close();
-
-        // Then concatenate the data file.
-        srcChannel = new FileInputStream(base + ".data").getChannel();
-        dstChannel.transferFrom(srcChannel, size, srcChannel.size());
-
-        // Clean up.
-        srcChannel.close();
-        dstChannel.close();
-
-        // Return the path of the temp file.
-        return temp.getPath();
-    }
-
-    /**
-     * Returns the tools revision number.
-     */
-    private static String getRevision() {
-        Properties p = new Properties();
-        try{
-            String toolsdir = System.getProperty("com.android.traceview.toolsdir"); //$NON-NLS-1$
-            File sourceProp;
-            if (toolsdir == null || toolsdir.length() == 0) {
-                sourceProp = new File("source.properties"); //$NON-NLS-1$
-            } else {
-                sourceProp = new File(toolsdir, "source.properties"); //$NON-NLS-1$
-            }
-            p.load(new FileInputStream(sourceProp));
-            String revision = p.getProperty("Pkg.Revision"); //$NON-NLS-1$
-            if (revision != null && revision.length() > 0) {
-                return revision;
-            }
-        } catch (FileNotFoundException e) {
-            // couldn't find the file? don't ping.
-        } catch (IOException e) {
-            // couldn't find the file? don't ping.
-        }
-
-        return null;
-    }
-
-
-    public static void main(String[] args) {
-        TraceReader reader = null;
-        boolean regression = false;
-
-        // ping the usage server
-
-        String revision = getRevision();
-        if (revision != null) {
-            SdkStatsService.ping(PING_NAME, revision, null);
-        }
-
-        // Process command line arguments
-        int argc = 0;
-        int len = args.length;
-        while (argc < len) {
-            String arg = args[argc];
-            if (arg.charAt(0) != '-') {
-                break;
-            }
-            if (arg.equals("-r")) {
-                regression = true;
-            } else {
-                break;
-            }
-            argc++;
-        }
-        if (argc != len - 1) {
-            System.out.printf("Usage: java %s [-r] trace%n", MainWindow.class.getName());
-            System.out.printf("  -r   regression only%n");
-            return;
-        }
-
-        String traceName = args[len - 1];
-        File file = new File(traceName);
-        if (file.exists() && file.isDirectory()) {
-            System.out.printf("Qemu trace files not supported yet.\n");
-            System.exit(1);
-            // reader = new QtraceReader(traceName);
-        } else {
-            // If the filename as given doesn't exist...
-            if (!file.exists()) {
-                // Try appending .trace.
-                if (new File(traceName + ".trace").exists()) {
-                    traceName = traceName + ".trace";
-                // Next, see if it is the old two-file trace.
-                } else if (new File(traceName + ".data").exists()
-                    && new File(traceName + ".key").exists()) {
-                    try {
-                        traceName = makeTempTraceFile(traceName);
-                    } catch (IOException e) {
-                        System.err.printf("cannot convert old trace file '%s'\n", traceName);
-                        System.exit(1);
-                    }
-                // Otherwise, give up.
-                } else {
-                    System.err.printf("trace file '%s' not found\n", traceName);
-                    System.exit(1);
-                }
-            }
-
-            reader = new DmTraceReader(traceName, regression);
-        }
-        reader.getTraceUnits().setTimeScale(TraceUnits.TimeScale.MilliSeconds);
-        new MainWindow(traceName, reader).run();
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/MethodData.java b/tools/traceview/src/com/android/traceview/MethodData.java
deleted file mode 100644
index 0bc9853..0000000
--- a/tools/traceview/src/com/android/traceview/MethodData.java
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-
-public class MethodData {
-
-    private int mId;
-    private int mRank = -1;
-    private String mClassName;
-    private String mMethodName;
-    private String mSignature;
-    private String mName;
-    private String mProfileName;
-    private String mPathname;
-    private int mLineNumber;
-    private long mElapsedExclusive;
-    private long mElapsedInclusive;
-    private long mTopExclusive;
-    private int[] mNumCalls = new int[2]; // index 0=normal, 1=recursive
-    private Color mColor;
-    private Color mFadedColor;
-    private Image mImage;
-    private Image mFadedImage;
-    private HashMap<Integer, ProfileData> mParents;
-    private HashMap<Integer, ProfileData> mChildren;
-    
-    // The parents of this method when this method was in a recursive call
-    private HashMap<Integer, ProfileData> mRecursiveParents;
-    
-    // The children of this method when this method was in a recursive call
-    private HashMap<Integer, ProfileData> mRecursiveChildren;
-
-    private ProfileNode[] mProfileNodes;
-    private int mX;
-    private int mY;
-    private double mWeight;
-
-    public MethodData(int id, String className) {
-        mId = id;
-        mClassName = className;
-        mMethodName = null;
-        mSignature = null;
-        mPathname = null;
-        mLineNumber = -1;
-        computeName();
-        computeProfileName();
-    }
-
-    public MethodData(int id, String className, String methodName,
-            String signature, String pathname, int lineNumber) {
-        mId = id;
-        mClassName = className;
-        mMethodName = methodName;
-        mSignature = signature;
-        mPathname = pathname;
-        mLineNumber = lineNumber;
-        computeName();
-        computeProfileName();
-    }
-
-    private Comparator<ProfileData> mByElapsedInclusive = new Comparator<ProfileData>() {
-        public int compare(ProfileData pd1, ProfileData pd2) {
-            if (pd2.getElapsedInclusive() > pd1.getElapsedInclusive())
-                return 1;
-            if (pd2.getElapsedInclusive() < pd1.getElapsedInclusive())
-                return -1;
-            return 0;
-        }
-    };
-
-    public double addWeight(int x, int y, double weight) {
-        if (mX == x && mY == y)
-            mWeight += weight;
-        else {
-            mX = x;
-            mY = y;
-            mWeight = weight;
-        }
-        return mWeight;
-    }
-
-    public void clearWeight() {
-        mWeight = 0;
-    }
-
-    public int getRank() {
-        return mRank;
-    }
-
-    public void setRank(int rank) {
-        mRank = rank;
-        computeProfileName();
-    }
-
-    public void addElapsedExclusive(long time) {
-        mElapsedExclusive += time;
-    }
-
-    public void addElapsedInclusive(long time, boolean isRecursive, Call parent) {
-        if (isRecursive == false) {
-            mElapsedInclusive += time;
-            mNumCalls[0] += 1;
-        } else {
-            mNumCalls[1] += 1;
-        }
-
-        if (parent == null)
-            return;
-
-        // Find the child method in the parent
-        MethodData parentMethod = parent.mMethodData;
-        if (parent.isRecursive()) {
-            parentMethod.mRecursiveChildren = updateInclusive(time,
-                    parentMethod, this, false,
-                    parentMethod.mRecursiveChildren);
-        } else {
-            parentMethod.mChildren = updateInclusive(time,
-                    parentMethod, this, false, parentMethod.mChildren);
-        }
-
-        // Find the parent method in the child
-        if (isRecursive) {
-            mRecursiveParents = updateInclusive(time, this, parentMethod, true,
-                    mRecursiveParents);
-        } else {
-            mParents = updateInclusive(time, this, parentMethod, true,
-                    mParents);
-        }
-    }
-    
-    private HashMap<Integer, ProfileData> updateInclusive(long time,
-            MethodData contextMethod, MethodData elementMethod,
-            boolean elementIsParent, HashMap<Integer, ProfileData> map) {
-        if (map == null) {
-            map = new HashMap<Integer, ProfileData>(4);
-        } else {
-            ProfileData profileData = map.get(elementMethod.mId);
-            if (profileData != null) {
-                profileData.addElapsedInclusive(time);
-                return map;
-            }
-        }
-
-        ProfileData elementData = new ProfileData(contextMethod,
-                elementMethod, elementIsParent);
-        elementData.setElapsedInclusive(time);
-        elementData.setNumCalls(1);
-        map.put(elementMethod.mId, elementData);
-        return map;
-    }
-
-    public void analyzeData() {
-        // Sort the parents and children into decreasing inclusive time
-        ProfileData[] sortedParents;
-        ProfileData[] sortedChildren;
-        ProfileData[] sortedRecursiveParents;
-        ProfileData[] sortedRecursiveChildren;
-        
-        sortedParents = sortProfileData(mParents);
-        sortedChildren = sortProfileData(mChildren);
-        sortedRecursiveParents = sortProfileData(mRecursiveParents);
-        sortedRecursiveChildren = sortProfileData(mRecursiveChildren);
-        
-        // Add "self" time to the top of the sorted children
-        sortedChildren = addSelf(sortedChildren);
-        
-        // Create the ProfileNode objects that we need
-        ArrayList<ProfileNode> nodes = new ArrayList<ProfileNode>();
-        ProfileNode profileNode;
-        if (mParents != null) {
-            profileNode = new ProfileNode("Parents", this, sortedParents,
-                    true, false);
-            nodes.add(profileNode);
-        }
-        if (mChildren != null) {
-            profileNode = new ProfileNode("Children", this, sortedChildren,
-                    false, false);
-            nodes.add(profileNode);
-        }
-        if (mRecursiveParents!= null) {
-            profileNode = new ProfileNode("Parents while recursive", this,
-                    sortedRecursiveParents, true, true);
-            nodes.add(profileNode);
-        }
-        if (mRecursiveChildren != null) {
-            profileNode = new ProfileNode("Children while recursive", this,
-                    sortedRecursiveChildren, false, true);
-            nodes.add(profileNode);
-        }
-        mProfileNodes = nodes.toArray(new ProfileNode[nodes.size()]);
-    }
-    
-    // Create and return a ProfileData[] array that is a sorted copy
-    // of the given HashMap values.
-    private ProfileData[] sortProfileData(HashMap<Integer, ProfileData> map) {
-        if (map == null)
-            return null;
-
-        // Convert the hash values to an array of ProfileData
-        Collection<ProfileData> values = map.values();
-        ProfileData[] sorted = values.toArray(new ProfileData[values.size()]);
-        
-        // Sort the array by elapsed inclusive time
-        Arrays.sort(sorted, mByElapsedInclusive);
-        return sorted;
-    }
-    
-    private ProfileData[] addSelf(ProfileData[] children) {
-        ProfileData[] pdata;
-        if (children == null) {
-            pdata = new ProfileData[1];
-        } else {
-            pdata = new ProfileData[children.length + 1];
-            System.arraycopy(children, 0, pdata, 1, children.length);
-        }
-        pdata[0] = new ProfileSelf(this);
-        return pdata;
-    }
-
-    public void addTopExclusive(long time) {
-        mTopExclusive += time;
-    }
-
-    public long getTopExclusive() {
-        return mTopExclusive;
-    }
-
-    public int getId() {
-        return mId;
-    }
-
-    private void computeName() {
-        if (mMethodName == null) {
-            mName = mClassName;
-            return;
-        }
-
-        StringBuilder sb = new StringBuilder();
-        sb.append(mClassName);
-        sb.append(".");  //$NON-NLS-1$
-        sb.append(mMethodName);
-        sb.append(" ");  //$NON-NLS-1$
-        sb.append(mSignature);
-        mName = sb.toString();
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public String getClassName() {
-        return mClassName;
-    }
-
-    public String getMethodName() {
-        return mMethodName;
-    }
-
-    public String getProfileName() {
-        return mProfileName;
-    }
-
-    public void computeProfileName() {
-        if (mRank == -1) {
-            mProfileName = mName;
-            return;
-        }
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append(mRank);
-        sb.append(" ");  //$NON-NLS-1$
-        sb.append(getName());
-        mProfileName = sb.toString();
-    }
-
-    public String getCalls() {
-        return String.format("%d+%d", mNumCalls[0], mNumCalls[1]);
-    }
-
-    public int getTotalCalls() {
-        return mNumCalls[0] + mNumCalls[1];
-    }
-
-    public Color getColor() {
-        return mColor;
-    }
-
-    public void setColor(Color color) {
-        mColor = color;
-    }
-
-    public void setImage(Image image) {
-        mImage = image;
-    }
-
-    public Image getImage() {
-        return mImage;
-    }
-
-    @Override
-    public String toString() {
-        return getName();
-    }
-
-    public long getElapsedExclusive() {
-        return mElapsedExclusive;
-    }
-
-    public long getElapsedInclusive() {
-        return mElapsedInclusive;
-    }
-
-    public void setFadedColor(Color fadedColor) {
-        mFadedColor = fadedColor;
-    }
-
-    public Color getFadedColor() {
-        return mFadedColor;
-    }
-
-    public void setFadedImage(Image fadedImage) {
-        mFadedImage = fadedImage;
-    }
-
-    public Image getFadedImage() {
-        return mFadedImage;
-    }
-
-    public void setPathname(String pathname) {
-        mPathname = pathname;
-    }
-
-    public String getPathname() {
-        return mPathname;
-    }
-
-    public void setLineNumber(int lineNumber) {
-        mLineNumber = lineNumber;
-    }
-
-    public int getLineNumber() {
-        return mLineNumber;
-    }
-
-    public ProfileNode[] getProfileNodes() {
-        return mProfileNodes;
-    }
-
-    public static class Sorter implements Comparator<MethodData> {
-        public int compare(MethodData md1, MethodData md2) {
-            if (mColumn == Column.BY_NAME) {
-                int result = md1.getName().compareTo(md2.getName());
-                return (mDirection == Direction.INCREASING) ? result : -result;
-            }
-            if (mColumn == Column.BY_INCLUSIVE) {
-                if (md2.getElapsedInclusive() > md1.getElapsedInclusive())
-                    return (mDirection == Direction.INCREASING) ? -1 : 1;
-                if (md2.getElapsedInclusive() < md1.getElapsedInclusive())
-                    return (mDirection == Direction.INCREASING) ? 1 : -1;
-                return md1.getName().compareTo(md2.getName());
-            }
-            if (mColumn == Column.BY_EXCLUSIVE) {
-                if (md2.getElapsedExclusive() > md1.getElapsedExclusive())
-                    return (mDirection == Direction.INCREASING) ? -1 : 1;
-                if (md2.getElapsedExclusive() < md1.getElapsedExclusive())
-                    return (mDirection == Direction.INCREASING) ? 1 : -1;
-                return md1.getName().compareTo(md2.getName());
-            }
-            if (mColumn == Column.BY_CALLS) {
-                int result = md1.getTotalCalls() - md2.getTotalCalls();
-                if (result == 0)
-                    return md1.getName().compareTo(md2.getName());
-                return (mDirection == Direction.INCREASING) ? result : -result;
-            }
-            if (mColumn == Column.BY_TIME_PER_CALL) {
-                double time1 = md1.getElapsedInclusive();
-                time1 = time1 / md1.getTotalCalls();
-                double time2 = md2.getElapsedInclusive();
-                time2 = time2 / md2.getTotalCalls();
-                double diff = time1 - time2;
-                int result = 0;
-                if (diff < 0)
-                    result = -1;
-                else if (diff > 0)
-                    result = 1;
-                if (result == 0)
-                    return md1.getName().compareTo(md2.getName());
-                return (mDirection == Direction.INCREASING) ? result : -result;
-            }
-            return 0;
-        }
-
-        public void setColumn(Column column) {
-            // If the sort column specified is the same as last time,
-            // then reverse the sort order.
-            if (mColumn == column) {
-                // Reverse the sort order
-                if (mDirection == Direction.INCREASING)
-                    mDirection = Direction.DECREASING;
-                else
-                    mDirection = Direction.INCREASING;
-            } else {
-                // Sort names into increasing order, data into decreasing order.
-                if (column == Column.BY_NAME)
-                    mDirection = Direction.INCREASING;
-                else
-                    mDirection = Direction.DECREASING;
-            }
-            mColumn = column;
-        }
-
-        public Column getColumn() {
-            return mColumn;
-        }
-
-        public void setDirection(Direction direction) {
-            mDirection = direction;
-        }
-
-        public Direction getDirection() {
-            return mDirection;
-        }
-
-        public static enum Column {
-            BY_NAME, BY_EXCLUSIVE, BY_INCLUSIVE, BY_CALLS, BY_TIME_PER_CALL
-        };
-
-        public static enum Direction {
-            INCREASING, DECREASING
-        };
-
-        private Column mColumn;
-        private Direction mDirection;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/ProfileData.java b/tools/traceview/src/com/android/traceview/ProfileData.java
deleted file mode 100644
index f0c1d61..0000000
--- a/tools/traceview/src/com/android/traceview/ProfileData.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-
-public class ProfileData {
-
-    protected MethodData mElement;
-    
-    /** mContext is either the parent or child of mElement */
-    protected MethodData mContext;
-    protected boolean mElementIsParent;
-    protected long mElapsedInclusive;
-    protected int mNumCalls;
-
-    public ProfileData() {
-    }
-
-    public ProfileData(MethodData context, MethodData element,
-            boolean elementIsParent) {
-        mContext = context;
-        mElement = element;
-        mElementIsParent = elementIsParent;
-    }
-
-    public String getProfileName() {
-        return mElement.getProfileName();
-    }
-
-    public MethodData getMethodData() {
-        return mElement;
-    }
-
-    public void addElapsedInclusive(long elapsedInclusive) {
-        mElapsedInclusive += elapsedInclusive;
-        mNumCalls += 1;
-    }
-
-    public void setElapsedInclusive(long elapsedInclusive) {
-        mElapsedInclusive = elapsedInclusive;
-    }
-
-    public long getElapsedInclusive() {
-        return mElapsedInclusive;
-    }
-
-    public void setNumCalls(int numCalls) {
-        mNumCalls = numCalls;
-    }
-
-    public String getNumCalls() {
-        int totalCalls;
-        if (mElementIsParent)
-            totalCalls = mContext.getTotalCalls();
-        else
-            totalCalls = mElement.getTotalCalls();
-        return String.format("%d/%d", mNumCalls, totalCalls);
-    }
-
-    public boolean isParent() {
-        return mElementIsParent;
-    }
-
-    public MethodData getContext() {
-        return mContext;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/ProfileNode.java b/tools/traceview/src/com/android/traceview/ProfileNode.java
deleted file mode 100644
index 7cb0b5d..0000000
--- a/tools/traceview/src/com/android/traceview/ProfileNode.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-public class ProfileNode {
-
-    private String mLabel;
-    private MethodData mMethodData;
-    private ProfileData[] mChildren;
-    private boolean mIsParent;
-    private boolean mIsRecursive;
-
-    public ProfileNode(String label, MethodData methodData,
-            ProfileData[] children, boolean isParent, boolean isRecursive) {
-        mLabel = label;
-        mMethodData = methodData;
-        mChildren = children;
-        mIsParent = isParent;
-        mIsRecursive = isRecursive;
-    }
-
-    public String getLabel() {
-        return mLabel;
-    }
-    
-    public ProfileData[] getChildren() {
-        return mChildren;
-    }
-
-    public boolean isParent() {
-        return mIsParent;
-    }
-
-    public boolean isRecursive() {
-        return mIsRecursive;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/ProfileProvider.java b/tools/traceview/src/com/android/traceview/ProfileProvider.java
deleted file mode 100644
index fe5c832..0000000
--- a/tools/traceview/src/com/android/traceview/ProfileProvider.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.regex.Pattern;
-
-import org.eclipse.jface.viewers.IColorProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
-
-class ProfileProvider implements ITreeContentProvider {
-
-    private MethodData[] mRoots;
-    private SelectionAdapter mListener;
-    private TreeViewer mTreeViewer;
-    private TraceReader mReader;
-    private Image mSortUp;
-    private Image mSortDown;
-    private String mColumnNames[] = { "Name", "Incl %", "Inclusive", "Excl %",
-            "Exclusive", "Calls+Recur\nCalls/Total", "Time/Call" };
-    private int mColumnWidths[] = { 370, 70, 70, 70, 70, 90, 70 };
-    private int mColumnAlignments[] = { SWT.LEFT, SWT.RIGHT, SWT.RIGHT,
-            SWT.RIGHT, SWT.RIGHT, SWT.CENTER, SWT.RIGHT };
-    private static final int COL_NAME = 0;
-    private static final int COL_INCLUSIVE_PER = 1;
-    private static final int COL_INCLUSIVE = 2;
-    private static final int COL_EXCLUSIVE_PER = 3;
-    private static final int COL_EXCLUSIVE = 4;
-    private static final int COL_CALLS = 5;
-    private static final int COL_TIME_PER_CALL = 6;
-    private long mTotalTime;
-    private Pattern mUppercase;
-    private int mPrevMatchIndex = -1;
-
-    public ProfileProvider(TraceReader reader) {
-        mRoots = reader.getMethods();
-        mReader = reader;
-        mTotalTime = reader.getEndTime();
-        Display display = Display.getCurrent();
-        InputStream in = getClass().getClassLoader().getResourceAsStream(
-                "icons/sort_up.png");
-        mSortUp = new Image(display, in);
-        in = getClass().getClassLoader().getResourceAsStream(
-                "icons/sort_down.png");
-        mSortDown = new Image(display, in);
-        mUppercase = Pattern.compile("[A-Z]");
-    }
-
-    private MethodData doMatchName(String name, int startIndex) {
-        // Check if the given "name" has any uppercase letters
-        boolean hasUpper = mUppercase.matcher(name).matches();
-        for (int ii = startIndex; ii < mRoots.length; ++ii) {
-            MethodData md = mRoots[ii];
-            String fullName = md.getName();
-            // If there were no upper case letters in the given name,
-            // then ignore case when matching.
-            if (!hasUpper)
-                fullName = fullName.toLowerCase();
-            if (fullName.indexOf(name) != -1) {
-                mPrevMatchIndex = ii;
-                return md;
-            }
-        }
-        mPrevMatchIndex = -1;
-        return null;
-    }
-
-    public MethodData findMatchingName(String name) {
-        return doMatchName(name, 0);
-    }
-
-    public MethodData findNextMatchingName(String name) {
-        return doMatchName(name, mPrevMatchIndex + 1);
-    }
-
-    public MethodData findMatchingTreeItem(TreeItem item) {
-        if (item == null)
-            return null;
-        String text = item.getText();
-        if (Character.isDigit(text.charAt(0)) == false)
-            return null;
-        int spaceIndex = text.indexOf(' ');
-        String numstr = text.substring(0, spaceIndex);
-        int rank = Integer.valueOf(numstr);
-        for (MethodData md : mRoots) {
-            if (md.getRank() == rank)
-                return md;
-        }
-        return null;
-    }
-
-    public void setTreeViewer(TreeViewer treeViewer) {
-        mTreeViewer = treeViewer;
-    }
-
-    public String[] getColumnNames() {
-        return mColumnNames;
-    }
-
-    public int[] getColumnWidths() {
-        return mColumnWidths;
-    }
-
-    public int[] getColumnAlignments() {
-        return mColumnAlignments;
-    }
-
-    public Object[] getChildren(Object element) {
-        if (element instanceof MethodData) {
-            MethodData md = (MethodData) element;
-            return md.getProfileNodes();
-        }
-        if (element instanceof ProfileNode) {
-            ProfileNode pn = (ProfileNode) element;
-            return pn.getChildren();
-        }
-        return new Object[0];
-    }
-
-    public Object getParent(Object element) {
-        return null;
-    }
-
-    public boolean hasChildren(Object element) {
-        if (element instanceof MethodData)
-            return true;
-        if (element instanceof ProfileNode)
-            return true;
-        return false;
-    }
-
-    public Object[] getElements(Object element) {
-        return mRoots;
-    }
-
-    public void dispose() {
-    }
-
-    public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
-    }
-
-    public Object getRoot() {
-        return "root";
-    }
-
-    public SelectionAdapter getColumnListener() {
-        if (mListener == null)
-            mListener = new ColumnListener();
-        return mListener;
-    }
-
-    public LabelProvider getLabelProvider() {
-        return new ProfileLabelProvider();
-    }
-
-    class ProfileLabelProvider extends LabelProvider implements
-            ITableLabelProvider, IColorProvider {
-        Color colorRed;
-        Color colorParentsBack;
-        Color colorChildrenBack;
-        TraceUnits traceUnits;
-
-        public ProfileLabelProvider() {
-            Display display = Display.getCurrent();
-            colorRed = display.getSystemColor(SWT.COLOR_RED);
-            colorParentsBack = new Color(display, 230, 230, 255); // blue
-            colorChildrenBack = new Color(display, 255, 255, 210); // yellow
-            traceUnits = mReader.getTraceUnits();
-        }
-
-        public String getColumnText(Object element, int col) {
-            if (element instanceof MethodData) {
-                MethodData md = (MethodData) element;
-                if (col == COL_NAME)
-                    return md.getProfileName();
-                if (col == COL_EXCLUSIVE) {
-                    double val = md.getElapsedExclusive();
-                    val = traceUnits.getScaledValue(val);
-                    return String.format("%.3f", val);
-                }
-                if (col == COL_EXCLUSIVE_PER) {
-                    double val = md.getElapsedExclusive();
-                    double per = val * 100.0 / mTotalTime;
-                    return String.format("%.1f%%", per);
-                }
-                if (col == COL_INCLUSIVE) {
-                    double val = md.getElapsedInclusive();
-                    val = traceUnits.getScaledValue(val);
-                    return String.format("%.3f", val);
-                }
-                if (col == COL_INCLUSIVE_PER) {
-                    double val = md.getElapsedInclusive();
-                    double per = val * 100.0 / mTotalTime;
-                    return String.format("%.1f%%", per);
-                }
-                if (col == COL_CALLS)
-                    return md.getCalls();
-                if (col == COL_TIME_PER_CALL) {
-                    int numCalls = md.getTotalCalls();
-                    double val = md.getElapsedInclusive();
-                    val = val / numCalls;
-                    val = traceUnits.getScaledValue(val);
-                    return String.format("%.3f", val);
-                }
-            } else if (element instanceof ProfileSelf) {
-                ProfileSelf ps = (ProfileSelf) element;
-                if (col == COL_NAME)
-                    return ps.getProfileName();
-                if (col == COL_INCLUSIVE) {
-                    double val = ps.getElapsedInclusive();
-                    val = traceUnits.getScaledValue(val);
-                    return String.format("%.3f", val);
-                }
-                if (col == COL_INCLUSIVE_PER) {
-                    double total;
-                    double val = ps.getElapsedInclusive();
-                    MethodData context = ps.getContext();
-                    total = context.getElapsedInclusive();
-                    double per = val * 100.0 / total;
-                    return String.format("%.1f%%", per);
-                }
-                return "";
-            } else if (element instanceof ProfileData) {
-                ProfileData pd = (ProfileData) element;
-                if (col == COL_NAME)
-                    return pd.getProfileName();
-                if (col == COL_INCLUSIVE) {
-                    double val = pd.getElapsedInclusive();
-                    val = traceUnits.getScaledValue(val);
-                    return String.format("%.3f", val);
-                }
-                if (col == COL_INCLUSIVE_PER) {
-                    double total;
-                    double val = pd.getElapsedInclusive();
-                    MethodData context = pd.getContext();
-                    total = context.getElapsedInclusive();
-                    double per = val * 100.0 / total;
-                    return String.format("%.1f%%", per);
-                }
-                if (col == COL_CALLS)
-                    return pd.getNumCalls();
-                return "";
-            } else if (element instanceof ProfileNode) {
-                ProfileNode pn = (ProfileNode) element;
-                if (col == COL_NAME)
-                    return pn.getLabel();
-                return "";
-            }
-            return "col" + col;
-        }
-
-        public Image getColumnImage(Object element, int col) {
-            if (col != COL_NAME)
-                return null;
-            if (element instanceof MethodData) {
-                MethodData md = (MethodData) element;
-                return md.getImage();
-            }
-            if (element instanceof ProfileData) {
-                ProfileData pd = (ProfileData) element;
-                MethodData md = pd.getMethodData();
-                return md.getImage();
-            }
-            return null;
-        }
-
-        public Color getForeground(Object element) {
-            return null;
-        }
-
-        public Color getBackground(Object element) {
-            if (element instanceof ProfileData) {
-                ProfileData pd = (ProfileData) element;
-                if (pd.isParent())
-                    return colorParentsBack;
-                return colorChildrenBack;
-            }
-            if (element instanceof ProfileNode) {
-                ProfileNode pn = (ProfileNode) element;
-                if (pn.isParent())
-                    return colorParentsBack;
-                return colorChildrenBack;
-            }
-            return null;
-        }
-    }
-
-    class ColumnListener extends SelectionAdapter {
-        MethodData.Sorter sorter = new MethodData.Sorter();
-
-        @Override
-        public void widgetSelected(SelectionEvent event) {
-            TreeColumn column = (TreeColumn) event.widget;
-            String name = column.getText();
-            Tree tree = column.getParent();
-            tree.setRedraw(false);
-            TreeColumn[] columns = tree.getColumns();
-            for (TreeColumn col : columns) {
-                col.setImage(null);
-            }
-            if (name == mColumnNames[COL_NAME]) {
-                // Sort names alphabetically
-                sorter.setColumn(MethodData.Sorter.Column.BY_NAME);
-                Arrays.sort(mRoots, sorter);
-            } else if (name == mColumnNames[COL_EXCLUSIVE]) {
-                sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE);
-                Arrays.sort(mRoots, sorter);
-            } else if (name == mColumnNames[COL_EXCLUSIVE_PER]) {
-                sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE);
-                Arrays.sort(mRoots, sorter);
-            } else if (name == mColumnNames[COL_INCLUSIVE]) {
-                sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE);
-                Arrays.sort(mRoots, sorter);
-            } else if (name == mColumnNames[COL_INCLUSIVE_PER]) {
-                sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE);
-                Arrays.sort(mRoots, sorter);
-            } else if (name == mColumnNames[COL_CALLS]) {
-                sorter.setColumn(MethodData.Sorter.Column.BY_CALLS);
-                Arrays.sort(mRoots, sorter);
-            } else if (name == mColumnNames[COL_TIME_PER_CALL]) {
-                sorter.setColumn(MethodData.Sorter.Column.BY_TIME_PER_CALL);
-                Arrays.sort(mRoots, sorter);
-            }
-            MethodData.Sorter.Direction direction = sorter.getDirection();
-            if (direction == MethodData.Sorter.Direction.INCREASING)
-                column.setImage(mSortDown);
-            else
-                column.setImage(mSortUp);
-            tree.setRedraw(true);
-            mTreeViewer.refresh();
-        }
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/ProfileSelf.java b/tools/traceview/src/com/android/traceview/ProfileSelf.java
deleted file mode 100644
index 3a4f3d9..0000000
--- a/tools/traceview/src/com/android/traceview/ProfileSelf.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-public class ProfileSelf extends ProfileData {
-    public ProfileSelf(MethodData methodData) {
-        mElement = methodData;
-        mContext = methodData;
-    }
-
-    @Override
-    public String getProfileName() {
-        return "self";
-    }
-
-    @Override
-    public long getElapsedInclusive() {
-        return mElement.getTopExclusive();
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/ProfileView.java b/tools/traceview/src/com/android/traceview/ProfileView.java
deleted file mode 100644
index e48cb56..0000000
--- a/tools/traceview/src/com/android/traceview/ProfileView.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.util.ArrayList;
-import java.util.Observable;
-import java.util.Observer;
-
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeViewerListener;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TreeExpansionEvent;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
-
-public class ProfileView extends Composite implements Observer {
-    
-    private TreeViewer mTreeViewer;
-    private Text mSearchBox;
-    private SelectionController mSelectionController;
-    private ProfileProvider mProfileProvider;
-    private Color mColorNoMatch;
-    private Color mColorMatch;
-    private MethodData mCurrentHighlightedMethod;
-
-    public ProfileView(Composite parent, TraceReader reader,
-            SelectionController selectController) {
-        super(parent, SWT.NONE);
-        setLayout(new GridLayout(1, false));
-        this.mSelectionController = selectController;
-        mSelectionController.addObserver(this);
-
-        // Add a tree viewer at the top
-        mTreeViewer = new TreeViewer(this, SWT.MULTI | SWT.NONE);
-        mTreeViewer.setUseHashlookup(true);
-        mProfileProvider = reader.getProfileProvider();
-        mProfileProvider.setTreeViewer(mTreeViewer);
-        SelectionAdapter listener = mProfileProvider.getColumnListener();
-        final Tree tree = mTreeViewer.getTree();
-        tree.setHeaderVisible(true);
-        tree.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-        // Get the column names from the ProfileProvider
-        String[] columnNames = mProfileProvider.getColumnNames();
-        int[] columnWidths = mProfileProvider.getColumnWidths();
-        int[] columnAlignments = mProfileProvider.getColumnAlignments();
-        for (int ii = 0; ii < columnWidths.length; ++ii) {
-            TreeColumn column = new TreeColumn(tree, SWT.LEFT);
-            column.setText(columnNames[ii]);
-            column.setWidth(columnWidths[ii]);
-            column.setMoveable(true);
-            column.addSelectionListener(listener);
-            column.setAlignment(columnAlignments[ii]);
-        }
-
-        // Add a listener to the tree so that we can make the row
-        // height smaller.
-        tree.addListener(SWT.MeasureItem, new Listener() {
-            public void handleEvent(Event event) {
-                int fontHeight = event.gc.getFontMetrics().getHeight();
-                event.height = fontHeight;
-            }
-        });
-
-        mTreeViewer.setContentProvider(mProfileProvider);
-        mTreeViewer.setLabelProvider(mProfileProvider.getLabelProvider());
-        mTreeViewer.setInput(mProfileProvider.getRoot());
-
-        // Create another composite to hold the label and text box
-        Composite composite = new Composite(this, SWT.NONE);
-        composite.setLayout(new GridLayout(2, false));
-        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        // Add a label for the search box
-        Label label = new Label(composite, SWT.NONE);
-        label.setText("Find:");
-
-        // Add a text box for searching for method names
-        mSearchBox = new Text(composite, SWT.BORDER);
-        mSearchBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        Display display = getDisplay();
-        mColorNoMatch = new Color(display, 255, 200, 200);
-        mColorMatch = mSearchBox.getBackground();
-
-        mSearchBox.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent ev) {
-                String query = mSearchBox.getText();
-                if (query.length() == 0)
-                    return;
-                findName(query);
-            }
-        });
-
-        // Add a key listener to the text box so that we can clear
-        // the text box if the user presses <ESC>.
-        mSearchBox.addKeyListener(new KeyAdapter() {
-            @Override
-            public void keyPressed(KeyEvent event) {
-                if (event.keyCode == SWT.ESC) {
-                    mSearchBox.setText("");
-                } else if (event.keyCode == SWT.CR) {
-                    String query = mSearchBox.getText();
-                    if (query.length() == 0)
-                        return;
-                    findNextName(query);
-                }
-            }
-        });
-
-        // Also add a key listener to the tree viewer so that the
-        // user can just start typing anywhere in the tree view.
-        tree.addKeyListener(new KeyAdapter() {
-            @Override
-            public void keyPressed(KeyEvent event) {
-                if (event.keyCode == SWT.ESC) {
-                    mSearchBox.setText("");
-                } else if (event.keyCode == SWT.BS) {
-                    // Erase the last character from the search box
-                    String text = mSearchBox.getText();
-                    int len = text.length();
-                    String chopped;
-                    if (len <= 1)
-                        chopped = "";
-                    else
-                        chopped = text.substring(0, len - 1);
-                    mSearchBox.setText(chopped);
-                } else if (event.keyCode == SWT.CR) {
-                    String query = mSearchBox.getText();
-                    if (query.length() == 0)
-                        return;
-                    findNextName(query);
-                } else {
-                    // Append the given character to the search box
-                    String str = String.valueOf(event.character);
-                    mSearchBox.append(str);
-                }
-                event.doit = false;
-            }
-        });
-
-        // Add a selection listener to the tree so that the user can click
-        // on a method that is a child or parent and jump to that method.
-        mTreeViewer
-                .addSelectionChangedListener(new ISelectionChangedListener() {
-                    public void selectionChanged(SelectionChangedEvent ev) {
-                        ISelection sel = ev.getSelection();
-                        if (sel.isEmpty())
-                            return;
-                        if (sel instanceof IStructuredSelection) {
-                            IStructuredSelection selection = (IStructuredSelection) sel;
-                            Object element = selection.getFirstElement();
-                            if (element == null)
-                                return;
-                            if (element instanceof MethodData) {
-                                MethodData md = (MethodData) element;
-                                highlightMethod(md, true);
-                            }
-                            if (element instanceof ProfileData) {
-                                MethodData md = ((ProfileData) element)
-                                        .getMethodData();
-                                highlightMethod(md, true);
-                            }
-                        }
-                    }
-                });
-        
-        // Add a tree listener so that we can expand the parents and children
-        // of a method when a method is expanded.
-        mTreeViewer.addTreeListener(new ITreeViewerListener() {
-            public void treeExpanded(TreeExpansionEvent event) {
-                Object element = event.getElement();
-                if (element instanceof MethodData) {
-                    MethodData md = (MethodData) element;
-                    expandNode(md);
-                }
-            }
-            public void treeCollapsed(TreeExpansionEvent event) {
-            }
-        });
-
-        tree.addListener(SWT.MouseDown, new Listener() {
-            public void handleEvent(Event event) {
-                Point point = new Point(event.x, event.y);
-                TreeItem treeItem = tree.getItem(point);
-                MethodData md = mProfileProvider.findMatchingTreeItem(treeItem);
-                if (md == null)
-                    return;
-                ArrayList<Selection> selections = new ArrayList<Selection>();
-                selections.add(Selection.highlight("MethodData", md));
-                mSelectionController.change(selections, "ProfileView");
-            }
-        });
-    }
-
-    private void findName(String query) {
-        MethodData md = mProfileProvider.findMatchingName(query);
-        selectMethod(md);
-    }
-
-    private void findNextName(String query) {
-        MethodData md = mProfileProvider.findNextMatchingName(query);
-        selectMethod(md);
-    }
-
-    private void selectMethod(MethodData md) {
-        if (md == null) {
-            mSearchBox.setBackground(mColorNoMatch);
-            return;
-        }
-        mSearchBox.setBackground(mColorMatch);
-        highlightMethod(md, false);
-    }
-
-    public void update(Observable objservable, Object arg) {
-        // Ignore updates from myself
-        if (arg == "ProfileView")
-            return;
-        // System.out.printf("profileview update from %s\n", arg);
-        ArrayList<Selection> selections;
-        selections = mSelectionController.getSelections();
-        for (Selection selection : selections) {
-            Selection.Action action = selection.getAction();
-            if (action != Selection.Action.Highlight)
-                continue;
-            String name = selection.getName();
-            if (name == "MethodData") {
-                MethodData md = (MethodData) selection.getValue();
-                highlightMethod(md, true);
-                return;
-            }
-            if (name == "Call") {
-                Call call = (Call) selection.getValue();
-                MethodData md = call.mMethodData;
-                highlightMethod(md, true);
-                return;
-            }
-        }
-    }
-
-    private void highlightMethod(MethodData md, boolean clearSearch) {
-        if (md == null)
-            return;
-        // Avoid an infinite recursion
-        if (md == mCurrentHighlightedMethod)
-            return;
-        if (clearSearch) {
-            mSearchBox.setText("");
-            mSearchBox.setBackground(mColorMatch);
-        }
-        mCurrentHighlightedMethod = md;
-        mTreeViewer.collapseAll();
-        // Expand this node and its children
-        expandNode(md);
-        StructuredSelection sel = new StructuredSelection(md);
-        mTreeViewer.setSelection(sel, true);
-        Tree tree = mTreeViewer.getTree();
-        TreeItem[] items = tree.getSelection();
-        tree.setTopItem(items[0]);
-        // workaround a Mac bug by adding showItem().
-        tree.showItem(items[0]);
-    }
-
-    private void expandNode(MethodData md) {
-        ProfileNode[] nodes = md.getProfileNodes();
-        mTreeViewer.setExpandedState(md, true);
-        // Also expand the "Parents" and "Children" nodes.
-        for (ProfileNode node : nodes) {
-            if (node.isRecursive() == false)
-                mTreeViewer.setExpandedState(node, true);
-        }
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/QtraceReader.java b/tools/traceview/src/com/android/traceview/QtraceReader.java
deleted file mode 100644
index c4db4a2..0000000
--- a/tools/traceview/src/com/android/traceview/QtraceReader.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class QtraceReader extends TraceReader {
-    QtraceReader(String traceName) {
-    }
-
-    @Override
-    public MethodData[] getMethods() {
-        return null;
-    }
-
-    @Override
-    public HashMap<Integer, String> getThreadLabels() {
-        return null;
-    }
-
-    @Override
-    public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
-        return null;
-    }
-
-    @Override
-    public ProfileProvider getProfileProvider() {
-        return null;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/Selection.java b/tools/traceview/src/com/android/traceview/Selection.java
deleted file mode 100644
index 3764619..0000000
--- a/tools/traceview/src/com/android/traceview/Selection.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-public class Selection {
-
-    private Action mAction;
-    private String mName;
-    private Object mValue;
-
-    public Selection(Action action, String name, Object value) {
-        mAction = action;
-        mName = name;
-        mValue = value;
-    }
-
-    public static Selection highlight(String name, Object value) {
-        return new Selection(Action.Highlight, name, value);
-    }
-
-    public static Selection include(String name, Object value) {
-        return new Selection(Action.Include, name, value);
-    }
-
-    public static Selection exclude(String name, Object value) {
-        return new Selection(Action.Exclude, name, value);
-    }
-
-    public void setName(String name) {
-        mName = name;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public void setValue(Object value) {
-        mValue = value;
-    }
-
-    public Object getValue() {
-        return mValue;
-    }
-
-    public void setAction(Action action) {
-        mAction = action;
-    }
-
-    public Action getAction() {
-        return mAction;
-    }
-
-    public static enum Action {
-        Highlight, Include, Exclude, Aggregate
-    };
-}
diff --git a/tools/traceview/src/com/android/traceview/SelectionController.java b/tools/traceview/src/com/android/traceview/SelectionController.java
deleted file mode 100644
index 4c930ea..0000000
--- a/tools/traceview/src/com/android/traceview/SelectionController.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.util.ArrayList;
-import java.util.Observable;
-
-public class SelectionController extends Observable {
-
-    private ArrayList<Selection> mSelections;
-
-    public void change(ArrayList<Selection> selections, Object arg) {
-        this.mSelections = selections;
-        setChanged();
-        notifyObservers(arg);
-    }
-
-    public ArrayList<Selection> getSelections() {
-        return mSelections;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/ThreadData.java b/tools/traceview/src/com/android/traceview/ThreadData.java
deleted file mode 100644
index 54ea891..0000000
--- a/tools/traceview/src/com/android/traceview/ThreadData.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-class ThreadData implements TimeLineView.Row {
-
-    private int mId;
-    private String mName;
-    private long mGlobalStartTime = -1;
-    private long mGlobalEndTime = -1;
-    private long mLastEventTime;
-    private long mCpuTime;
-    private Call mRoot;
-    private Call mCurrent;
-    private Call mLastContextSwitch;
-    private ArrayList<Call> mStack = new ArrayList<Call>();
-    
-    // This is a hash of all the methods that are currently on the stack.
-    private HashMap<MethodData, Integer> mStackMethods = new HashMap<MethodData, Integer>();
-    
-    // True if no calls have ever been added to this thread
-    private boolean mIsEmpty;
-
-    ThreadData(int id, String name, MethodData topLevel) {
-        mId = id;
-        mName = String.format("[%d] %s", id, name);
-        mRoot = new Call(mName, topLevel);
-        mCurrent = mRoot;
-        mIsEmpty = true;
-    }
-
-    public boolean isEmpty() {
-        return mIsEmpty;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public Call getCalltreeRoot() {
-        return mRoot;
-    }
-
-    void handleCall(Call call, long globalTime) {
-        mIsEmpty = false;
-        long currentTime = call.mThreadStartTime;
-        if (currentTime < mLastEventTime) {
-            System.err
-            .printf(
-                    "ThreadData: '%1$s' call time (%2$d) is less than previous time (%3$d) for thread '%4$s'\n",
-                    call.getName(), currentTime, mLastEventTime, mName);
-            System.exit(1);
-        }
-        long elapsed = currentTime - mLastEventTime;
-        mCpuTime += elapsed;
-        if (call.getMethodAction() == 0) {
-            // This is a method entry.
-            enter(call, elapsed);
-        } else {
-            // This is a method exit.
-            exit(call, elapsed, globalTime);
-        }
-        mLastEventTime = currentTime;
-        mGlobalEndTime = globalTime;
-    }
-
-    private void enter(Call c, long elapsed) {
-        Call caller = mCurrent;
-        push(c);
-        
-        // Check the stack for a matching method to determine if this call
-        // is recursive.
-        MethodData md = c.mMethodData;
-        Integer num = mStackMethods.get(md);
-        if (num == null) {
-            num = 0;
-        } else if (num > 0) {
-            c.setRecursive(true);
-        }
-        num += 1;
-        mStackMethods.put(md, num);
-        mCurrent = c;
-
-        // Add the elapsed time to the caller's exclusive time
-        caller.addExclusiveTime(elapsed);
-    }
-
-    private void exit(Call c, long elapsed, long globalTime) {
-        mCurrent.mGlobalEndTime = globalTime;
-        Call top = pop();
-        if (top == null) {
-            return;
-        }
-
-        if (mCurrent.mMethodData != c.mMethodData) {
-            String error = "Method exit (" + c.getName()
-                    + ") does not match current method (" + mCurrent.getName()
-                    + ")";
-            throw new RuntimeException(error);
-        } else {
-            long duration = c.mThreadStartTime - mCurrent.mThreadStartTime;
-            Call caller = top();
-            mCurrent.addExclusiveTime(elapsed);
-            mCurrent.addInclusiveTime(duration, caller);
-            if (caller == null) {
-                caller = mRoot;
-            }
-            mCurrent = caller;
-        }
-    }
-
-    public void push(Call c) {
-        mStack.add(c);
-    }
-
-    public Call pop() {
-        ArrayList<Call> stack = mStack;
-        if (stack.size() == 0)
-            return null;
-        Call top = stack.get(stack.size() - 1);
-        stack.remove(stack.size() - 1);
-        
-        // Decrement the count on the method in the hash table and remove
-        // the entry when it goes to zero.
-        MethodData md = top.mMethodData;
-        Integer num = mStackMethods.get(md);
-        if (num != null) {
-            num -= 1;
-            if (num <= 0) {
-                mStackMethods.remove(md);
-            } else {
-                mStackMethods.put(md, num);
-            }
-        }
-        return top;
-    }
-
-    public Call top() {
-        ArrayList<Call> stack = mStack;
-        if (stack.size() == 0)
-            return null;
-        return stack.get(stack.size() - 1);
-    }
-
-    public long endTrace() {
-        // If we have calls on the stack when the trace ends, then clean up
-        // the stack and compute the inclusive time of the methods by pretending
-        // that we are exiting from their methods now.
-        while (mCurrent != mRoot) {
-            long duration = mLastEventTime - mCurrent.mThreadStartTime;
-            pop();
-            Call caller = top();
-            mCurrent.addInclusiveTime(duration, caller);
-            mCurrent.mGlobalEndTime = mGlobalEndTime;
-            if (caller == null) {
-                caller = mRoot;
-            }
-            mCurrent = caller;
-        }
-        return mLastEventTime;
-    }
-
-    @Override
-    public String toString() {
-        return mName;
-    }
-
-    public int getId() {
-        return mId;
-    }
-
-    public void setCpuTime(long cpuTime) {
-        mCpuTime = cpuTime;
-    }
-
-    public long getCpuTime() {
-        return mCpuTime;
-    }
-
-    public void setGlobalStartTime(long globalStartTime) {
-        mGlobalStartTime = globalStartTime;
-    }
-
-    public long getGlobalStartTime() {
-        return mGlobalStartTime;
-    }
-
-    public void setLastEventTime(long lastEventTime) {
-        mLastEventTime = lastEventTime;
-    }
-
-    public long getLastEventTime() {
-        return mLastEventTime;
-    }
-
-    public void setGlobalEndTime(long globalEndTime) {
-        mGlobalEndTime = globalEndTime;
-    }
-
-    public long getGlobalEndTime() {
-        return mGlobalEndTime;
-    }
-
-    public void setLastContextSwitch(Call lastContextSwitch) {
-        mLastContextSwitch = lastContextSwitch;
-    }
-
-    public Call getLastContextSwitch() {
-        return mLastContextSwitch;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/TickScaler.java b/tools/traceview/src/com/android/traceview/TickScaler.java
deleted file mode 100644
index 79fa160..0000000
--- a/tools/traceview/src/com/android/traceview/TickScaler.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-class TickScaler {
-
-    private double mMinVal; // required input
-    private double mMaxVal; // required input
-    private double mRangeVal;
-    private int mNumPixels; // required input
-    private int mPixelsPerTick; // required input
-    private double mPixelsPerRange;
-    private double mTickIncrement;
-    private double mMinMajorTick;
-
-    TickScaler(double minVal, double maxVal, int numPixels, int pixelsPerTick) {
-        mMinVal = minVal;
-        mMaxVal = maxVal;
-        mNumPixels = numPixels;
-        mPixelsPerTick = pixelsPerTick;
-    }
-
-    public void setMinVal(double minVal) {
-        mMinVal = minVal;
-    }
-
-    public double getMinVal() {
-        return mMinVal;
-    }
-
-    public void setMaxVal(double maxVal) {
-        mMaxVal = maxVal;
-    }
-
-    public double getMaxVal() {
-        return mMaxVal;
-    }
-
-    public void setNumPixels(int numPixels) {
-        mNumPixels = numPixels;
-    }
-
-    public int getNumPixels() {
-        return mNumPixels;
-    }
-
-    public void setPixelsPerTick(int pixelsPerTick) {
-        mPixelsPerTick = pixelsPerTick;
-    }
-
-    public int getPixelsPerTick() {
-        return mPixelsPerTick;
-    }
-
-    public void setPixelsPerRange(double pixelsPerRange) {
-        mPixelsPerRange = pixelsPerRange;
-    }
-
-    public double getPixelsPerRange() {
-        return mPixelsPerRange;
-    }
-
-    public void setTickIncrement(double tickIncrement) {
-        mTickIncrement = tickIncrement;
-    }
-
-    public double getTickIncrement() {
-        return mTickIncrement;
-    }
-
-    public void setMinMajorTick(double minMajorTick) {
-        mMinMajorTick = minMajorTick;
-    }
-
-    public double getMinMajorTick() {
-        return mMinMajorTick;
-    }
-
-    // Convert a time value to a 0-based pixel value
-    public int valueToPixel(double value) {
-        return (int) Math.ceil(mPixelsPerRange * (value - mMinVal) - 0.5);
-    }
-
-    // Convert a time value to a 0-based fractional pixel
-    public double valueToPixelFraction(double value) {
-        return mPixelsPerRange * (value - mMinVal);
-    }
-
-    // Convert a 0-based pixel value to a time value
-    public double pixelToValue(int pixel) {
-        return mMinVal + (pixel / mPixelsPerRange);
-    }
-
-    public void computeTicks(boolean useGivenEndPoints) {
-        int numTicks = mNumPixels / mPixelsPerTick;
-        mRangeVal = mMaxVal - mMinVal;
-        mTickIncrement = mRangeVal / numTicks;
-        double dlogTickIncrement = Math.log10(mTickIncrement);
-        int logTickIncrement = (int) Math.floor(dlogTickIncrement);
-        double scale = Math.pow(10, logTickIncrement);
-        double scaledTickIncr = mTickIncrement / scale;
-        if (scaledTickIncr > 5.0)
-            scaledTickIncr = 10;
-        else if (scaledTickIncr > 2)
-            scaledTickIncr = 5;
-        else if (scaledTickIncr > 1)
-            scaledTickIncr = 2;
-        else
-            scaledTickIncr = 1;
-        mTickIncrement = scaledTickIncr * scale;
-
-        if (!useGivenEndPoints) {
-            // Round up the max val to the next minor tick
-            double minorTickIncrement = mTickIncrement / 5;
-            double dval = mMaxVal / minorTickIncrement;
-            int ival = (int) dval;
-            if (ival != dval)
-                mMaxVal = (ival + 1) * minorTickIncrement;
-
-            // Round down the min val to a multiple of tickIncrement
-            ival = (int) (mMinVal / mTickIncrement);
-            mMinVal = ival * mTickIncrement;
-            mMinMajorTick = mMinVal;
-        } else {
-            int ival = (int) (mMinVal / mTickIncrement);
-            mMinMajorTick = ival * mTickIncrement;
-            if (mMinMajorTick < mMinVal)
-                mMinMajorTick = mMinMajorTick + mTickIncrement;
-        }
-
-        mRangeVal = mMaxVal - mMinVal;
-        mPixelsPerRange = (double) mNumPixels / mRangeVal;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/TimeLineView.java b/tools/traceview/src/com/android/traceview/TimeLineView.java
deleted file mode 100644
index 67dc97b..0000000
--- a/tools/traceview/src/com/android/traceview/TimeLineView.java
+++ /dev/null
@@ -1,1961 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import org.eclipse.jface.resource.FontRegistry;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.ScrollBar;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Observable;
-import java.util.Observer;
-
-public class TimeLineView extends Composite implements Observer {
-
-    private HashMap<String, RowData> mRowByName;
-    private double mTotalElapsed;
-    private RowData[] mRows;
-    private Segment[] mSegments;
-    private ArrayList<Segment> mSegmentList = new ArrayList<Segment>();
-    private HashMap<Integer, String> mThreadLabels;
-    private Timescale mTimescale;
-    private Surface mSurface;
-    private RowLabels mLabels;
-    private SashForm mSashForm;
-    private int mScrollOffsetY;
-
-    public static final int PixelsPerTick = 50;
-    private TickScaler mScaleInfo = new TickScaler(0, 0, 0, PixelsPerTick);
-    private static final int LeftMargin = 10; // blank space on left
-    private static final int RightMargin = 60; // blank space on right
-
-    private Color mColorBlack;
-    private Color mColorGray;
-    private Color mColorDarkGray;
-    private Color mColorForeground;
-    private Color mColorRowBack;
-    private Color mColorZoomSelection;
-    private FontRegistry mFontRegistry;
-
-    /** vertical height of drawn blocks in each row */
-    private static final int rowHeight = 20;
-
-    /** the blank space between rows */
-    private static final int rowYMargin = 12;
-    private static final int rowYMarginHalf = rowYMargin / 2;
-
-    /** total vertical space for row */
-    private static final int rowYSpace = rowHeight + rowYMargin;
-    private static final int majorTickLength = 8;
-    private static final int minorTickLength = 4;
-    private static final int timeLineOffsetY = 38;
-    private static final int tickToFontSpacing = 2;
-
-    /** start of first row */
-    private static final int topMargin = 70;
-    private int mMouseRow = -1;
-    private int mNumRows;
-    private int mStartRow;
-    private int mEndRow;
-    private TraceUnits mUnits;
-    private int mSmallFontWidth;
-    private int mSmallFontHeight;
-    private int mMediumFontWidth;
-    private SelectionController mSelectionController;
-    private MethodData mHighlightMethodData;
-    private Call mHighlightCall;
-    private static final int MinInclusiveRange = 3;
-
-    /** Setting the fonts looks good on Linux but bad on Macs */
-    private boolean mSetFonts = false;
-
-    public static interface Block {
-        public String getName();
-        public MethodData getMethodData();
-        public long getStartTime();
-        public long getEndTime();
-        public Color getColor();
-        public double addWeight(int x, int y, double weight);
-        public void clearWeight();
-    }
-
-    public static interface Row {
-        public int getId();
-        public String getName();
-    }
-
-    public static class Record {
-        Row row;
-        Block block;
-
-        public Record(Row row, Block block) {
-            this.row = row;
-            this.block = block;
-        }
-    }
-
-    public TimeLineView(Composite parent, TraceReader reader,
-            SelectionController selectionController) {
-        super(parent, SWT.NONE);
-        mRowByName = new HashMap<String, RowData>();
-        this.mSelectionController = selectionController;
-        selectionController.addObserver(this);
-        mUnits = reader.getTraceUnits();
-        mThreadLabels = reader.getThreadLabels();
-
-        Display display = getDisplay();
-        mColorGray = display.getSystemColor(SWT.COLOR_GRAY);
-        mColorDarkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
-        mColorBlack = display.getSystemColor(SWT.COLOR_BLACK);
-        // mColorBackground = display.getSystemColor(SWT.COLOR_WHITE);
-        mColorForeground = display.getSystemColor(SWT.COLOR_BLACK);
-        mColorRowBack = new Color(display, 240, 240, 255);
-        mColorZoomSelection = new Color(display, 230, 230, 230);
-
-        mFontRegistry = new FontRegistry(display);
-        mFontRegistry.put("small",  // $NON-NLS-1$
-                new FontData[] { new FontData("Arial", 8, SWT.NORMAL) });  // $NON-NLS-1$
-        mFontRegistry.put("courier8",  // $NON-NLS-1$
-                new FontData[] { new FontData("Courier New", 8, SWT.BOLD) });  // $NON-NLS-1$
-        mFontRegistry.put("medium",  // $NON-NLS-1$
-                new FontData[] { new FontData("Courier New", 10, SWT.NORMAL) });  // $NON-NLS-1$
-
-        Image image = new Image(display, new Rectangle(100, 100, 100, 100));
-        GC gc = new GC(image);
-        if (mSetFonts) {
-            gc.setFont(mFontRegistry.get("small"));  // $NON-NLS-1$
-        }
-        mSmallFontWidth = gc.getFontMetrics().getAverageCharWidth();
-        mSmallFontHeight = gc.getFontMetrics().getHeight();
-
-        if (mSetFonts) {
-            gc.setFont(mFontRegistry.get("medium"));  // $NON-NLS-1$
-        }
-        mMediumFontWidth = gc.getFontMetrics().getAverageCharWidth();
-
-        image.dispose();
-        gc.dispose();
-
-        setLayout(new FillLayout());
-
-        // Create a sash form for holding two canvas views, one for the
-        // thread labels and one for the thread timeline.
-        mSashForm = new SashForm(this, SWT.HORIZONTAL);
-        mSashForm.setBackground(mColorGray);
-        mSashForm.SASH_WIDTH = 3;
-
-        // Create a composite for the left side of the sash
-        Composite composite = new Composite(mSashForm, SWT.NONE);
-        GridLayout layout = new GridLayout(1, true /* make columns equal width */);
-        layout.marginHeight = 0;
-        layout.marginWidth = 0;
-        layout.verticalSpacing = 1;
-        composite.setLayout(layout);
-        
-        // Create a blank corner space in the upper left corner
-        BlankCorner corner = new BlankCorner(composite);
-        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
-        gridData.heightHint = topMargin;
-        corner.setLayoutData(gridData);
-        
-        // Add the thread labels below the blank corner.
-        mLabels = new RowLabels(composite);
-        gridData = new GridData(GridData.FILL_BOTH);
-        mLabels.setLayoutData(gridData);
-        
-        // Create another composite for the right side of the sash
-        composite = new Composite(mSashForm, SWT.NONE);
-        layout = new GridLayout(1, true /* make columns equal width */);
-        layout.marginHeight = 0;
-        layout.marginWidth = 0;
-        layout.verticalSpacing = 1;
-        composite.setLayout(layout);
-
-        mTimescale = new Timescale(composite);
-        gridData = new GridData(GridData.FILL_HORIZONTAL);
-        gridData.heightHint = topMargin;
-        mTimescale.setLayoutData(gridData);
-
-        mSurface = new Surface(composite);
-        gridData = new GridData(GridData.FILL_BOTH);
-        mSurface.setLayoutData(gridData);
-        mSashForm.setWeights(new int[] { 1, 5 });
-
-        final ScrollBar vBar = mSurface.getVerticalBar();
-        vBar.addListener(SWT.Selection, new Listener() {
-           public void handleEvent(Event e) {
-               mScrollOffsetY = vBar.getSelection();
-               Point dim = mSurface.getSize();
-               int newScrollOffsetY = computeVisibleRows(dim.y);
-               if (newScrollOffsetY != mScrollOffsetY) {
-                   mScrollOffsetY = newScrollOffsetY;
-                   vBar.setSelection(newScrollOffsetY);
-               }
-               mLabels.redraw();
-               mSurface.redraw();
-           }
-        });
-        
-        mSurface.addListener(SWT.Resize, new Listener() {
-            public void handleEvent(Event e) {
-                Point dim = mSurface.getSize();
-                
-                // If we don't need the scroll bar then don't display it.
-                if (dim.y >= mNumRows * rowYSpace) {
-                    vBar.setVisible(false);
-                } else {
-                    vBar.setVisible(true);
-                }
-                int newScrollOffsetY = computeVisibleRows(dim.y);
-                if (newScrollOffsetY != mScrollOffsetY) {
-                    mScrollOffsetY = newScrollOffsetY;
-                    vBar.setSelection(newScrollOffsetY);
-                }
-                
-                int spaceNeeded = mNumRows * rowYSpace;
-                vBar.setMaximum(spaceNeeded);
-                vBar.setThumb(dim.y);
-
-                mLabels.redraw();
-                mSurface.redraw();
-            }
-        });
-
-        mSurface.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mouseUp(MouseEvent me) {
-                mSurface.mouseUp(me);
-            }
-
-            @Override
-            public void mouseDown(MouseEvent me) {
-                mSurface.mouseDown(me);
-            }
-
-            @Override
-            public void mouseDoubleClick(MouseEvent me) {
-                mSurface.mouseDoubleClick(me);
-            }
-        });
-        
-        mSurface.addMouseMoveListener(new MouseMoveListener() {
-            public void mouseMove(MouseEvent me) {
-                mSurface.mouseMove(me);
-            }
-        });
-
-        mTimescale.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mouseUp(MouseEvent me) {
-                mTimescale.mouseUp(me);
-            }
-
-            @Override
-            public void mouseDown(MouseEvent me) {
-                mTimescale.mouseDown(me);
-            }
-
-            @Override
-            public void mouseDoubleClick(MouseEvent me) {
-                mTimescale.mouseDoubleClick(me);
-            }
-        });
-        
-        mTimescale.addMouseMoveListener(new MouseMoveListener() {
-            public void mouseMove(MouseEvent me) {
-                mTimescale.mouseMove(me);
-            }
-        });
-
-        mLabels.addMouseMoveListener(new MouseMoveListener() {
-            public void mouseMove(MouseEvent me) {
-                mLabels.mouseMove(me);
-            }
-        });
-
-        setData(reader.getThreadTimeRecords());
-    }
-
-    public void update(Observable objservable, Object arg) {
-        // Ignore updates from myself
-        if (arg == "TimeLineView")  // $NON-NLS-1$
-            return;
-        // System.out.printf("timeline update from %s\n", arg);
-        boolean foundHighlight = false;
-        ArrayList<Selection> selections;
-        selections = mSelectionController.getSelections();
-        for (Selection selection : selections) {
-            Selection.Action action = selection.getAction();
-            if (action != Selection.Action.Highlight)
-                continue;
-            String name = selection.getName();
-            // System.out.printf(" timeline highlight %s from %s\n", name, arg);
-            if (name == "MethodData") {  // $NON-NLS-1$
-                foundHighlight = true;
-                mHighlightMethodData = (MethodData) selection.getValue();
-                // System.out.printf(" method %s\n",
-                // highlightMethodData.getName());
-                mHighlightCall = null;
-                startHighlighting();
-            } else if (name == "Call") {  // $NON-NLS-1$
-                foundHighlight = true;
-                mHighlightCall = (Call) selection.getValue();
-                // System.out.printf(" call %s\n", highlightCall.getName());
-                mHighlightMethodData = null;
-                startHighlighting();
-            }
-        }
-        if (foundHighlight == false)
-            mSurface.clearHighlights();
-    }
-
-    public void setData(ArrayList<Record> records) {
-        if (records == null)
-            records = new ArrayList<Record>();
-
-        if (false) {
-            System.out.println("TimelineView() list of records:");  // $NON-NLS-1$
-            for (Record r : records) {
-                System.out.printf("row '%s' block '%s' [%d, %d]\n", r.row  // $NON-NLS-1$
-                        .getName(), r.block.getName(), r.block.getStartTime(),
-                        r.block.getEndTime());
-                if (r.block.getStartTime() > r.block.getEndTime()) {
-                    System.err.printf("Error: block startTime > endTime\n");  // $NON-NLS-1$
-                    System.exit(1);
-                }
-            }
-        }
-
-        // Sort the records into increasing start time, and decreasing end time
-        Collections.sort(records, new Comparator<Record>() {
-            public int compare(Record r1, Record r2) {
-                long start1 = r1.block.getStartTime();
-                long start2 = r2.block.getStartTime();
-                if (start1 > start2)
-                    return 1;
-                if (start1 < start2)
-                    return -1;
-
-                // The start times are the same, so compare the end times
-                long end1 = r1.block.getEndTime();
-                long end2 = r2.block.getEndTime();
-                if (end1 > end2)
-                    return -1;
-                if (end1 < end2)
-                    return 1;
-
-                return 0;
-            }
-        });
-
-        // The records are sorted into increasing start time,
-        // so the minimum start time is the start time of the first record.
-        double minVal = 0;
-        if (records.size() > 0)
-            minVal = records.get(0).block.getStartTime();
-
-        // Sum the time spent in each row and block, and
-        // keep track of the maximum end time.
-        double maxVal = 0;
-        for (Record rec : records) {
-            Row row = rec.row;
-            Block block = rec.block;
-            String rowName = row.getName();
-            RowData rd = mRowByName.get(rowName);
-            if (rd == null) {
-                rd = new RowData(row);
-                mRowByName.put(rowName, rd);
-            }
-            long blockStartTime = block.getStartTime();
-            long blockEndTime = block.getEndTime();
-            if (blockEndTime > rd.mEndTime) {
-                long start = Math.max(blockStartTime, rd.mEndTime);
-                rd.mElapsed += blockEndTime - start;
-                mTotalElapsed += blockEndTime - start;
-                rd.mEndTime = blockEndTime;
-            }
-            if (blockEndTime > maxVal)
-                maxVal = blockEndTime;
-
-            // Keep track of nested blocks by using a stack (for each row).
-            // Create a Segment object for each visible part of a block.
-            Block top = rd.top();
-            if (top == null) {
-                rd.push(block);
-                continue;
-            }
-
-            long topStartTime = top.getStartTime();
-            long topEndTime = top.getEndTime();
-            if (topEndTime >= blockStartTime) {
-                // Add this segment if it has a non-zero elapsed time.
-                if (topStartTime < blockStartTime) {
-                    Segment segment = new Segment(rd, top, topStartTime,
-                            blockStartTime);
-                    mSegmentList.add(segment);
-                }
-
-                // If this block starts where the previous (top) block ends,
-                // then pop off the top block.
-                if (topEndTime == blockStartTime)
-                    rd.pop();
-                rd.push(block);
-            } else {
-                // We may have to pop several frames here.
-                popFrames(rd, top, blockStartTime);
-                rd.push(block);
-            }
-        }
-
-        // Clean up the stack of each row
-        for (RowData rd : mRowByName.values()) {
-            Block top = rd.top();
-            popFrames(rd, top, Integer.MAX_VALUE);
-        }
-
-        mSurface.setRange(minVal, maxVal);
-        mSurface.setLimitRange(minVal, maxVal);
-
-        // Sort the rows into decreasing elapsed time
-        Collection<RowData> rv = mRowByName.values();
-        mRows = rv.toArray(new RowData[rv.size()]);
-        Arrays.sort(mRows, new Comparator<RowData>() {
-            public int compare(RowData rd1, RowData rd2) {
-                return (int) (rd2.mElapsed - rd1.mElapsed);
-            }
-        });
-
-        // Assign ranks to the sorted rows
-        for (int ii = 0; ii < mRows.length; ++ii) {
-            mRows[ii].mRank = ii;
-        }
-
-        // Compute the number of rows with data
-        mNumRows = 0;
-        for (int ii = 0; ii < mRows.length; ++ii) {
-            if (mRows[ii].mElapsed == 0)
-                break;
-            mNumRows += 1;
-        }
-
-        // Sort the blocks into increasing rows, and within rows into
-        // increasing start values.
-        mSegments = mSegmentList.toArray(new Segment[mSegmentList.size()]);
-        Arrays.sort(mSegments, new Comparator<Segment>() {
-            public int compare(Segment bd1, Segment bd2) {
-                RowData rd1 = bd1.mRowData;
-                RowData rd2 = bd2.mRowData;
-                int diff = rd1.mRank - rd2.mRank;
-                if (diff == 0) {
-                    long timeDiff = bd1.mStartTime - bd2.mStartTime;
-                    if (timeDiff == 0)
-                        timeDiff = bd1.mEndTime - bd2.mEndTime;
-                    return (int) timeDiff;
-                }
-                return diff;
-            }
-        });
-
-        if (false) {
-            for (Segment segment : mSegments) {
-                System.out.printf("seg '%s' [%6d, %6d] %s\n",
-                        segment.mRowData.mName, segment.mStartTime,
-                        segment.mEndTime, segment.mBlock.getName());
-                if (segment.mStartTime > segment.mEndTime) {
-                    System.err.printf("Error: segment startTime > endTime\n");
-                    System.exit(1);
-                }
-            }
-        }
-    }
-
-    private void popFrames(RowData rd, Block top, long startTime) {
-        long topEndTime = top.getEndTime();
-        long lastEndTime = top.getStartTime();
-        while (topEndTime <= startTime) {
-            if (topEndTime > lastEndTime) {
-                Segment segment = new Segment(rd, top, lastEndTime, topEndTime);
-                mSegmentList.add(segment);
-                lastEndTime = topEndTime;
-            }
-            rd.pop();
-            top = rd.top();
-            if (top == null)
-                return;
-            topEndTime = top.getEndTime();
-        }
-
-        // If we get here, then topEndTime > startTime
-        if (lastEndTime < startTime) {
-            Segment bd = new Segment(rd, top, lastEndTime, startTime);
-            mSegmentList.add(bd);
-        }
-    }
-
-    private class RowLabels extends Canvas {
-
-        /** The space between the row label and the sash line */
-        private static final int labelMarginX = 2;
-
-        public RowLabels(Composite parent) {
-            super(parent, SWT.NO_BACKGROUND);
-            addPaintListener(new PaintListener() {
-                public void paintControl(PaintEvent pe) {
-                    draw(pe.display, pe.gc);
-                }
-            });
-        }
-
-        private void mouseMove(MouseEvent me) {
-            int rownum = (me.y + mScrollOffsetY) / rowYSpace;
-            if (mMouseRow != rownum) {
-                mMouseRow = rownum;
-                redraw();
-                mSurface.redraw();
-            }
-        }
-
-        private void draw(Display display, GC gc) {
-            if (mSegments.length == 0) {
-                // gc.setBackground(colorBackground);
-                // gc.fillRectangle(getBounds());
-                return;
-            }
-            Point dim = getSize();
-
-            // Create an image for double-buffering
-            Image image = new Image(display, getBounds());
-
-            // Set up the off-screen gc
-            GC gcImage = new GC(image);
-            if (mSetFonts)
-                gcImage.setFont(mFontRegistry.get("medium"));  // $NON-NLS-1$
-
-            if (mNumRows > 2) {
-                // Draw the row background stripes
-                gcImage.setBackground(mColorRowBack);
-                for (int ii = 1; ii < mNumRows; ii += 2) {
-                    RowData rd = mRows[ii];
-                    int y1 = rd.mRank * rowYSpace - mScrollOffsetY;
-                    gcImage.fillRectangle(0, y1, dim.x, rowYSpace);
-                }
-            }
-
-            // Draw the row labels
-            int offsetY = rowYMarginHalf - mScrollOffsetY;
-            for (int ii = mStartRow; ii <= mEndRow; ++ii) {
-                RowData rd = mRows[ii];
-                int y1 = rd.mRank * rowYSpace + offsetY;
-                Point extent = gcImage.stringExtent(rd.mName);
-                int x1 = dim.x - extent.x - labelMarginX;
-                gcImage.drawString(rd.mName, x1, y1, true);
-            }
-
-            // Draw a highlight box on the row where the mouse is.
-            if (mMouseRow >= mStartRow && mMouseRow <= mEndRow) {
-                gcImage.setForeground(mColorGray);
-                int y1 = mMouseRow * rowYSpace - mScrollOffsetY;
-                gcImage.drawRectangle(0, y1, dim.x, rowYSpace);
-            }
-
-            // Draw the off-screen buffer to the screen
-            gc.drawImage(image, 0, 0);
-
-            // Clean up
-            image.dispose();
-            gcImage.dispose();
-        }
-    }
-    
-    private class BlankCorner extends Canvas {
-        public BlankCorner(Composite parent) {
-            //super(parent, SWT.NO_BACKGROUND);
-            super(parent, SWT.NONE);
-            addPaintListener(new PaintListener() {
-                public void paintControl(PaintEvent pe) {
-                    draw(pe.display, pe.gc);
-                }
-            });
-        }
-
-        private void draw(Display display, GC gc) {
-            // Create a blank image and draw it to the canvas
-            Image image = new Image(display, getBounds());
-            gc.drawImage(image, 0, 0);
-
-            // Clean up
-            image.dispose();
-        }
-    }
-
-    private class Timescale extends Canvas {
-        private Point mMouse = new Point(LeftMargin, 0);
-        private Cursor mZoomCursor;
-        private String mMethodName = null;
-        private Color mMethodColor = null;
-        private int mMethodStartY;
-        private int mMarkStartX;
-        private int mMarkEndX;
-        
-        /** The space between the colored block and the method name */
-        private static final int METHOD_BLOCK_MARGIN = 10;
-
-        public Timescale(Composite parent) {
-            //super(parent, SWT.NO_BACKGROUND);
-            super(parent, SWT.NONE);
-            Display display = getDisplay();
-            mZoomCursor = new Cursor(display, SWT.CURSOR_SIZEWE);
-            setCursor(mZoomCursor);
-            mMethodStartY = mSmallFontHeight + 1;
-            addPaintListener(new PaintListener() {
-                public void paintControl(PaintEvent pe) {
-                    draw(pe.display, pe.gc);
-                }
-            });
-        }
-
-        public void setVbarPosition(int x) {
-            mMouse.x = x;
-        }
-
-        public void setMarkStart(int x) {
-            mMarkStartX = x;
-        }
-
-        public void setMarkEnd(int x) {
-            mMarkEndX = x;
-        }
-        
-        public void setMethodName(String name) {
-            mMethodName = name;
-        }
-        
-        public void setMethodColor(Color color) {
-            mMethodColor = color;
-        }
-        
-        private void mouseMove(MouseEvent me) {
-            me.y = -1;
-            mSurface.mouseMove(me);
-        }
-        
-        private void mouseDown(MouseEvent me) {
-            mSurface.startScaling(me.x);
-            mSurface.redraw();
-        }
-        
-        private void mouseUp(MouseEvent me) {
-            mSurface.stopScaling(me.x);
-        }
-        
-        private void mouseDoubleClick(MouseEvent me) {
-            mSurface.resetScale();
-            mSurface.redraw();
-        }
-
-        private void draw(Display display, GC gc) {
-            Point dim = getSize();
-
-            // Create an image for double-buffering
-            Image image = new Image(display, getBounds());
-
-            // Set up the off-screen gc
-            GC gcImage = new GC(image);
-            if (mSetFonts)
-                gcImage.setFont(mFontRegistry.get("medium"));  // $NON-NLS-1$
-
-            if (mSurface.drawingSelection()) {
-                drawSelection(display, gcImage);
-            }
-            
-            drawTicks(display, gcImage);
-
-            // Draw the vertical bar where the mouse is
-            gcImage.setForeground(mColorDarkGray);
-            gcImage.drawLine(mMouse.x, timeLineOffsetY, mMouse.x, dim.y);
-            
-            // Draw the current millseconds
-            drawTickLegend(display, gcImage);
-            
-            // Draw the method name and color, if needed
-            drawMethod(display, gcImage);
-            
-            // Draw the off-screen buffer to the screen
-            gc.drawImage(image, 0, 0);
-
-            // Clean up
-            image.dispose();
-            gcImage.dispose();
-        }
-        
-        private void drawSelection(Display display, GC gc) {
-            Point dim = getSize();
-            gc.setForeground(mColorGray);
-            gc.drawLine(mMarkStartX, timeLineOffsetY, mMarkStartX, dim.y);
-            gc.setBackground(mColorZoomSelection);
-            int x, width;
-            if (mMarkStartX < mMarkEndX) {
-                x = mMarkStartX;
-                width = mMarkEndX - mMarkStartX;
-            } else {
-                x = mMarkEndX;
-                width = mMarkStartX - mMarkEndX;
-            }
-            if (width > 1) {
-                gc.fillRectangle(x, timeLineOffsetY, width, dim.y);
-            }
-        }
-
-        private void drawTickLegend(Display display, GC gc) {
-            int mouseX = mMouse.x - LeftMargin;
-            double mouseXval = mScaleInfo.pixelToValue(mouseX);
-            String info = mUnits.labelledString(mouseXval);
-            gc.setForeground(mColorForeground);
-            gc.drawString(info, LeftMargin + 2, 1, true);
-
-            // Display the maximum data value
-            double maxVal = mScaleInfo.getMaxVal();
-            info = mUnits.labelledString(maxVal);
-            info = String.format(" max %s ", info);  // $NON-NLS-1$
-            Point extent = gc.stringExtent(info);
-            Point dim = getSize();
-            int x1 = dim.x - RightMargin - extent.x;
-            gc.drawString(info, x1, 1, true);
-        }
-        
-        private void drawMethod(Display display, GC gc) {
-            if (mMethodName == null) {
-                return;
-            }
-
-            int x1 = LeftMargin;
-            int y1 = mMethodStartY;
-            gc.setBackground(mMethodColor);
-            int width = 2 * mSmallFontWidth;
-            gc.fillRectangle(x1, y1, width, mSmallFontHeight);
-            x1 += width + METHOD_BLOCK_MARGIN;
-            gc.drawString(mMethodName, x1, y1, true);
-        }
-        
-        private void drawTicks(Display display, GC gc) {
-            Point dim = getSize();
-            int y2 = majorTickLength + timeLineOffsetY;
-            int y3 = minorTickLength + timeLineOffsetY;
-            int y4 = y2 + tickToFontSpacing;
-            gc.setForeground(mColorForeground);
-            gc.drawLine(LeftMargin, timeLineOffsetY, dim.x - RightMargin,
-                    timeLineOffsetY);
-            double minVal = mScaleInfo.getMinVal();
-            double maxVal = mScaleInfo.getMaxVal();
-            double minMajorTick = mScaleInfo.getMinMajorTick();
-            double tickIncrement = mScaleInfo.getTickIncrement();
-            double minorTickIncrement = tickIncrement / 5;
-            double pixelsPerRange = mScaleInfo.getPixelsPerRange();
-            
-            // Draw the initial minor ticks, if any
-            if (minVal < minMajorTick) {
-                gc.setForeground(mColorGray);
-                double xMinor = minMajorTick;
-                for (int ii = 1; ii <= 4; ++ii) {
-                    xMinor -= minorTickIncrement;
-                    if (xMinor < minVal)
-                        break;
-                    int x1 = LeftMargin
-                            + (int) (0.5 + (xMinor - minVal) * pixelsPerRange);
-                    gc.drawLine(x1, timeLineOffsetY, x1, y3);
-                }
-            }
-            
-            if (tickIncrement <= 10) {
-                // TODO avoid rendering the loop when tickIncrement is invalid. It can be zero
-                // or too small.
-                // System.out.println(String.format("Timescale.drawTicks error: tickIncrement=%1f", tickIncrement));
-                return;
-            }
-            for (double x = minMajorTick; x <= maxVal; x += tickIncrement) {
-                int x1 = LeftMargin
-                        + (int) (0.5 + (x - minVal) * pixelsPerRange);
-
-                // Draw a major tick
-                gc.setForeground(mColorForeground);
-                gc.drawLine(x1, timeLineOffsetY, x1, y2);
-                if (x > maxVal)
-                    break;
-
-                // Draw the tick text
-                String tickString = mUnits.valueOf(x);
-                gc.drawString(tickString, x1, y4, true);
-
-                // Draw 4 minor ticks between major ticks
-                gc.setForeground(mColorGray);
-                double xMinor = x;
-                for (int ii = 1; ii <= 4; ii++) {
-                    xMinor += minorTickIncrement;
-                    if (xMinor > maxVal)
-                        break;
-                    x1 = LeftMargin
-                            + (int) (0.5 + (xMinor - minVal) * pixelsPerRange);
-                    gc.drawLine(x1, timeLineOffsetY, x1, y3);
-                }
-            }
-        }
-    }
-
-    private static enum GraphicsState {
-        Normal, Marking, Scaling, Animating
-    };
-
-    private class Surface extends Canvas {
-
-        public Surface(Composite parent) {
-            super(parent, SWT.NO_BACKGROUND | SWT.V_SCROLL);
-            Display display = getDisplay();
-            mNormalCursor = new Cursor(display, SWT.CURSOR_CROSS);
-            mIncreasingCursor = new Cursor(display, SWT.CURSOR_SIZEE);
-            mDecreasingCursor = new Cursor(display, SWT.CURSOR_SIZEW);
-
-            initZoomFractionsWithExp();
-
-            addPaintListener(new PaintListener() {
-                public void paintControl(PaintEvent pe) {
-                    draw(pe.display, pe.gc);
-                }
-            });
-
-            mZoomAnimator = new Runnable() {
-                public void run() {
-                    animateZoom();
-                }
-            };
-
-            mHighlightAnimator = new Runnable() {
-                public void run() {
-                    animateHighlight();
-                }
-            };
-        }
-
-        private void initZoomFractionsWithExp() {
-            mZoomFractions = new double[ZOOM_STEPS];
-            int next = 0;
-            for (int ii = 0; ii < ZOOM_STEPS / 2; ++ii, ++next) {
-                mZoomFractions[next] = (double) (1 << ii)
-                        / (double) (1 << (ZOOM_STEPS / 2));
-                // System.out.printf("%d %f\n", next, zoomFractions[next]);
-            }
-            for (int ii = 2; ii < 2 + ZOOM_STEPS / 2; ++ii, ++next) {
-                mZoomFractions[next] = (double) ((1 << ii) - 1)
-                        / (double) (1 << ii);
-                // System.out.printf("%d %f\n", next, zoomFractions[next]);
-            }
-        }
-
-        @SuppressWarnings("unused")
-        private void initZoomFractionsWithSinWave() {
-            mZoomFractions = new double[ZOOM_STEPS];
-            for (int ii = 0; ii < ZOOM_STEPS; ++ii) {
-                double offset = Math.PI * (double) ii / (double) ZOOM_STEPS;
-                mZoomFractions[ii] = (Math.sin((1.5 * Math.PI + offset)) + 1.0) / 2.0;
-                // System.out.printf("%d %f\n", ii, zoomFractions[ii]);
-            }
-        }
-
-        public void setRange(double minVal, double maxVal) {
-            mMinDataVal = minVal;
-            mMaxDataVal = maxVal;
-            mScaleInfo.setMinVal(minVal);
-            mScaleInfo.setMaxVal(maxVal);
-        }
-
-        public void setLimitRange(double minVal, double maxVal) {
-            mLimitMinVal = minVal;
-            mLimitMaxVal = maxVal;
-        }
-        
-        public void resetScale() {
-            mScaleInfo.setMinVal(mLimitMinVal);
-            mScaleInfo.setMaxVal(mLimitMaxVal);
-        }
-
-        private void draw(Display display, GC gc) {
-            if (mSegments.length == 0) {
-                // gc.setBackground(colorBackground);
-                // gc.fillRectangle(getBounds());
-                return;
-            }
-
-            // Create an image for double-buffering
-            Image image = new Image(display, getBounds());
-
-            // Set up the off-screen gc
-            GC gcImage = new GC(image);
-            if (mSetFonts)
-                gcImage.setFont(mFontRegistry.get("small"));  // $NON-NLS-1$
-
-            // Draw the background
-            // gcImage.setBackground(colorBackground);
-            // gcImage.fillRectangle(image.getBounds());
-
-            if (mGraphicsState == GraphicsState.Scaling) {
-                double diff = mMouse.x - mMouseMarkStartX;
-                if (diff > 0) {
-                    double newMinVal = mScaleMinVal - diff / mScalePixelsPerRange;
-                    if (newMinVal < mLimitMinVal)
-                        newMinVal = mLimitMinVal;
-                    mScaleInfo.setMinVal(newMinVal);
-                    // System.out.printf("diff %f scaleMin %f newMin %f\n",
-                    // diff, scaleMinVal, newMinVal);
-                } else if (diff < 0) {
-                    double newMaxVal = mScaleMaxVal - diff / mScalePixelsPerRange;
-                    if (newMaxVal > mLimitMaxVal)
-                        newMaxVal = mLimitMaxVal;
-                    mScaleInfo.setMaxVal(newMaxVal);
-                    // System.out.printf("diff %f scaleMax %f newMax %f\n",
-                    // diff, scaleMaxVal, newMaxVal);
-                }
-            }
-
-            // Recompute the ticks and strips only if the size has changed,
-            // or we scrolled so that a new row is visible.
-            Point dim = getSize();
-            if (mStartRow != mCachedStartRow || mEndRow != mCachedEndRow 
-                    || mScaleInfo.getMinVal() != mCachedMinVal
-                    || mScaleInfo.getMaxVal() != mCachedMaxVal) {
-                mCachedStartRow = mStartRow;
-                mCachedEndRow = mEndRow;
-                int xdim = dim.x - TotalXMargin;
-                mScaleInfo.setNumPixels(xdim);
-                boolean forceEndPoints = (mGraphicsState == GraphicsState.Scaling
-                        || mGraphicsState == GraphicsState.Animating);
-                mScaleInfo.computeTicks(forceEndPoints);
-                mCachedMinVal = mScaleInfo.getMinVal();
-                mCachedMaxVal = mScaleInfo.getMaxVal();
-                if (mLimitMinVal > mScaleInfo.getMinVal())
-                    mLimitMinVal = mScaleInfo.getMinVal();
-                if (mLimitMaxVal < mScaleInfo.getMaxVal())
-                    mLimitMaxVal = mScaleInfo.getMaxVal();
-
-                // Compute the strips
-                computeStrips();
-            }
-
-            if (mNumRows > 2) {
-                // Draw the row background stripes
-                gcImage.setBackground(mColorRowBack);
-                for (int ii = 1; ii < mNumRows; ii += 2) {
-                    RowData rd = mRows[ii];
-                    int y1 = rd.mRank * rowYSpace - mScrollOffsetY;
-                    gcImage.fillRectangle(0, y1, dim.x, rowYSpace);
-                }
-            }
-
-            if (drawingSelection()) {
-                drawSelection(display, gcImage);
-            }
-
-            String blockName = null;
-            Color blockColor = null;
-
-            if (mDebug) {
-                double pixelsPerRange = mScaleInfo.getPixelsPerRange();
-                System.out
-                        .printf(
-                                "dim.x %d pixels %d minVal %f, maxVal %f ppr %f rpp %f\n",
-                                dim.x, dim.x - TotalXMargin, mScaleInfo
-                                        .getMinVal(), mScaleInfo.getMaxVal(),
-                                pixelsPerRange, 1.0 / pixelsPerRange);
-            }
-
-            // Draw the strips
-            Block selectBlock = null;
-            for (Strip strip : mStripList) {
-                if (strip.mColor == null) {
-                    // System.out.printf("strip.color is null\n");
-                    continue;
-                }
-                gcImage.setBackground(strip.mColor);
-                gcImage.fillRectangle(strip.mX, strip.mY - mScrollOffsetY, strip.mWidth,
-                        strip.mHeight);
-                if (mMouseRow == strip.mRowData.mRank) {
-                    if (mMouse.x >= strip.mX
-                            && mMouse.x < strip.mX + strip.mWidth) {
-                        blockName = strip.mSegment.mBlock.getName();
-                        blockColor = strip.mColor;
-                    }
-                    if (mMouseSelect.x >= strip.mX
-                            && mMouseSelect.x < strip.mX + strip.mWidth) {
-                        selectBlock = strip.mSegment.mBlock;
-                    }
-                }
-            }
-            mMouseSelect.x = 0;
-            mMouseSelect.y = 0;
-
-            if (selectBlock != null) {
-                ArrayList<Selection> selections = new ArrayList<Selection>();
-                // Get the row label
-                RowData rd = mRows[mMouseRow];
-                selections.add(Selection.highlight("Thread", rd.mName));  // $NON-NLS-1$
-                selections.add(Selection.highlight("Call", selectBlock));  // $NON-NLS-1$
-
-                int mouseX = mMouse.x - LeftMargin;
-                double mouseXval = mScaleInfo.pixelToValue(mouseX);
-                selections.add(Selection.highlight("Time", mouseXval));  // $NON-NLS-1$
-                
-                mSelectionController.change(selections, "TimeLineView");  // $NON-NLS-1$
-                mHighlightMethodData = null;
-                mHighlightCall = (Call) selectBlock;
-                startHighlighting();
-            }
-
-            // Draw a highlight box on the row where the mouse is.
-            // Except don't draw the box if we are animating the
-            // highlighing of a call or method because the inclusive
-            // highlight bar passes through the highlight box and
-            // causes an annoying flashing artifact.
-            if (mMouseRow >= 0 && mMouseRow < mNumRows && mHighlightStep == 0) {
-                gcImage.setForeground(mColorGray);
-                int y1 = mMouseRow * rowYSpace - mScrollOffsetY;
-                gcImage.drawLine(0, y1, dim.x, y1);
-                gcImage.drawLine(0, y1 + rowYSpace, dim.x, y1 + rowYSpace);
-            }
-
-            // Highlight a selected method, if any
-            drawHighlights(gcImage, dim);
-
-            // Draw a vertical line where the mouse is.
-            gcImage.setForeground(mColorDarkGray);
-            int lineEnd = Math.min(dim.y, mNumRows * rowYSpace);
-            gcImage.drawLine(mMouse.x, 0, mMouse.x, lineEnd);
-
-            if (blockName != null) {
-                mTimescale.setMethodName(blockName);
-                mTimescale.setMethodColor(blockColor);
-                mShowHighlightName = false;
-            } else if (mShowHighlightName) {
-                // Draw the highlighted method name
-                MethodData md = mHighlightMethodData;
-                if (md == null && mHighlightCall != null)
-                    md = mHighlightCall.getMethodData();
-                if (md == null)
-                    System.out.printf("null highlight?\n");  // $NON-NLS-1$
-                if (md != null) {
-                    mTimescale.setMethodName(md.getProfileName());
-                    mTimescale.setMethodColor(md.getColor());
-                }
-            } else {
-                mTimescale.setMethodName(null);
-                mTimescale.setMethodColor(null);
-            }
-            mTimescale.redraw();
-
-            // Draw the off-screen buffer to the screen
-            gc.drawImage(image, 0, 0);
-
-            // Clean up
-            image.dispose();
-            gcImage.dispose();
-        }
-
-        private void drawHighlights(GC gc, Point dim) {
-            int height = highlightHeight;
-            if (height <= 0)
-                return;
-            for (Range range : mHighlightExclusive) {
-                gc.setBackground(range.mColor);
-                int xStart = range.mXdim.x;
-                int width = range.mXdim.y;
-                gc.fillRectangle(xStart, range.mY - height - mScrollOffsetY, width, height);
-            }
-
-            // Draw the inclusive lines a bit shorter
-            height -= 1;
-            if (height <= 0)
-                height = 1;
-
-            // Highlight the inclusive ranges
-            gc.setForeground(mColorDarkGray);
-            gc.setBackground(mColorDarkGray);
-            for (Range range : mHighlightInclusive) {
-                int x1 = range.mXdim.x;
-                int x2 = range.mXdim.y;
-                boolean drawLeftEnd = false;
-                boolean drawRightEnd = false;
-                if (x1 >= LeftMargin)
-                    drawLeftEnd = true;
-                else
-                    x1 = LeftMargin;
-                if (x2 >= LeftMargin)
-                    drawRightEnd = true;
-                else
-                    x2 = dim.x - RightMargin;
-                int y1 = range.mY + rowHeight + 2 - mScrollOffsetY;
-
-                // If the range is very narrow, then just draw a small
-                // rectangle.
-                if (x2 - x1 < MinInclusiveRange) {
-                    int width = x2 - x1;
-                    if (width < 2)
-                        width = 2;
-                    gc.fillRectangle(x1, y1, width, height);
-                    continue;
-                }
-                if (drawLeftEnd) {
-                    if (drawRightEnd) {
-                        // Draw both ends
-                        int[] points = { x1, y1, x1, y1 + height, x2,
-                                y1 + height, x2, y1 };
-                        gc.drawPolyline(points);
-                    } else {
-                        // Draw the left end
-                        int[] points = { x1, y1, x1, y1 + height, x2,
-                                y1 + height };
-                        gc.drawPolyline(points);
-                    }
-                } else {
-                    if (drawRightEnd) {
-                        // Draw the right end
-                        int[] points = { x1, y1 + height, x2, y1 + height, x2,
-                                y1 };
-                        gc.drawPolyline(points);
-                    } else {
-                        // Draw neither end, just the line
-                        int[] points = { x1, y1 + height, x2, y1 + height };
-                        gc.drawPolyline(points);
-                    }
-                }
-
-                // Draw the arrowheads, if necessary
-                if (drawLeftEnd == false) {
-                    int[] points = { x1 + 7, y1 + height - 4, x1, y1 + height,
-                            x1 + 7, y1 + height + 4 };
-                    gc.fillPolygon(points);
-                }
-                if (drawRightEnd == false) {
-                    int[] points = { x2 - 7, y1 + height - 4, x2, y1 + height,
-                            x2 - 7, y1 + height + 4 };
-                    gc.fillPolygon(points);
-                }
-            }
-        }
-
-        private boolean drawingSelection() {
-            return mGraphicsState == GraphicsState.Marking
-                    || mGraphicsState == GraphicsState.Animating;
-        }
-        
-        private void drawSelection(Display display, GC gc) {
-            Point dim = getSize();
-            gc.setForeground(mColorGray);
-            gc.drawLine(mMouseMarkStartX, 0, mMouseMarkStartX, dim.y);
-            gc.setBackground(mColorZoomSelection);
-            int width;
-            int mouseX = (mGraphicsState == GraphicsState.Animating) ? mMouseMarkEndX : mMouse.x;
-            int x;
-            if (mMouseMarkStartX < mouseX) {
-                x = mMouseMarkStartX;
-                width = mouseX - mMouseMarkStartX;
-            } else {
-                x = mouseX;
-                width = mMouseMarkStartX - mouseX;
-            }
-            gc.fillRectangle(x, 0, width, dim.y);
-        }
-
-        private void computeStrips() {
-            double minVal = mScaleInfo.getMinVal();
-            double maxVal = mScaleInfo.getMaxVal();
-
-            // Allocate space for the pixel data
-            Pixel[] pixels = new Pixel[mNumRows];
-            for (int ii = 0; ii < mNumRows; ++ii)
-                pixels[ii] = new Pixel();
-
-            // Clear the per-block pixel data
-            for (int ii = 0; ii < mSegments.length; ++ii) {
-                mSegments[ii].mBlock.clearWeight();
-            }
-
-            mStripList.clear();
-            mHighlightExclusive.clear();
-            mHighlightInclusive.clear();
-            MethodData callMethod = null;
-            long callStart = 0;
-            long callEnd = -1;
-            RowData callRowData = null;
-            int prevMethodStart = -1;
-            int prevCallStart = -1;
-            if (mHighlightCall != null) {
-                int callPixelStart = -1;
-                int callPixelEnd = -1;
-                callStart = mHighlightCall.mGlobalStartTime;
-                callEnd = mHighlightCall.mGlobalEndTime;
-                callMethod = mHighlightCall.mMethodData;
-                if (callStart >= minVal)
-                    callPixelStart = mScaleInfo.valueToPixel(callStart);
-                if (callEnd <= maxVal)
-                    callPixelEnd = mScaleInfo.valueToPixel(callEnd);
-                // System.out.printf("callStart,End %d,%d minVal,maxVal %f,%f
-                // callPixelStart,End %d,%d\n",
-                // callStart, callEnd, minVal, maxVal, callPixelStart,
-                // callPixelEnd);
-                int threadId = mHighlightCall.getThreadId();
-                String threadName = mThreadLabels.get(threadId);
-                callRowData = mRowByName.get(threadName);
-                int y1 = callRowData.mRank * rowYSpace + rowYMarginHalf;
-                Color color = callMethod.getColor();
-                mHighlightInclusive.add(new Range(callPixelStart + LeftMargin,
-                        callPixelEnd + LeftMargin, y1, color));
-            }
-            for (Segment segment : mSegments) {
-                if (segment.mEndTime <= minVal)
-                    continue;
-                if (segment.mStartTime >= maxVal)
-                    continue;
-                Block block = segment.mBlock;
-                Color color = block.getColor();
-                if (color == null)
-                    continue;
-
-                double recordStart = Math.max(segment.mStartTime, minVal);
-                double recordEnd = Math.min(segment.mEndTime, maxVal);
-                if (recordStart == recordEnd)
-                    continue;
-                int pixelStart = mScaleInfo.valueToPixel(recordStart);
-                int pixelEnd = mScaleInfo.valueToPixel(recordEnd);
-                int width = pixelEnd - pixelStart;
-
-                RowData rd = segment.mRowData;
-                MethodData md = block.getMethodData();
-
-                // We will add the scroll offset later when we draw the strips
-                int y1 = rd.mRank * rowYSpace + rowYMarginHalf;
-
-                // If we can't display any more rows, then quit
-                if (rd.mRank > mEndRow)
-                    break;
-
-                // System.out.printf("segment %s val: [%.1f, %.1f] frac [%f, %f]
-                // pixel: [%d, %d] pix.start %d weight %.2f %s\n",
-                // block.getName(), recordStart, recordEnd,
-                // scaleInfo.valueToPixelFraction(recordStart),
-                // scaleInfo.valueToPixelFraction(recordEnd),
-                // pixelStart, pixelEnd, pixels[rd.rank].start,
-                // pixels[rd.rank].maxWeight,
-                // pixels[rd.rank].segment != null
-                // ? pixels[rd.rank].segment.block.getName()
-                // : "null");
-
-                if (mHighlightMethodData != null) {
-                    if (mHighlightMethodData == md) {
-                        if (prevMethodStart != pixelStart) {
-                            prevMethodStart = pixelStart;
-                            int rangeWidth = width;
-                            if (rangeWidth == 0)
-                                rangeWidth = 1;
-                            mHighlightExclusive.add(new Range(pixelStart
-                                    + LeftMargin, rangeWidth, y1, color));
-                            Call call = (Call) block;
-                            callStart = call.mGlobalStartTime;
-                            int callPixelStart = -1;
-                            if (callStart >= minVal)
-                                callPixelStart = mScaleInfo.valueToPixel(callStart);
-                            if (prevCallStart != callPixelStart) {
-                                prevCallStart = callPixelStart;
-                                int callPixelEnd = -1;
-                                callEnd = call.mGlobalEndTime;
-                                if (callEnd <= maxVal)
-                                    callPixelEnd = mScaleInfo.valueToPixel(callEnd);
-                                mHighlightInclusive.add(new Range(
-                                        callPixelStart + LeftMargin,
-                                        callPixelEnd + LeftMargin, y1, color));
-                            }
-                        }
-                    } else if (mFadeColors) {
-                        color = md.getFadedColor();
-                    }
-                } else if (mHighlightCall != null) {
-                    if (segment.mStartTime >= callStart
-                            && segment.mEndTime <= callEnd && callMethod == md
-                            && callRowData == rd) {
-                        if (prevMethodStart != pixelStart) {
-                            prevMethodStart = pixelStart;
-                            int rangeWidth = width;
-                            if (rangeWidth == 0)
-                                rangeWidth = 1;
-                            mHighlightExclusive.add(new Range(pixelStart
-                                    + LeftMargin, rangeWidth, y1, color));
-                        }
-                    } else if (mFadeColors) {
-                        color = md.getFadedColor();
-                    }
-                }
-
-                // Cases:
-                // 1. This segment starts on a different pixel than the
-                // previous segment started on. In this case, emit
-                // the pixel strip, if any, and:
-                // A. If the width is 0, then add this segment's
-                // weight to the Pixel.
-                // B. If the width > 0, then emit a strip for this
-                // segment (no partial Pixel data).
-                //
-                // 2. Otherwise (the new segment starts on the same
-                // pixel as the previous segment): add its "weight"
-                // to the current pixel, and:
-                // A. If the new segment has width 1,
-                // then emit the pixel strip and then
-                // add the segment's weight to the pixel.
-                // B. If the new segment has width > 1,
-                // then emit the pixel strip, and emit the rest
-                // of the strip for this segment (no partial Pixel
-                // data).
-
-                Pixel pix = pixels[rd.mRank];
-                if (pix.mStart != pixelStart) {
-                    if (pix.mSegment != null) {
-                        // Emit the pixel strip. This also clears the pixel.
-                        emitPixelStrip(rd, y1, pix);
-                    }
-
-                    if (width == 0) {
-                        // Compute the "weight" of this segment for the first
-                        // pixel. For a pixel N, the "weight" of a segment is
-                        // how much of the region [N - 0.5, N + 0.5] is covered
-                        // by the segment.
-                        double weight = computeWeight(recordStart, recordEnd,
-                                pixelStart);
-                        weight = block.addWeight(pixelStart, rd.mRank, weight);
-                        if (weight > pix.mMaxWeight) {
-                            pix.setFields(pixelStart, weight, segment, color,
-                                    rd);
-                        }
-                    } else {
-                        int x1 = pixelStart + LeftMargin;
-                        Strip strip = new Strip(x1, y1, width, rowHeight, rd,
-                                segment, color);
-                        mStripList.add(strip);
-                    }
-                } else {
-                    double weight = computeWeight(recordStart, recordEnd,
-                            pixelStart);
-                    weight = block.addWeight(pixelStart, rd.mRank, weight);
-                    if (weight > pix.mMaxWeight) {
-                        pix.setFields(pixelStart, weight, segment, color, rd);
-                    }
-                    if (width == 1) {
-                        // Emit the pixel strip. This also clears the pixel.
-                        emitPixelStrip(rd, y1, pix);
-
-                        // Compute the weight for the next pixel
-                        pixelStart += 1;
-                        weight = computeWeight(recordStart, recordEnd,
-                                pixelStart);
-                        weight = block.addWeight(pixelStart, rd.mRank, weight);
-                        pix.setFields(pixelStart, weight, segment, color, rd);
-                    } else if (width > 1) {
-                        // Emit the pixel strip. This also clears the pixel.
-                        emitPixelStrip(rd, y1, pix);
-
-                        // Emit a strip for the rest of the segment.
-                        pixelStart += 1;
-                        width -= 1;
-                        int x1 = pixelStart + LeftMargin;
-                        Strip strip = new Strip(x1, y1, width, rowHeight, rd,
-                                segment, color);
-                        mStripList.add(strip);
-                    }
-                }
-            }
-
-            // Emit the last pixels of each row, if any
-            for (int ii = 0; ii < mNumRows; ++ii) {
-                Pixel pix = pixels[ii];
-                if (pix.mSegment != null) {
-                    RowData rd = pix.mRowData;
-                    int y1 = rd.mRank * rowYSpace + rowYMarginHalf;
-                    // Emit the pixel strip. This also clears the pixel.
-                    emitPixelStrip(rd, y1, pix);
-                }
-            }
-
-            if (false) {
-                System.out.printf("computeStrips()\n");
-                for (Strip strip : mStripList) {
-                    System.out.printf("%3d, %3d width %3d height %d %s\n",
-                            strip.mX, strip.mY, strip.mWidth, strip.mHeight,
-                            strip.mSegment.mBlock.getName());
-                }
-            }
-        }
-
-        private double computeWeight(double start, double end, int pixel) {
-            double pixelStartFraction = mScaleInfo.valueToPixelFraction(start);
-            double pixelEndFraction = mScaleInfo.valueToPixelFraction(end);
-            double leftEndPoint = Math.max(pixelStartFraction, pixel - 0.5);
-            double rightEndPoint = Math.min(pixelEndFraction, pixel + 0.5);
-            double weight = rightEndPoint - leftEndPoint;
-            return weight;
-        }
-
-        private void emitPixelStrip(RowData rd, int y, Pixel pixel) {
-            Strip strip;
-
-            if (pixel.mSegment == null)
-                return;
-
-            int x = pixel.mStart + LeftMargin;
-            // Compute the percentage of the row height proportional to
-            // the weight of this pixel. But don't let the proportion
-            // exceed 3/4 of the row height so that we can easily see
-            // if a given time range includes more than one method.
-            int height = (int) (pixel.mMaxWeight * rowHeight * 0.75);
-            if (height < mMinStripHeight)
-                height = mMinStripHeight;
-            int remainder = rowHeight - height;
-            if (remainder > 0) {
-                strip = new Strip(x, y, 1, remainder, rd, pixel.mSegment,
-                        mFadeColors ? mColorGray : mColorBlack);
-                mStripList.add(strip);
-                // System.out.printf("emitPixel (%d, %d) height %d black\n",
-                // x, y, remainder);
-            }
-            strip = new Strip(x, y + remainder, 1, height, rd, pixel.mSegment,
-                    pixel.mColor);
-            mStripList.add(strip);
-            // System.out.printf("emitPixel (%d, %d) height %d %s\n",
-            // x, y + remainder, height, pixel.segment.block.getName());
-            pixel.mSegment = null;
-            pixel.mMaxWeight = 0.0;
-        }
-
-        private void mouseMove(MouseEvent me) {
-            if (false) {
-                if (mHighlightMethodData != null) {
-                    mHighlightMethodData = null;
-                    // Force a recomputation of the strip colors
-                    mCachedEndRow = -1;
-                }
-            }
-            Point dim = mSurface.getSize();
-            int x = me.x;
-            if (x < LeftMargin)
-                x = LeftMargin;
-            if (x > dim.x - RightMargin)
-                x = dim.x - RightMargin;
-            mMouse.x = x;
-            mMouse.y = me.y;
-            mTimescale.setVbarPosition(x);
-            if (mGraphicsState == GraphicsState.Marking) {
-                mTimescale.setMarkEnd(x);
-            }
-
-            if (mGraphicsState == GraphicsState.Normal) {
-                // Set the cursor to the normal state.
-                mSurface.setCursor(mNormalCursor);
-            } else if (mGraphicsState == GraphicsState.Marking) {
-                // Make the cursor point in the direction of the sweep
-                if (mMouse.x >= mMouseMarkStartX)
-                    mSurface.setCursor(mIncreasingCursor);
-                else
-                    mSurface.setCursor(mDecreasingCursor);
-            }
-            int rownum = (mMouse.y + mScrollOffsetY) / rowYSpace;
-            if (me.y < 0 || me.y >= dim.y) {
-                rownum = -1;
-            }
-            if (mMouseRow != rownum) {
-                mMouseRow = rownum;
-                mLabels.redraw();
-            }
-            redraw();
-        }
-
-        private void mouseDown(MouseEvent me) {
-            Point dim = mSurface.getSize();
-            int x = me.x;
-            if (x < LeftMargin)
-                x = LeftMargin;
-            if (x > dim.x - RightMargin)
-                x = dim.x - RightMargin;
-            mMouseMarkStartX = x;
-            mGraphicsState = GraphicsState.Marking;
-            mSurface.setCursor(mIncreasingCursor);
-            mTimescale.setMarkStart(mMouseMarkStartX);
-            mTimescale.setMarkEnd(mMouseMarkStartX);
-            redraw();
-        }
-
-        private void mouseUp(MouseEvent me) {
-            mSurface.setCursor(mNormalCursor);
-            if (mGraphicsState != GraphicsState.Marking) {
-                mGraphicsState = GraphicsState.Normal;
-                return;
-            }
-            mGraphicsState = GraphicsState.Animating;
-            Point dim = mSurface.getSize();
-
-            // If the user released the mouse outside the drawing area then
-            // cancel the zoom.
-            if (me.y <= 0 || me.y >= dim.y) {
-                mGraphicsState = GraphicsState.Normal;
-                redraw();
-                return;
-            }
-
-            int x = me.x;
-            if (x < LeftMargin)
-                x = LeftMargin;
-            if (x > dim.x - RightMargin)
-                x = dim.x - RightMargin;
-            mMouseMarkEndX = x;
-
-            // If the user clicked and released the mouse at the same point
-            // (+/- a pixel or two) then cancel the zoom (but select the
-            // method).
-            int dist = mMouseMarkEndX - mMouseMarkStartX;
-            if (dist < 0)
-                dist = -dist;
-            if (dist <= 2) {
-                mGraphicsState = GraphicsState.Normal;
-
-                // Select the method underneath the mouse
-                mMouseSelect.x = mMouseMarkStartX;
-                mMouseSelect.y = me.y;
-                redraw();
-                return;
-            }
-
-            // Make mouseEndX be the higher end point
-            if (mMouseMarkEndX < mMouseMarkStartX) {
-                int temp = mMouseMarkEndX;
-                mMouseMarkEndX = mMouseMarkStartX;
-                mMouseMarkStartX = temp;
-            }
-
-            // If the zoom area is the whole window (or nearly the whole
-            // window) then cancel the zoom.
-            if (mMouseMarkStartX <= LeftMargin + MinZoomPixelMargin
-                    && mMouseMarkEndX >= dim.x - RightMargin - MinZoomPixelMargin) {
-                mGraphicsState = GraphicsState.Normal;
-                redraw();
-                return;
-            }
-
-            // Compute some variables needed for zooming.
-            // It's probably easiest to explain by an example. There
-            // are two scales (or dimensions) involved: one for the pixels
-            // and one for the values (microseconds). To keep the example
-            // simple, suppose we have pixels in the range [0,16] and
-            // values in the range [100, 260], and suppose the user
-            // selects a zoom window from pixel 4 to pixel 8.
-            //
-            // usec: 100 140 180 260
-            // |-------|ZZZZZZZ|---------------|
-            // pixel: 0 4 8 16
-            //
-            // I've drawn the pixels starting at zero for simplicity, but
-            // in fact the drawable area is offset from the left margin
-            // by the value of "LeftMargin".
-            //
-            // The "pixels-per-range" (ppr) in this case is 0.1 (a tenth of
-            // a pixel per usec). What we want is to redraw the screen in
-            // several steps, each time increasing the zoom window until the
-            // zoom window fills the screen. For simplicity, assume that
-            // we want to zoom in four equal steps. Then the snapshots
-            // of the screen at each step would look something like this:
-            //
-            // usec: 100 140 180 260
-            // |-------|ZZZZZZZ|---------------|
-            // pixel: 0 4 8 16
-            //
-            // usec: ? 140 180 ?
-            // |-----|ZZZZZZZZZZZZZ|-----------|
-            // pixel: 0 3 10 16
-            //
-            // usec: ? 140 180 ?
-            // |---|ZZZZZZZZZZZZZZZZZZZ|-------|
-            // pixel: 0 2 12 16
-            //
-            // usec: ?140 180 ?
-            // |-|ZZZZZZZZZZZZZZZZZZZZZZZZZ|---|
-            // pixel: 0 1 14 16
-            //
-            // usec: 140 180
-            // |ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ|
-            // pixel: 0 16
-            //
-            // The problem is how to compute the endpoints (denoted by ?)
-            // for each step. This is a little tricky. We first need to
-            // compute the "fixed point": this is the point in the selection
-            // that doesn't move left or right. Then we can recompute the
-            // "ppr" (pixels per range) at each step and then find the
-            // endpoints. The computation of the end points is done
-            // in animateZoom(). This method computes the fixed point
-            // and some other variables needed in animateZoom().
-
-            double minVal = mScaleInfo.getMinVal();
-            double maxVal = mScaleInfo.getMaxVal();
-            double ppr = mScaleInfo.getPixelsPerRange();
-            mZoomMin = minVal + ((mMouseMarkStartX - LeftMargin) / ppr);
-            mZoomMax = minVal + ((mMouseMarkEndX - LeftMargin) / ppr);
-
-            // Clamp the min and max values to the actual data min and max
-            if (mZoomMin < mMinDataVal)
-                mZoomMin = mMinDataVal;
-            if (mZoomMax > mMaxDataVal)
-                mZoomMax = mMaxDataVal;
-
-            // Snap the min and max points to the grid determined by the
-            // TickScaler
-            // before we zoom.
-            int xdim = dim.x - TotalXMargin;
-            TickScaler scaler = new TickScaler(mZoomMin, mZoomMax, xdim,
-                    PixelsPerTick);
-            scaler.computeTicks(false);
-            mZoomMin = scaler.getMinVal();
-            mZoomMax = scaler.getMaxVal();
-
-            // Also snap the mouse points (in pixel space) to be consistent with
-            // zoomMin and zoomMax (in value space).
-            mMouseMarkStartX = (int) ((mZoomMin - minVal) * ppr + LeftMargin);
-            mMouseMarkEndX = (int) ((mZoomMax - minVal) * ppr + LeftMargin);
-            mTimescale.setMarkStart(mMouseMarkStartX);
-            mTimescale.setMarkEnd(mMouseMarkEndX);
-
-            // Compute the mouse selection end point distances
-            mMouseEndDistance = dim.x - RightMargin - mMouseMarkEndX;
-            mMouseStartDistance = mMouseMarkStartX - LeftMargin;
-            mZoomMouseStart = mMouseMarkStartX;
-            mZoomMouseEnd = mMouseMarkEndX;
-            mZoomStep = 0;
-
-            // Compute the fixed point in both value space and pixel space.
-            mMin2ZoomMin = mZoomMin - minVal;
-            mZoomMax2Max = maxVal - mZoomMax;
-            mZoomFixed = mZoomMin + (mZoomMax - mZoomMin) * mMin2ZoomMin
-                    / (mMin2ZoomMin + mZoomMax2Max);
-            mZoomFixedPixel = (mZoomFixed - minVal) * ppr + LeftMargin;
-            mFixedPixelStartDistance = mZoomFixedPixel - LeftMargin;
-            mFixedPixelEndDistance = dim.x - RightMargin - mZoomFixedPixel;
-
-            mZoomMin2Fixed = mZoomFixed - mZoomMin;
-            mFixed2ZoomMax = mZoomMax - mZoomFixed;
-
-            getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
-            redraw();
-            update();
-        }
-
-        // No defined behavior yet for double-click.
-        private void mouseDoubleClick(MouseEvent me) {
-        }
-        
-        public void startScaling(int mouseX) {
-            Point dim = mSurface.getSize();
-            int x = mouseX;
-            if (x < LeftMargin)
-                x = LeftMargin;
-            if (x > dim.x - RightMargin)
-                x = dim.x - RightMargin;
-            mMouseMarkStartX = x;
-            mGraphicsState = GraphicsState.Scaling;
-            mScalePixelsPerRange = mScaleInfo.getPixelsPerRange();
-            mScaleMinVal = mScaleInfo.getMinVal();
-            mScaleMaxVal = mScaleInfo.getMaxVal();
-        }
-
-        public void stopScaling(int mouseX) {
-            mGraphicsState = GraphicsState.Normal;
-        }
-        
-        private void animateHighlight() {
-            mHighlightStep += 1;
-            if (mHighlightStep >= HIGHLIGHT_STEPS) {
-                mFadeColors = false;
-                mHighlightStep = 0;
-                // Force a recomputation of the strip colors
-                mCachedEndRow = -1;
-            } else {
-                mFadeColors = true;
-                mShowHighlightName = true;
-                highlightHeight = highlightHeights[mHighlightStep];
-                getDisplay().timerExec(HIGHLIGHT_TIMER_INTERVAL, mHighlightAnimator);
-            }
-            redraw();
-        }
-
-        private void clearHighlights() {
-            // System.out.printf("clearHighlights()\n");
-            mShowHighlightName = false;
-            highlightHeight = 0;
-            mHighlightMethodData = null;
-            mHighlightCall = null;
-            mFadeColors = false;
-            mHighlightStep = 0;
-            // Force a recomputation of the strip colors
-            mCachedEndRow = -1;
-            redraw();
-        }
-
-        private void animateZoom() {
-            mZoomStep += 1;
-            if (mZoomStep > ZOOM_STEPS) {
-                mGraphicsState = GraphicsState.Normal;
-                // Force a normal recomputation
-                mCachedMinVal = mScaleInfo.getMinVal() + 1;
-            } else if (mZoomStep == ZOOM_STEPS) {
-                mScaleInfo.setMinVal(mZoomMin);
-                mScaleInfo.setMaxVal(mZoomMax);
-                mMouseMarkStartX = LeftMargin;
-                Point dim = getSize();
-                mMouseMarkEndX = dim.x - RightMargin;
-                mTimescale.setMarkStart(mMouseMarkStartX);
-                mTimescale.setMarkEnd(mMouseMarkEndX);
-                getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
-            } else {
-                // Zoom in slowly at first, then speed up, then slow down.
-                // The zoom fractions are precomputed to save time.
-                double fraction = mZoomFractions[mZoomStep];
-                mMouseMarkStartX = (int) (mZoomMouseStart - fraction * mMouseStartDistance);
-                mMouseMarkEndX = (int) (mZoomMouseEnd + fraction * mMouseEndDistance);
-                mTimescale.setMarkStart(mMouseMarkStartX);
-                mTimescale.setMarkEnd(mMouseMarkEndX);
-
-                // Compute the new pixels-per-range. Avoid division by zero.
-                double ppr;
-                if (mZoomMin2Fixed >= mFixed2ZoomMax)
-                    ppr = (mZoomFixedPixel - mMouseMarkStartX) / mZoomMin2Fixed;
-                else
-                    ppr = (mMouseMarkEndX - mZoomFixedPixel) / mFixed2ZoomMax;
-                double newMin = mZoomFixed - mFixedPixelStartDistance / ppr;
-                double newMax = mZoomFixed + mFixedPixelEndDistance / ppr;
-                mScaleInfo.setMinVal(newMin);
-                mScaleInfo.setMaxVal(newMax);
-
-                getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
-            }
-            redraw();
-        }
-
-        private static final int TotalXMargin = LeftMargin + RightMargin;
-        private static final int yMargin = 1; // blank space on top
-        // The minimum margin on each side of the zoom window, in pixels.
-        private static final int MinZoomPixelMargin = 10;
-        private GraphicsState mGraphicsState = GraphicsState.Normal;
-        private Point mMouse = new Point(LeftMargin, 0);
-        private int mMouseMarkStartX;
-        private int mMouseMarkEndX;
-        private boolean mDebug = false;
-        private ArrayList<Strip> mStripList = new ArrayList<Strip>();
-        private ArrayList<Range> mHighlightExclusive = new ArrayList<Range>();
-        private ArrayList<Range> mHighlightInclusive = new ArrayList<Range>();
-        private int mMinStripHeight = 2;
-        private double mCachedMinVal;
-        private double mCachedMaxVal;
-        private int mCachedStartRow;
-        private int mCachedEndRow;
-        private double mScalePixelsPerRange;
-        private double mScaleMinVal;
-        private double mScaleMaxVal;
-        private double mLimitMinVal;
-        private double mLimitMaxVal;
-        private double mMinDataVal;
-        private double mMaxDataVal;
-        private Cursor mNormalCursor;
-        private Cursor mIncreasingCursor;
-        private Cursor mDecreasingCursor;
-        private static final int ZOOM_TIMER_INTERVAL = 10;
-        private static final int HIGHLIGHT_TIMER_INTERVAL = 50;
-        private static final int ZOOM_STEPS = 8; // must be even
-        private int highlightHeight = 4;
-        private final int[] highlightHeights = { 0, 2, 4, 5, 6, 5, 4, 2, 4, 5,
-                6 };
-        private final int HIGHLIGHT_STEPS = highlightHeights.length;
-        private boolean mFadeColors;
-        private boolean mShowHighlightName;
-        private double[] mZoomFractions;
-        private int mZoomStep;
-        private int mZoomMouseStart;
-        private int mZoomMouseEnd;
-        private int mMouseStartDistance;
-        private int mMouseEndDistance;
-        private Point mMouseSelect = new Point(0, 0);
-        private double mZoomFixed;
-        private double mZoomFixedPixel;
-        private double mFixedPixelStartDistance;
-        private double mFixedPixelEndDistance;
-        private double mZoomMin2Fixed;
-        private double mMin2ZoomMin;
-        private double mFixed2ZoomMax;
-        private double mZoomMax2Max;
-        private double mZoomMin;
-        private double mZoomMax;
-        private Runnable mZoomAnimator;
-        private Runnable mHighlightAnimator;
-        private int mHighlightStep;
-    }
-
-    private int computeVisibleRows(int ydim) {
-        // If we resize, then move the bottom row down.  Don't allow the scroll
-        // to waste space at the bottom.
-        int offsetY = mScrollOffsetY;
-        int spaceNeeded = mNumRows * rowYSpace;
-        if (offsetY + ydim > spaceNeeded) {
-            offsetY = spaceNeeded - ydim;
-            if (offsetY < 0) {
-                offsetY = 0;
-            }
-        }
-        mStartRow = offsetY / rowYSpace;
-        mEndRow = (offsetY + ydim) / rowYSpace;
-        if (mEndRow >= mNumRows) {
-            mEndRow = mNumRows - 1;
-        }
-        
-        return offsetY;
-    }
-
-    private void startHighlighting() {
-        // System.out.printf("startHighlighting()\n");
-        mSurface.mHighlightStep = 0;
-        mSurface.mFadeColors = true;
-        // Force a recomputation of the color strips
-        mSurface.mCachedEndRow = -1;
-        getDisplay().timerExec(0, mSurface.mHighlightAnimator);
-    }
-
-    private static class RowData {
-        RowData(Row row) {
-            mName = row.getName();
-            mStack = new ArrayList<Block>();
-        }
-
-        public void push(Block block) {
-            mStack.add(block);
-        }
-
-        public Block top() {
-            if (mStack.size() == 0)
-                return null;
-            return mStack.get(mStack.size() - 1);
-        }
-
-        public void pop() {
-            if (mStack.size() == 0)
-                return;
-            mStack.remove(mStack.size() - 1);
-        }
-
-        private String mName;
-        private int mRank;
-        private long mElapsed;
-        private long mEndTime;
-        private ArrayList<Block> mStack;
-    }
-
-    private static class Segment {
-        Segment(RowData rowData, Block block, long startTime, long endTime) {
-            mRowData = rowData;
-            mBlock = block;
-            mStartTime = startTime;
-            mEndTime = endTime;
-        }
-
-        private RowData mRowData;
-        private Block mBlock;
-        private long mStartTime;
-        private long mEndTime;
-    }
-
-    private static class Strip {
-        Strip(int x, int y, int width, int height, RowData rowData,
-                Segment segment, Color color) {
-            mX = x;
-            mY = y;
-            mWidth = width;
-            mHeight = height;
-            mRowData = rowData;
-            mSegment = segment;
-            mColor = color;
-        }
-
-        int mX;
-        int mY;
-        int mWidth;
-        int mHeight;
-        RowData mRowData;
-        Segment mSegment;
-        Color mColor;
-    }
-
-    private static class Pixel {
-        public void setFields(int start, double weight, Segment segment,
-                Color color, RowData rowData) {
-            mStart = start;
-            mMaxWeight = weight;
-            mSegment = segment;
-            mColor = color;
-            mRowData = rowData;
-        }
-
-        int mStart = -2; // some value that won't match another pixel
-        double mMaxWeight;
-        Segment mSegment;
-        Color mColor; // we need the color here because it may be faded
-        RowData mRowData;
-    }
-
-    private static class Range {
-        Range(int xStart, int width, int y, Color color) {
-            mXdim.x = xStart;
-            mXdim.y = width;
-            mY = y;
-            mColor = color;
-        }
-
-        Point mXdim = new Point(0, 0);
-        int mY;
-        Color mColor;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/TraceReader.java b/tools/traceview/src/com/android/traceview/TraceReader.java
deleted file mode 100644
index ae75876..0000000
--- a/tools/traceview/src/com/android/traceview/TraceReader.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public abstract class TraceReader {
-
-    private TraceUnits mTraceUnits;
-
-    public TraceUnits getTraceUnits() {
-        if (mTraceUnits == null)
-            mTraceUnits = new TraceUnits();
-        return mTraceUnits;
-    }
-
-    public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
-        return null;
-    }
-
-    public HashMap<Integer, String> getThreadLabels() {
-        return null;
-    }
-
-    public MethodData[] getMethods() {
-        return null;
-    }
-
-    public ThreadData[] getThreads() {
-        return null;
-    }
-
-    public long getEndTime() {
-        return 0;
-    }
-
-    public ProfileProvider getProfileProvider() {
-        return null;
-    }
-}
diff --git a/tools/traceview/src/com/android/traceview/TraceUnits.java b/tools/traceview/src/com/android/traceview/TraceUnits.java
deleted file mode 100644
index 20938f5..0000000
--- a/tools/traceview/src/com/android/traceview/TraceUnits.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.traceview;
-
-import java.text.DecimalFormat;
-
-// This should be a singleton.
-public class TraceUnits {
-
-    private TimeScale mTimeScale = TimeScale.MicroSeconds;
-    private double mScale = 1.0;
-    DecimalFormat mFormatter = new DecimalFormat();
-
-    public double getScaledValue(long value) {
-        return value * mScale;
-    }
-
-    public double getScaledValue(double value) {
-        return value * mScale;
-    }
-
-    public String valueOf(long value) {
-        return valueOf((double) value);
-    }
-
-    public String valueOf(double value) {
-        String pattern;
-        double scaled = value * mScale;
-        if ((int) scaled == scaled)
-            pattern = "###,###";
-        else
-            pattern = "###,###.###";
-        mFormatter.applyPattern(pattern);
-        return mFormatter.format(scaled);
-    }
-
-    public String labelledString(double value) {
-        String units = label();
-        String num = valueOf(value);
-        return String.format("%s: %s", units, num);
-    }
-
-    public String labelledString(long value) {
-        return labelledString((double) value);
-    }
-
-    public String label() {
-        if (mScale == 1.0)
-            return "usec";
-        if (mScale == 0.001)
-            return "msec";
-        if (mScale == 0.000001)
-            return "sec";
-        return null;
-    }
-
-    public void setTimeScale(TimeScale val) {
-        mTimeScale = val;
-        switch (val) {
-        case Seconds:
-            mScale = 0.000001;
-            break;
-        case MilliSeconds:
-            mScale = 0.001;
-            break;
-        case MicroSeconds:
-            mScale = 1.0;
-            break;
-        }
-    }
-
-    public TimeScale getTimeScale() {
-        return mTimeScale;
-    }
-
-    public enum TimeScale {
-        Seconds, MilliSeconds, MicroSeconds
-    };
-}
diff --git a/tools/traceview/src/resources/icons/sort_down.png b/tools/traceview/src/resources/icons/sort_down.png
deleted file mode 100644
index de6a2a0..0000000
--- a/tools/traceview/src/resources/icons/sort_down.png
+++ /dev/null
Binary files differ
diff --git a/tools/traceview/src/resources/icons/sort_up.png b/tools/traceview/src/resources/icons/sort_up.png
deleted file mode 100644
index 8578a87..0000000
--- a/tools/traceview/src/resources/icons/sort_up.png
+++ /dev/null
Binary files differ
